基于全局的唯一流水ID将一个请求在分布式系统中的流转路径聚合,然后使用调用过程中传递和保存的SpanID将聚合的请求路径
通过树形结构进行展示。5.1 APM系统简介 5.1.1 优秀的开源APM系统 1.Ponpoint特性:1.安装的采集端代理组件对原有的服务代码无入侵2.对性能影响比较小,只增加约3%的资源利用率3.根据请求的流量自动生成微服务调用的拓扑结构4.通过可视化结构显示网络微服务调用的关系,下钻(指点击进入子页面)可显示该服务的详细信息页面5.实时监控活动线程,并通过图像的形式展示6.可视化的显示请求发生的位置,帮助快速定位问题7.可以收集和显示cpu,内存,垃圾回收,请求吞吐量和JVM运行情况等8.使用异步线程推送和udp协议减少对程序处理性能的影响2.Zipkin能够收集服务调用的时序数据,解决微服务架构中定位超时等性能问题。它通过在应用程序中挂在字节码增强库来将实时数据汇报给Zipkin。Zipkin UI 可以通过图形的方式显示调用链中有多少请求经过系统的某一节点,并构造和显示系统的拓扑结构。如果定位微服务系统交互的超时问题,则可以根据服务节点,调用链长度,时间戳等信息过滤和查找想找到的调用链,一旦找到一个调用链,则能清晰的看到调用链是否有问题以及问题在哪里。3.CAT是美团点评开源的一款实时的应用和性能监控系统,它的系统原型和理念来源于eBay的CAL系统,并且增强了CAL系统的核心模型,添加了丰富的报表功能。5.1.2 国内商业APM产品的介绍 1.听云2.博睿3.OneAPM4.云智慧5.2 调用链跟踪的原理 5.2.1 分布式系统的远程调用过程 服务于一个用户的请求内部服务调用的结构是一个树形结构,树节点是整个架构的基本单元,每个节点是一个独立的服务节点。在谷歌的Dapper论文中,每个节点都对应一个span,节点之间的连线表示span和它的父span之间的关系,具体表现为一次调用请求和响应的调用关系,后面我们把描述一次请求调用和响应组成的数据叫做调用信息。我们通过什么手段标识响应和请求是一对呢?谷歌的Dapper论文通过增加应用层的标记来对服务化中的请求和响应建立联系,例如:它通过http协议头携带标记信息,标记信息包括标识调用链的唯一流水ID,这里叫做TraceID,以及标识调用层次和顺序的SpanID和ParentSpanID。一次远程调用的过程可以分为4个阶段,每个阶段对应一种远程调用的信息类型:1.调用端发送请求的调用信息2.被调用端接收请求的调用信息3.被调用端发送响应的调用信息4.调用端接收响应的调用信息上面每种类型的远程调用信息包含:调用端或者被调用端的IP,系统ID;本次请求的TraceID,SpanID和ParentSpanID;时间戳,调用的方法名称及远程调用信息的类型等。其中,远程调用信息的类型除了上面4个阶段对应的4种类型,在第3个阶段和第4个阶段又进一步分为响应成功和异常响应,我们也为主子线程间的调用增加了一种调用信息类型。我们为远程调用信息的类型定义的枚举类型如下:1.RPCPhase.P1:调用端发送请求的调用信息类型2.RPCPhase.P2:被调用端接收请求的调用信息类型3.RPCPhase.P3:被调用端发送响应成功的调用信息类型2.RPCPhase.P4:调用端接收响应成功的调用信息类型2.RPCPhase.E3:被调用端发送响应失败的调用信息类型2.RPCPhase.E4:调用端接收响应失败的调用信息类型2.RPCPhase.SIB:主子线程间传递调用信息类型5.2.2 TraceID 我们在前端接收用户的请求后,会为用户的请求分配一个TraceID,然后在内部服务调用时,会通过应用层的协议将TraceID传递到下层服务,直到整个调用链路中的每个节点都拥有了TraceID,在系统出问题后,我们可以使用这个唯一的TraceID迅速找到系统间发生的所有交互请求和响应,并定位问题发生的节点。Vesta 是一款原创的多场景的互联网发号器,此发号器可以作为全局唯一的流水号,也就是TraceID。5.2.3 SpanID TraceID 解决了系统间调用关系的串联问题,对调用关系串联后,我们能够找到服务于一个用户请求的调用和响应消息的集合,这些集合的请求和响应都是为同一次用户请求而服务的,但是我们无法标识和恢复这些请求和响应调用时的顺序和层级关系。因此,我们需要附加的信息在系统之间的请求和响应消息中传递,它就是SpanID,这里包含SpanID和ParentSpanID。SpanID和ParentSpanID 组合在一起就可以表示一个树形的调用关系,一个SpanID和ParentSpanID记录了一次调用的节点信息。SpanID表示当前为一个调用节点,ParentSpanID表示这个调用节点的父节点,通过这2个数据,我们就可以恢复树形的调用链。当出现故障时,我们需要为开发,运维人员显示树形的调用链,只需要下面4个步骤即可:1.通过TraceID把一整条调用链的所有信息收集到一个集合中,包括请求和响应2.通过SpanID和ParentSpanID恢复树形的调用链,ParentSpanID为-1的节点为调用树的根节点,也就是调用链的源头请求3.识别调用链中出错或者超市的节点,做出标记4.把恢复的调用树和出错的节点信息通过某种图形显示到UI界面上SpanID 是一个64位的整型值,有多种策略生成SpanID:1.使用随机数产生SpanID,理论上随机数是可以重复的,但是由于64位长整数型的取值范围,重复的可能性微乎其微,并且本地生成随机数的效率会高于其他方法。2.使用分布式的全局唯一的流水号生成方式,可以参考互联网发号器Vesta3.每个SpanID包含所有父亲及前辈节点的SpanID,使用圆点符号作为分隔符,不再需要 ParentSpanID 字段。如 SpanID=1.1.2。这种方案实现起来简单,但在某些场景下有一个致命的缺点,当一个请求的调用链有太多节点和层次时,SpanID 会携带太多冗余的信息,导致服务间调用的性能下降5.2.4 业务链 在生产实践中,由于业务流程复杂,一个业务流程的完成由用户的多次请求组成,这些请求之间是有关联的,我们在串联调用链之后,会根据业务的属性,将不同的调用链聚合在一起形成业务链,便于排查问题。例如用户在电商平台下单后会进行支付,由于在支付后对货物不满意,会申请退款。要完成这样的业务流程至少需要3次用户请求,这3次用户请求是通过业务系统的ID进行串联的,用户下单后会产生订单号,支付时会传入订单号,退款时也会传入原始订单号。我们需要在多次请求之间建立联系,可以通过业务系统的订单号来串联业务链,调用链是一个简单的树形结构,而业务链是一个森林结构。我们在恢复了下单,支付和退款调用链之后,通过业务的ID订单号将3个调用链关联在一起,这样开发,运维可以以更高的角度来查看业务系统的运行状态,迅速定位用户的请求卡在哪个链的哪个请求节点上,帮助业务人员和运营人员更好的了解产品的运行情况或者获得一些有价值的业务系统。5.3 调用链跟踪系统的设计与实现 5.3.1 整体架构 调用链跟踪系统通常由采集器,处理器和分布式存储系统组成,经过这几个模块处理后的调用数据会在调用链展示系统中对外提供查看和查询的功能。每个模块的功能职责如下:1.采集器:负责把业务系统的远程服务调用信息从业务系统中传递给处理器2.处理器:负责从业务系统的采集器中接收服务调用信息并聚合调用链,将其存储在分布式数据存储中,以及对调用链进行分析,并输出给监控和报警系统3.分布式存储系统:存储海量的调用链数据,并支持灵活的查询和搜索功能5.3.2 TraceID和SpanID在服务间的传递 调用链系统的输入是各个业务系统之间的远程服务调用产生的请求和响应信息。1.Java 进程内传递在java应用系统内通常通过ThreadLocal来传递 TraceID和SpanID,这样在需要调用外部系统时,TraceID和SpanID都是可以得到的。2.服务间传递在服务于服务之间的通信里,我们需要在应用层的网络通信协议中传递TraceID和SpanID。如果我们使用restful,则http头是传递TraceID和SpanID的最佳位置;如果我们使用的是rpc远程调用,则通常需要在rpc的序列化协议上增加定制的字段,将TraceID和SpanID从调用方传递给被调用方。3.主子线程间传递在服务化架构里,为了缩短请求的响应时间,提升用户体验,我们通常把一些非核心链路上的逻辑抽象成异步处理,这通常会在异步线程中执行,如果我们想跟着这部分调用链,则需要在创建新的线程或者子线程,将TraceID和SpanID一并传递过去。4.消息队列传递为了让系统之间最大化的解耦或者对突发流量进行消峰处理,通常我们会使用消息队列,但之后就无法对调用流程进行调用链的跟踪了,我们需要一种方案来弥补这种缺陷。调用链跟踪消息队列的实现有以下3种方式:1.通过更改消息队列实现的底层协议,将TraceID和SpanID在底层透明的传递,这样就不需要在应用层有感知,但是更改消息队列协议的实现复杂,消息队列产品多样化,这种方案不容易。2.在应用层的报文上增加附加字段,应用层在发送消息时,手工将TranceID和SpanID通过报文传输,这种方案入侵了业务系统,但实现起来比较简单。3.在第2种方案的基础上,可以在消息队列客户端的库上做定制化,在每次发送消息时将TraceID和SpanID增加到消息报文中,在消息队列的处理机的库中先对报文进行解析,再将业务报文传递给应用层,这样既不用修改底层协议,也不用在开发者在写业务逻辑代码时,手工赋值这2个字段。5.缓存,数据库访问作为调用链中非常重要的一部分,我们需要对数据库和缓存的访问进行跟踪。1.对缓存和数据库服务进行二次开发,通常改造缓存和数据库服务于其客户端的网络通信协议,将TraceID和SpanID通过网络通信协议进行透明的传输,但是这种方案的技术难度比较大,风险比较高。2.封装缓存,数据库的客户端,将TracdID和SpanID域访问的数据进行关联,这种方案实现简单,使用方案,对业务代码无入侵。5.3.3 采集器的设计与实现 现在解决如何把调用信息从业务系统中传递出来。下面介绍采集器,通过它从业务应用系统中把TraceID和SpanID传递到调用链的处理器上。采集器的职责就是解决采集TraceID和SpanID数据及推送数据的问题。1.采集器的实现方法对java应用系统的采集一般有4种方法:应用层主动推送,aop推送,JavaAgent字节码增强和大数据日志推送。1.应用层推送这种方式,应用层通过编写代码的方式,把相关数据推送到调用链处理器,比较简单,缺点是入侵了业务。2.AOP推送这种方法在应用的业务层代码中使用AOP拦截目标服务调用,把请求和响应的调用信息收集后,推送到调用链处理器。这种方法虽然入侵了业务代码,但是只需要开发aop切面拦截类,并将aop拦截类注入业务代码的Spring配置环境中,这里aop功能独立,可升级,使用起来比较方便,耦合并不严重。3.JavaAgent 字节码增强JavaAgent 是 JDK5 的新特性,开发者可以构建一个独立于应用程序的代理程序,用来检测和协助运行在jvm上的程序,甚至能够替换和修改某些类的定义,增加定制化的监控代码,实现更为灵活的运行时虚拟机监控和Java字节码操作,这样的特性实际上提供了一种虚拟机级别支持的AOP实现方式。好处是完全不会入侵业务系统的代码,便于以后对程序进行优化和重构等,最小化对业务代码的影响。4.代理推送这种方法与第四章对大数据日志系统的建设方式类似,日志文件通过应用程序打印相关调用日志,然后随着日志一起推送到日志中心,再从日志中心提取相关的调用日志,组成调用链。2.推送的实现方法采集器采集的数据需要从业务服务的线程推送到调用链的处理器上,在推送的过程中,我们必须保证不能影响业务的正常运行,一般有如下2种方式。1.kafka消息队列在采集器和处理器中间增加了kafka消息队列,对于高峰时的日志处理起到了有效的消峰作用。2.udp推送无连接的特点,udp传输数据的效率上比tcp活着任何上层协议的效率都高。不管是kafka还是udp推送,我们都不能从业务线程中直接发送数据,这样一旦收集器出现问题,就会影响业务流程。因此,我们通常使用异步线程池发送调用信息,异步线程池与业务线程之间必须采用有界队列,防止收集器出现问题,出现数据积压后导致应用内存耗光而产生OutOfMemoryError问题。5.3.4 处理器的设计与实现 通过kafka或者upd,调用信息从业务系统传递到调用链处理器,调用链处理器对调用信息进行组合和聚合,并进行一定的附加处理,然后存储在大数据存储系统中,或者通过Spark等流式处理后发送给监控和报警系统。1.处理器的处理逻辑手机端的处理器需要对收集的信息进行处理,通常我们会使用java开发一个处理器,对从udp或者kafka得到的日志进行聚合,然后存入调用链的大数据存储系统中。一般在生产实践过程中,我们在处理器中除了要对调用链进行聚合,还需要从调用链中发现调用的问题,例如:抛异常,超时,服务响应时间过长等。这时我们还需要使用类似Storm,Spark等流式计算系统会回复的调用链进行分析,然后发送给报警和监控系统。2.调用链的大数据存储系统一条调用链波爱护一个用户请求在服务化架构中的多次调用信息,每个调用信息分成4个阶段,每个阶段都有不同类型的信息进行存储。我们需要用大数据存储技术。因此,HBase 是比较合适的存储系统,另外,基于HBase的TSDB 也适合存储基于时序的数据。5.3.5 调用链系统的展示 

5.分布式服务架构:原理、设计与实战 --- 基于调用链的服务治理系统的设计与实现相关推荐

  1. 让ERP的服务更开放! ——用微服务架构搭建的一套基于EBS的API服务系统

    1. 源码下载地址 源码链接: https://github.com/samt007/xygerp-api-demo 这是用Spring Cloud微服务架构搭建的一套基于EBS的API服务系统 如对 ...

  2. 微服务架构原理与开发实战

    内容简介 最近几年软件开发方法层出不穷,微服务作为一种主流的架构模式一直热度不减.为了帮助广大程序员们更好更快地理解微服务的概念,学习微服务在项目中的实践,本书全面阐述了微服务架构模式的特点.架构思路 ...

  3. Fabric 超级账本学习【8】Hyperledger Fabric 实战——基于区块链的学历学位系统

    文章目录 摘要 安装部署 基于区块链的学历学位系统 报错1如下 报错原因:config.yaml 配置文件中的证书路径错误 访问基于区块链的学历学位系统 登录 基于区块链的学历学位系统 添加高等教育学 ...

  4. android显示温湿度设计与实现,基于Android平台蝴蝶兰大棚温湿度测控系统的设计与实现...

    摘要: 随着物联网技术在农业设施智能化控制方面的广泛应用,温室大棚环境因子的监测与设施的控制也得到了长足的进步.从经济效益角度来说,专业化人才需求的不断增加与劳动力成本的不断提高之间的矛盾,从农业产业 ...

  5. android流量监控软件设计与实现,基于android平台的流量监控系统的设计与实现

    摘要: 为了解决流量超额使用,恶意流量吸费的非法插件以及软件恶意联网的问题,帮助用户安全放心使用手机,本文设计并实现了一款基于Android平台的流量监控系统. 本文以Android系统为平台,分别从 ...

  6. 毕业设计 课程设计 大作业 基于JAVA WEB的网上购物系统的设计与实现

    文章目录 前言 1 运行效果 2 系统设计说明 2.1 整体设计 2.1.1 实现的功能: 2.1.2 系统工作流程: 2.2 总体设计功能图 2.3 数据库设计 3 项目 前言 随着计算机网络技术的 ...

  7. 【字节青训营】微服务架构原理核心服务治理与具体实践

    1.微服务架构介绍 1.1系统架构的演进历史 1.单体架构 2.垂直应用架构 按照业务线垂直划分 3.分布式架构 抽出与业务无关的公共模块 4.SOA架构 面向服务 5.微服务架构 彻底的服务化 5. ...

  8. 创建微服务架构的步骤_如何快速搭建一个微服务架构?

    原标题:如何快速搭建一个微服务架构? 微服务火了很久,但网上很少有文章能做到成熟地将技术传播出来,同时完美地照顾"初入微服务领域人员",从 0 开始,采用通俗易懂的语言去讲解微服务 ...

  9. Re:从0开始的微服务架构:(二)如何快速体验微服务架构?

    记得好久之前看到一个大牛说过:如果单体架构都搞不好,就别搞微服务架构.乍一看,这句很有道理,后来发现这句话是不太对的,因为微服务架构的目的就是为了降低系统的复杂性,所以 微服务架构应该比单体架构更简单 ...

  10. b s架构监控java,基于B/S的视频监控系统的设计与实现

    基于B/S的视频监控系统的设计与实现 本文分析了基于C/S架构的视频监控系统的缺点和B/S结构的诸多优点,通过需求分析,设计实现了一种以B/S为架构的视频监控系统,并针对现存视频监控系统在权限控制方面 ...

最新文章

  1. java静态钥匙上同步代=代码块锁
  2. python:将json数据写入到excel
  3. Linux 内核的文件 Cache 管理机制介绍
  4. 记录一次redis事故
  5. 微内核和宏内核的区别_8086微处理器中的过程和宏之间的区别
  6. 华北水利水电大学c语言实验报告八2020,2021年华北水利水电大学级C语言实验报告.doc...
  7. python可变类型与不可变类型作为函数参数区别_不要用可变类型对象做函数默认参数...
  8. Ganglia 权威指南-安装Ganglia过程
  9. 深入理解IIS工作原理
  10. MATLAB模糊控制算法,驾驶员制动意图识别
  11. android xml 设置半透明
  12. uni-app微信小程序模拟器运行到某一页面调试操作
  13. 证明:T(n)= T(n-1) + O(n)等于O(n的平方)
  14. 人脸识别入门论文《Deep Facial Expression Recognition: A Survey》学习笔记
  15. Word中怎么用MathType编辑公式
  16. 51单片机程序烧写说明
  17. 2022 Java 知识点总结
  18. 如何去除图片中的白色背景(变透明)
  19. 编辑为什么建议转投_sci编辑建议转投应该接受吗
  20. 万能的SuperSlide

热门文章

  1. SecureCRT的安装、介绍、简单操作
  2. A. Holidays
  3. 10 使用ViewPager实现导航
  4. 【随机过程】随机过程之更新过程(1)
  5. Forms验证中的roles(转)
  6. Win32 网络编程基本函数
  7. JS控制文本框禁止输入特殊字符
  8. python实现汉诺塔(递归)
  9. [leetcode] 406. Queue Reconstruction by Height (medium)
  10. sql server 安装时提示要重启