分布式系统为什么需要分布式跟踪?
电商平台由数以百计的分布式服务构成,每一个请求路由过来后,会经过多个业务系统并留下足迹,并产生对各种Cache或DB的访问,但是这些分散的数据对于问题排查,或是流程优化都帮助有限。
对于这么一个跨进程/跨线程的场景,汇总收集并分析海量日志就显得尤为重要。要能做到追踪每个请求的完整调用链路,收集调用链路上每个服务的性能数据,计算性能数据和比对性能指标(SLA),甚至在更远的未来能够再反馈到服务治理中,那么这就是分布式跟踪的目标了。
在业界,twitter的zipkin和淘宝的鹰眼就是类似的系统,它们都起源于Google Dapper 论文,就像历史上Hadoop发源于Google Map/Reduce 论文,HBase源自Google BigTable 论文一样。
这样的系统通常有几个设计目标:
(1)低侵入性——作为非业务组件,应当尽可能少侵入或者无侵入其他业务系统,对于使用方透明,减少开发人员的负担。
(2)灵活的应用策略——可以(最好随时)决定所收集数据的范围和粒度。
(3)时效性——从数据的收集和产生,到数据计算和处理,再到最终展现,都要求尽可能快。
(4)决策支持——这些数据是否能在决策支持层面发挥作用,特别是从DevOps的角度。
(5)可视化才是王道。
先来一个直观感受
数据流转过程:
图1-1淘宝鹰眼的数据收集和存储
鹰眼的调用链绘制界面:
图1-2 淘宝鹰眼的调用链
鼠标移动到调用链的每一层点击,可以看到执行时长、宿主机IP、数据库操作、传入参数甚至错误堆栈等等具体信息。
淘宝如何实现的
同一次请求的所有相关调用的情况,在淘宝EagleEye里称作调用链。同一个时刻某一台服务器并行发起的网络调用有很多,怎么识别这个调用是属于哪个调用链的呢?可以在各个发起网络调用的中间件上下手。
在前端请求到达服务器时,应用容器在执行实际业务处理之前,会先执行EagleEye的埋点逻辑(类似Filter的机制),埋点逻辑为这个前端请求分配一个全局唯一的调用链ID。这个ID在EagleEye里面被称为TraceId,埋点逻辑把TraceId放在一个调用上下文对象里面,而调用上下文对象会存储在ThreadLocal里面。调用上下文里还有一个ID非常重要,在EagleEye里面被称作RpcId。RpcId用于区分同一个调用链下的多个网络调用的发生顺序和嵌套层次关系。对于前端收到请求,生成的RpcId固定都是0。
当这个前端执行业务处理需要发起RPC调用时,淘宝的RPC调用客户端HSF会首先从当前线程ThreadLocal上面获取之前EagleEye设置的调用上下文。然后,把RpcId递增一个序号。在EagleEye里使用多级序号来表示 RpcId,比如前端刚接到请求之后的RpcId 是0,那么它第一次调用 RPC 服务A时,会把RpcId改成0.1。之后,调用上下文会作为附件随这次请求一起发送到远程的HSF服务器。
HSF服务端收到这个请求之后,会从请求附件里取出调用上下文,并放到当前线程ThreadLocal上面。如果服务A在处理时,需要调用另一个服务,这个时候它会重复之前提到的操作,唯一的差别就是RpcId会先改成 0.1.1再传过去。服务A的逻辑全部处理完毕之后,HSF 在返回响应对象之前,会把这次调用情况以及TraceId、RpcId都打印到它的访问日志之中,同时,会从ThreadLocal清理掉调用上下文。
如图2-1展示了一个浏览器请求可能触发的系统间调用。
图2-1一个浏览器请求可能触发的系统间调用
图2-1描述了EagleEye在一个非常简单的分布式调用场景里做的事情,就是为每次调用分配TraceId、RpcId,放在ThreadLocal的调用上下文上面,调用结束的时候,把TraceId、RpcId打印到访问日志。
类似的其他网络调用中间件的调用过程也都比较类似,这里不再赘述了。访问日志里面,一般会记录调用时间、远端IP地址、结果状态码、调用 耗时之类,也会记录与这次调用类型相关的一些信息,如URL、服务名、消息topic等。
很多调用场景会比上面说的完全同步的调用更为复杂,比如会遇到异步、单向、广播、并发、批处理等等,这时候需要妥善处理好ThreadLocal上的调用上下文,避免调用上下文混乱和无法正确释放。另外,采用多级序号的RpcId设计方案会比单级序号递增更容易准确还原当时的调用情况。
最后,EagleEye分析系统把调用链相关的所有访问日志都收集上来,按TraceId汇总在一起之后,就可以准确还原调用当时的情况了。
图2-2一个典型的调用链
如图2-2所示,就是采集自淘宝线上环境的某一条实际调用链。调用链通过树形展现了调用情况。调用链可以清晰地看到当前请求的调用情况,帮助问题定位。如上图,mtop应用发生错误时,在调用链上可以直接看出这是因为第四层的一个(tair@1)请求导致网络超时,使最上层页面出现超时问题。这种调用链,可以在EagleEye系统监测到包含异常的访问日志后,把当前的错误与整个调用链关联起来。问题排查人员在发现入口错误量上涨或耗时上升时,通过EagleEye查找出这种包含错误的调用链采样,提高故障定位速度。
调用链数据在容量规划和稳定性方面的分析
如果对同一个前端入口的多条调用链做汇总统计,也就是说,把这个入口URL下面的所有调用按照调用链的树形结构全部叠加在一起,就可以得到一个新的树结构(如图2-3所示)。这就是入口下面的所有依赖的调用路径情况。
图2-3 对某个入口的调用链做统计之后得到的依赖分析
这种分析能力对于复杂的分布式环境的调用关系梳理尤为重要。传统的调用统计日志是按固定时间窗口预先做了统计的日志,上面缺少了链路细节导致没办法对超过两层以上的调用情况进行分析。
例如,后端数据库就无法评估数据库访问是来源于最上层的哪些入口;每个前端系统也无法清楚确定当前入口由于双十一活动流量翻倍,会对后端哪些系统造成多大的压力,需要分别准备多少机器。有了EagleEye的数据,这些问题就迎刃而解了。
http://express.ruanko.com/ruanko-express_79/tech-overnight3.html
相关推荐
《鹰眼下的淘宝-分布式调用跟踪系统介绍》是一篇深入探讨分布式系统监控与追踪的文章,主要关注于淘宝内部使用的“鹰眼”系统。这篇文章基于作者在ITeye博客上的分享,我们将围绕分布式调用跟踪、系统监控以及相关...
操作系统安全脆弱性主要由操作系统内核程序结构所造成,操作系统可提供远程调用、创建进程等服务,为攻击者提供了可利用的途径。网络协议的脆弱性则在于其安全设计上存在缺陷,如TCP/IP协议在设计时未考虑安全因素,...
2. **Java RMI (Remote Method Invocation)**:Java平台提供的远程方法调用机制,允许Java对象在不同的JVM之间进行通信,简化了分布式应用的开发。 3. **COM (Component Object Model)**:微软提出的一种组件对象...
分布式系统的设计,是一门复杂的学问,它涉及到通信协议、远程调用,服务治理,系统安全、存储、搜索、监控、稳定性保障、性能优化、数据分析、数据挖掘等各个领域,对任何一个领域的深入挖掘,都能够编写一本篇幅...
### 机器人操作系统(ROS)浅析 #### 一、引言与背景 《机器人操作系统(ROS)浅析》是一本详细介绍ROS(Robot Operating System)基础知识和技术细节的专业书籍。ROS并非传统意义上的操作系统,而是一个用于...
在分布式服务框架中,一个最基础的问题就是远程服务是怎么通讯的,在Java...要实现网络机器间的通讯,首先得来看看计算机系统网络通信的基本原理,在底层层面去看,网络通信需要做的就是将流从一台计算机传输到另外一
在GPFS文件系统中,应用程序不需要任何定制操作,只需要正常调用操作系统文件读写就可以,操作系统在后台调用文件读写的时候会跟GPFS所管理的文件系统I节点进行映射最终实现GPFS文件系统读写的调用。每一个GPFS...
其次,云数据管理系统的运作主要依赖于各种技术的支撑,在云计算策略的统一调配下,完成数据的存储、调用以及检索等过程。在此过程中,云计算技术的应用为信息时代环境下互联网产业的规模化发展奠定了基础。云数据...
- 远程过程调用中间件允许在分布式环境中透明地执行远程过程调用,简化了跨网络的服务调用过程。 6. **对象请求代理中间件(ORM)** - 对象请求代理中间件用于实现对象之间的通信和服务定位,特别适合于基于对象...
其次,LonWorks是由Echelon公司开发的一种局域网络技术,特别适用于分布式控制系统。它采用LonTalk协议,具有低功耗、高可靠性、自愈能力等优点,适合于楼宇自动化系统的通信。然而,LonWorks的网络配置相对复杂,...
Java技术浅析 Java是一种广泛应用于企业级项目开发的编程语言,它具有强大的功能和灵活的特性,使其成为开发大型项目的首选语言。Java技术浅析主要介绍了Java语言的技术关键词、编程技术框架、原理等知识点。 一、...
这在煤矿生产调度管理系统中尤为重要,因为它需要与其他系统或服务集成,例如与现有的煤矿企业管理系统、地质信息系统等进行数据交换和功能调用。Web Services的使用减少了系统集成的复杂性,提高了系统间通信的效率...
企业服务总线(Enterprise Service Bus,ESB)是一种中间件技术,用于构建分布式、松散耦合的企业级应用系统。本文档《ESB项目需求分析和方案设计浅析》主要探讨了在实施ESB项目时的需求分析和方案设计的关键点。 ...
【WebService技术浅析】 随着信息技术的飞速发展,传统的基于特定系统和环境的开发模式已无法满足日益复杂的业务需求。WebService技术应运而生,它为异构系统间的交互提供了通用且平台无关的解决方案。WebService的...
分布式计算的核心在于任务的地理分布和处理资源的独立性,不同子任务之间互不依赖,每个子任务在独立的计算系统中运行。这种计算模型最适合处理那些可以分解为多个相互独立的子任务的问题,如科学研究中的大规模模拟...
RMI(Remote Method Invocation,远程方法调用)是Java中一种用于实现分布式计算的技术,它允许一个Java对象调用另一个在网络另一端的Java对象的方法。然而,RMI的反序列化过程可能存在安全风险,尤其是在旧版本的...
Avro是Apache的一个数据序列化系统,提供了丰富的数据结构类型、快速的序列化机制、可用于远程过程调用等。 Hadoop的架构设计使得它特别适合于大规模数据分析和存储,它解决了在处理PB级别数据时的可扩展性和成本...
首先,Spring监听器是基于事件驱动模型的,这种模式在多线程和分布式系统中非常常见。在Spring中,当一个特定的事件发生时,如bean的初始化或销毁,上下文的启动或关闭等,Spring会通过发布事件(publishEvent)来...
消息队列(MQ)是现代分布式系统中用于应用程序间通信的一种技术,它允许不同进程之间通过消息传递的方式进行异步数据交换。消息队列的主要作用是实现生产者和消费者的解耦,即生产者负责发送消息,而消费者负责接收...