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. Spirng 循环依赖报错:Requested bean is currently in creation: Is there an unresolvable circular reference?

    1:前言 最近在项目中遇到了一次循环依赖报错的问题,虽然解决的很快,但是有些不明白的地方,特此记录. 在此我把 bean 的结构和 注入方式单独拎出来进行演示 1.1:报错提示 1.2:错误日志 Ex ...

  2. Vue框架-组件的概念及使用

    目录 一.Vue组件 1. 组件分类 1.1 根组件 1.2 局部组件 1.3 全局组件 2. 组件的特点 3. 如何创建组件 4. 组件的数据局部化 5. 组件传参·父传子 6. 组件传参·子传父 ...

  3. 后端程序员之路 7、Zookeeper

    Zookeeper是hadoop的一个子项目,提供分布式应用程序协调服务. Apache ZooKeeper - Homehttps://zookeeper.apache.org/ zookeeper ...

  4. CF1491C Pekora and Trampoline 题解

    题目链接 ​ 比赛时只想到了 \(\mathcal O(n^3)\) 的暴力做法,官方题解是 \(\mathcal O(n^2)\) ,并且是可以优化为 \(\mathcal O(n)\) 的(贪心+ ...

  5. pytorch(11)模型创建步骤与nn.Module

    模型创建与nn.Module 网络模型创建步骤 nn.Module graph LR 模型 --> 模型创建 模型创建 --> 构建网络层 构建网络层 --> id[卷积层,池化层, ...

  6. mysql内一些可以报错注入的查询语句

        一.exp() 取反参数 该函数简单来说就是,以e为底的对数,在当传递一个大于709的值时,函数exp()就会引起一个溢出错误,取反则可以导致很小的数值变得很大,比如说0 这样既可配合使用,e ...

  7. LeetCode 175. Combine Two Tables 【MySQL中连接查询on和where的区别】

    一.题目 175. Combine Two Tables 二.分析 连接查询的时候要考虑where和on的区别 where : 查询时,连接的时候是必须严格满足条件的,满足了才会加入到临时表中. on ...

  8. POJ_1458 Common Subsequence 【LCS】

    一.题目 Common Subsequence 二.分析 比较基础的求最长升序子序列. $DP[i][j]$表示的是字符串$S1[1...i]$与$S2[1...j]$的最长公共子序列长度. 状态转移 ...

  9. $.ajax data向后台传递参数失败 contentType: "application/json"

    在ajax方法设置中若不添加 contentType: "application/json" 则data可以是对象: $.ajax({ url: actionurl, type: ...

  10. 在 .NET Core 中构建 REST API

    翻译自 Camilo Reyes 2020年8月26日的文章 <Build a REST API in .NET Core> [1] REST API 可以使用简单的动词(如 POST.P ...