通过Dapr实现一个简单的基于.net的微服务电商系统(八)——一步一步教你如何撸Dapr之链路追踪
Dapr提供了一些开箱即用的分布式链路追踪解决方案,今天我们来讲一讲如何通过dapr的configuration来实现非侵入式链路追踪的
目录:
一、通过Dapr实现一个简单的基于.net的微服务电商系统
二、通过Dapr实现一个简单的基于.net的微服务电商系统(二)——通讯框架讲解
三、通过Dapr实现一个简单的基于.net的微服务电商系统(三)——一步一步教你如何撸Dapr
四、通过Dapr实现一个简单的基于.net的微服务电商系统(四)——一步一步教你如何撸Dapr之订阅发布
五、通过Dapr实现一个简单的基于.net的微服务电商系统(五)——一步一步教你如何撸Dapr之状态管理
六、通过Dapr实现一个简单的基于.net的微服务电商系统(六)——一步一步教你如何撸Dapr之Actor服务
七、通过Dapr实现一个简单的基于.net的微服务电商系统(七)——一步一步教你如何撸Dapr之服务限流
八、通过Dapr实现一个简单的基于.net的微服务电商系统(八)——一步一步教你如何撸Dapr之链路追踪
附录:(如果你觉得对你有用,请给个star)
一、电商Demo地址
首先依然简单聊聊什么是链路追踪以及我们为什么需要它,知道链路追踪的同学可以跳过。在传统的单体应用中,我们的每一次请求往往在同一个进程中被一次性处理。而在分布式系统中,我们需要通过不同容器隔离甚至物理机隔离的服务间协同作业来实现某些业务,同时由于业务流转会涉及到接口调用、事件订阅、状态读写、actor调用等等情况,往往想要追踪它们形成一个链式调用的记录会比较困难。这里举一个例子,某分布式系统集群运行在生产环境上,某日收到预警某接口调用非常缓慢。这个时候开发人员排查发现该聚合网关接口调用了服务A、B、C但是不知道具体是哪个服务导致的缓慢,通知A、B、C对应的开发组人员通过本地调试发现A、B、调用正常,C缓慢,但是C发现并非由于自身业务逻辑缓慢,而是自己调用D时返回比较缓慢,这时又只得通知D负责的团队进行业务排查,最终D发现自己的代码问题,然后逐一修复并发布到生产环境解决该问题。这个例子比较极端哈,这里仅举个例子说明。链路追踪系统就是帮助分布式系统在链路调用时记录每一个接口的响应时间以及自己依赖的下游接口的响应时间并提供可视化UI方便开发运维团队快速排查接口调用耗时异常定位问题。
传统的链路追踪一般是通过代码侵入式的方式由开发人员集成SDK插入代理,应用上线运行后这些代理即可自动化监视我们的应用进程记录流量流入、流出请求/响应时间并统一上报到链路追踪系统,而service mesh由于sidecar的存在可以确保流量在流入/流出应用时一定会经过sidecar,所以天生更容易实现链路追踪,从而免于让开发人员人工通过SDK的方式去集成一个分布式链路追踪系统,接下来就讲讲我们在dapr下如何来实现它。
首先我们需要在k8s环境跑起来一个链路追踪系统,大家可以看看这里是目前dapr支持的链路后端,我这里就选型我比较熟悉的zipkin来实现。zip在k8s中很容易跑起来,这是yaml:
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: zipkin
spec:
selector:
matchLabels:
app: zipkin
replicas: 1
template:
metadata:
labels:
app: zipkin
spec:
containers:
- name: zipkin
image: openzipkin/zipkin:latest
imagePullPolicy: IfNotPresent
ports:
- containerPort: 9411
env:
- name: TZ
value: "Asia/Shanghai"
---
apiVersion: v1
kind: Service
metadata:
name: zipkin
spec:
type: NodePort
selector:
app: zipkin
ports:
- protocol: TCP
port: 9411
targetPort: 9411
由于需要在本地访问zip的website,我这里偷懒直接将nodeport暴露到本地k8s集群,方便等会儿通过浏览器访问。现在我们apply一下,稍微等待一段时间k8s拉取镜像并运行起来后,通过kubectl get svc 查询zipkin暴露的随机端口即可通过localhost:nodeport访问到zipkin的界面:
接下来就比较简单了,我们创建一个类型为configuration的配置文件,并注入到每一个需要追踪的服务即可,其中samplingRate是指采样率,而endpointAddress是指我们在k8s集群内通过svc能访问到的zipkin的地址(如果你的zipkin部署在非本集群,则可通过ip or 网址的方式访问):
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: zipkin
spec:
metric:
enabled: true
tracing:
samplingRate: "1"
zipkin:
endpointAddress: "http://zipkin.infrastructure.svc.cluster.local:9411/api/v2/spans"
接着我们将这个configuration注入到我们需要的服务中,这里我们直接看电商demo yaml文件账户服务的情况(红字部分):
apiVersion: apps/v1
kind: Deployment
metadata:
name: accountservice
namespace: dapreshop
labels:
app: accountservice
spec:
replicas: 1
selector:
matchLabels:
app: accountservice
minReadySeconds: 5
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 1
template:
metadata:
labels:
app: accountservice
version: v1
annotations:
dapr.io/enabled: "true"
dapr.io/app-id: "accountservice"
dapr.io/app-port: "80"
dapr.io/config: "zipkin"
spec:
containers:
- name: web
image: accountservice:release
imagePullPolicy: Never
readinessProbe:
httpGet:
path: v1.0/healthz
port: 3500
initialDelaySeconds: 5
periodSeconds: 10
timeoutSeconds : 5
failureThreshold : 3
ports:
- containerPort: 80
现在我们来下单看看,访问admin.dapreshop.com:30882,初始化系统后,访问m.dapreshop.com:30882,下单一次。接着打开我们的zipkin,查询run query即可看到最新一条链路追踪记录如下:
可以看到链路追踪的root是我们的apigateway,因为客户端请求是从这里被聚合的。接着apigateway会调用商品服务、交易服务、用户服务、以及作业系统。这里我们再看看我们的代码看看createorder明细:
这个用例服务会调用用户服务获取一个mockaccount模拟用户用于下单,接着会调用一个创建订单的领域服务用于下单这里会调用商品的actor服务用于原子减扣库存(此部分可参考之前的actor文章),下单完成后会发送一个订单创建成功事件,由作业系统订阅并等待5分钟后进行未支付订单取消操作,整个下单流程如下:
整个流程相对比较简单,通过在daprd sidecar上申明了zipkin configuration后 daprd会忠实的将我们的请求转化为链路追踪记录并上报zipkin,我们点开zipkin那条记录查看明细如下:
可以非常清楚的看到我们的订单创建调用的账户服务的mockaccount接口,然后调用了商品服务的商品信息接口,接着调用数个商品actor进行库存减扣,最终持久化我们的订单后发起一个事件并且成功的被作业系统订阅。每一个接口请求了多少时间被清楚的记录了下来,这样在生产环境下就很容易排除慢接口的问题而不用像上面提到的那样各个团队忙的焦头烂额了
dapr目前还提供了其他的一些链路追踪客户端,但是整体大的流程基本如本文所述,今天的分享就到这里,希望大家多多支持dapr,多多转发fork+star。下一次我们将分享一下如何集成一个第三方的oauth授权服务来实现oauth。
通过Dapr实现一个简单的基于.net的微服务电商系统(八)——一步一步教你如何撸Dapr之链路追踪的更多相关文章
- 通过Dapr实现一个简单的基于.net的微服务电商系统(九)——一步一步教你如何撸Dapr之OAuth2授权
Oauth2授权,熟悉微信开发的同学对这个东西应该不陌生吧.当我们的应用系统需要集成第三方授权时一般都会做oauth集成,今天就来看看在Dapr的语境下我们如何仅通过配置无需修改应用程序的方式让第三方 ...
- 通过Dapr实现一个简单的基于.net的微服务电商系统(十)——一步一步教你如何撸Dapr之绑定
如果说Actor是dapr有状态服务的内部体现的话,那绑定应该是dapr对serverless这部分的体现了.我们可以通过绑定极大的扩展应用的能力,甚至未来会成为serverless的基础.最开始接触 ...
- 通过Dapr实现一个简单的基于.net的微服务电商系统(十一)——一步一步教你如何撸Dapr之自动扩/缩容
上一篇我们讲到了dapr提供的bindings,通过绑定可以让我们的程序轻装上阵,在极端情况下几乎不需要集成任何sdk,仅需要通过httpclient+text.json即可完成对外部组件的调用,这样 ...
- 通过Dapr实现一个简单的基于.net的微服务电商系统(十二)——istio+dapr构建多运行时服务网格
多运行时是一个非常新的概念.在 2020 年,Bilgin Ibryam 提出了 Multi-Runtime(多运行时)的理念,对基于 Sidecar 模式的各种产品形态进行了实践总结和理论升华.那到 ...
- 通过Dapr实现一个简单的基于.net的微服务电商系统(十三)——istio+dapr构建多运行时服务网格之生产环境部署
之前所有的演示都是在docker for windows上进行部署的,没有真正模拟生产环境,今天我们模拟真实环境在公有云上用linux操作如何实现istio+dapr+电商demo的部署. 目录:一. ...
- 通过Dapr实现一个简单的基于.net的微服务电商系统(十四)——开发环境容器调试小技巧
之前有很多同学提到如何做容器调试,特别是k8s环境下的容器调试,今天就讲讲我是如何调试的.大家都知道在vs自带的创建项目模板里勾选docker即可通过F5启动docker容器调试.但是对于启动在k8s ...
- 通过Dapr实现一个简单的基于.net的微服务电商系统(十五)——集中式接口文档实现
之前有小伙伴在评论区留言说如何集成swagger,最开始没有想透给了对方一个似是而非的回答.实际上后来下来想了一下,用.NET5 提供的Source Generator其实可以很方便的实现接口集成.今 ...
- 通过Dapr实现一个简单的基于.net的微服务电商系统(十六)——dapr+sentinel中间件实现服务保护
dapr目前更新到了1.2版本,在之前4月份的时候来自阿里的开发工程师发起了一个dapr集成Alibaba Sentinel的提案,很快被社区加入到了1.2的里程碑中并且在1.2 release 相关 ...
- 通过Dapr实现一个简单的基于.net的微服务电商系统(十七)——服务保护之动态配置与热重载
在上一篇文章里,我们通过注入sentinel component到apigateway实现了对下游服务的保护,不过受限于目前变更component需要人工的重新注入配置以及重启应用更新componen ...
随机推荐
- xmake v2.5.2 发布, 支持自动拉取交叉工具链和依赖包集成
xmake 是一个基于 Lua 的轻量级跨平台构建工具,使用 xmake.lua 维护项目构建,相比 makefile/CMakeLists.txt,配置语法更加简洁直观,对新手非常友好,短时间内就能 ...
- 快速查找未打补丁的exp
在windows DOS窗口下输入以下内容,输出为未打的补丁信息列表 systeminfo>vul.txt&(for %i in (KB977165 KB2160329 KB250366 ...
- for遍历是如何判断数据是不是list的最后一位
//listUser 是User的实体的集合for(User user : listUser){ if(listUser.size - 1 == listUser.indexOf(user)){ // ...
- RabbitMQ简介、安装、基本特性API--Java测试
新的阅读体验地址:http://www.zhouhong.icu/post/141 本篇文章所有的代码:https://github.com/Tom-shushu/Distributed-system ...
- js 数组的浅拷贝和深拷贝
1.背景介绍 javascript分原始类型与引用类型.Array是引用类型,直接用"="号赋值的话,只是把源数组的地址(或叫指针)赋值给目的数组,指向的是同一个内存地址,其中一个 ...
- Java数组:初识数组
数组:数组是相同类型数据的有序集合数组描述的是相同类型的若干个数据,按照一定的先后次序排列组合而成其中,每一个数据称作一个数组元素,每个数组元素可以通过一个下标来访问他们 数组基本特点:其长度是确定的 ...
- 200-Java语言基础-Java编程入门-006 | Java数组定义及使用(引用数据类型)
一.数组概述和定义格式说明 为什么要有数组(容器): 为了存储同种数据类型的多个值 数组概念: 数组是存储同一种数据类型多个元素的集合.也可以看成是一个容器. 数组既可以存储基本数据类型,也可以存储引 ...
- vue 仿zTree折叠树
需求: vue实现仿zTree折叠树,此文章仅作为记录文档. 实现: <template> <div class="line-tree"> <div ...
- golang 矩阵乘法、行列式、求逆矩阵
package matrix import ( "math" "github.com/astaxie/beego" ) type Matrix4 struct ...
- Android Studio 安装并使用genymotion
一.安装genymotion与VirtualBox 1.安装 genymotion安装包:https://pan.baidu.com/s/1UTwvJv2pbHE4znBw91V19g virtual ...