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之链路追踪的更多相关文章

  1. 通过Dapr实现一个简单的基于.net的微服务电商系统(九)——一步一步教你如何撸Dapr之OAuth2授权

    Oauth2授权,熟悉微信开发的同学对这个东西应该不陌生吧.当我们的应用系统需要集成第三方授权时一般都会做oauth集成,今天就来看看在Dapr的语境下我们如何仅通过配置无需修改应用程序的方式让第三方 ...

  2. 通过Dapr实现一个简单的基于.net的微服务电商系统(十)——一步一步教你如何撸Dapr之绑定

    如果说Actor是dapr有状态服务的内部体现的话,那绑定应该是dapr对serverless这部分的体现了.我们可以通过绑定极大的扩展应用的能力,甚至未来会成为serverless的基础.最开始接触 ...

  3. 通过Dapr实现一个简单的基于.net的微服务电商系统(十一)——一步一步教你如何撸Dapr之自动扩/缩容

    上一篇我们讲到了dapr提供的bindings,通过绑定可以让我们的程序轻装上阵,在极端情况下几乎不需要集成任何sdk,仅需要通过httpclient+text.json即可完成对外部组件的调用,这样 ...

  4. 通过Dapr实现一个简单的基于.net的微服务电商系统(十二)——istio+dapr构建多运行时服务网格

    多运行时是一个非常新的概念.在 2020 年,Bilgin Ibryam 提出了 Multi-Runtime(多运行时)的理念,对基于 Sidecar 模式的各种产品形态进行了实践总结和理论升华.那到 ...

  5. 通过Dapr实现一个简单的基于.net的微服务电商系统(十三)——istio+dapr构建多运行时服务网格之生产环境部署

    之前所有的演示都是在docker for windows上进行部署的,没有真正模拟生产环境,今天我们模拟真实环境在公有云上用linux操作如何实现istio+dapr+电商demo的部署. 目录:一. ...

  6. 通过Dapr实现一个简单的基于.net的微服务电商系统(十四)——开发环境容器调试小技巧

    之前有很多同学提到如何做容器调试,特别是k8s环境下的容器调试,今天就讲讲我是如何调试的.大家都知道在vs自带的创建项目模板里勾选docker即可通过F5启动docker容器调试.但是对于启动在k8s ...

  7. 通过Dapr实现一个简单的基于.net的微服务电商系统(十五)——集中式接口文档实现

    之前有小伙伴在评论区留言说如何集成swagger,最开始没有想透给了对方一个似是而非的回答.实际上后来下来想了一下,用.NET5 提供的Source Generator其实可以很方便的实现接口集成.今 ...

  8. 通过Dapr实现一个简单的基于.net的微服务电商系统(十六)——dapr+sentinel中间件实现服务保护

    dapr目前更新到了1.2版本,在之前4月份的时候来自阿里的开发工程师发起了一个dapr集成Alibaba Sentinel的提案,很快被社区加入到了1.2的里程碑中并且在1.2 release 相关 ...

  9. 通过Dapr实现一个简单的基于.net的微服务电商系统(十七)——服务保护之动态配置与热重载

    在上一篇文章里,我们通过注入sentinel component到apigateway实现了对下游服务的保护,不过受限于目前变更component需要人工的重新注入配置以及重启应用更新componen ...

随机推荐

  1. 微信小程序优化:实现picker组件中input输入框禁止输入,而只能通过picker组件选择日期

    原来的代码如下: <view class="right">     <picker mode="date" value="{{mat ...

  2. Hyperf-事件机制+异常处理

    Hyperf-事件机制+异常处理 标签(空格分隔): php, hyperf 异常处理器 在 Hyperf 里,业务代码都运行在 Worker 进程 上,也就意味着一旦任意一个请求的业务存在没有捕获处 ...

  3. 第31天学习打卡(File类。字符流读写文件)

    File类 概念 文件,文件夹,一个file对象代表磁盘上的某个文件或者文件夹 构造方法  File(String pathname) File(String parent,String child) ...

  4. 如何系统的了解Kafka

    1.概述 在大数据的浪潮下,时时刻刻都会产生大量的数据.比如社交媒体.博客.电子商务等等,这些数据会以不同的类型存储在不同的平台里面.为了执行ETL(提取.转换.加载)操作,需要一个消息中间件系统,该 ...

  5. Kubernetes-2.组件

    内容主要摘自官网文档资料 官网地址 本文概述了交付正常运行的Kubernetes集群所需的各种组件. 本文编写基于kubernetes v1.17版本 目录 Kubernetes集群 Master组件 ...

  6. Hi3559AV100-自己编译了u-boot、kernel及rootfs后,出现烧写错误或者烧写后板载无法启动的解决思路

    这篇随笔主要给出了Hi3559AV100-自己编译了u-boot.kernel及rootfs后,出现烧写错误或者烧写后板载无法启动的解决思路. 问题 (1)对于 u-boot 为官方的,kernel ...

  7. kubernets资源预留

    一.  Kubelet Node Allocatable Kubelet Node Allocatable用来为Kube组件和System进程预留资源,从而保证当节点出现满负荷时也能保证Kube和Sy ...

  8. HDOJ-2181(深搜记录路径)

    哈密顿绕行世界问题 HDOJ-2181 1.本题是典型的搜索记录路径的问题 2.主要使用的方法是dfs深搜,在输入的时候对vector进行排序,这样才能按照字典序输出. 3.为了记录路径,我使用的是两 ...

  9. Java 常见对象 01

    常见对象·Object类 Object类的概述 * A:Object 类概述 * 类层次结构的根类 * 所有类都直接或间接地继承自该类 * B:构造方法 * public Object() * 回想为 ...

  10. 1.5 PHP基础+1.5.1 访问数据库

    PHP作为流行的网站开发语言,具有上手简单,运行速度快的特点,它和javascript类似,无需定义变量类型,免去了使用者要对变量类型转换的烦恼,当然了,这就要求我们要对变量类型隐式转换过程予以关注. ...