Apache Skywalking 实战 阅读笔记 第三章 Apache Skywalking 实战 阅读笔记 第三章一、参考资料二、笔记总结第3章 Apache SkyWalking实战本章首先介绍后端技术栈的两种技术路线选择并介绍SkyWalking针对它们所采取的不同应对方式而后将通过一个具体示例展示如何使用SkyWalking来监控系统在该示例的基础上详细介绍多种监控指标的含义读者可以对照示例加深对这些指标的理解最后介绍如何配置监控模块、设置监控目标等内容。3.1 SkyWalking与单体应用架构现在通过具体例子为读者展示一个典型的单体应用架构如图3-1所示。使用Apache或者Nginx作为前端的负载均衡器服务层是Java的Web应用数据层是一个关系型数据库这里我们用MySQL来演示。3.1.2 单体应用架构的优缺点这个方案的优点包含以下三点第一开发简便。当前开发的目标工具和IDE都对这种开发模式有较好的支持。第二易于本地部署。你可以很容易地用War包将它部署到一个比较适合的应用程序包括Tomcat、Weblogin和Websphere等。这些容器的部署流程都非常简单。第三易于扩展。在Nginx和Apache等前端负载均衡器的协助下或使用F5追求更高性能可以很容易地将流量均匀分发在启动的多个实例上。这种架构的弊端第一由于单体应用的代码库非常庞大开发人员修改代码会非常困难而且也给新人员理解整个代码结构带来了非常大的挑战。这导致整个开发节奏变得非常缓慢而且模块之间的边界不清楚也很难构建一个统一的开发库来支持所有的项目。第二为本地的IDE带来非常大的负担。大的代码结构对编译、启动都会有非常高的要求。如果开发人员的本地开发机配置较低会增加无法启动或者启动失败的风险。第三对于Web容器的负担也比较大。由于构建包体量巨大经常超过500MB​有些开源Web容器就没法载入这些应用了。通常这时我们会转向一些商业项目但它所需的机器规格更高且有一些许可证购买需求会让你花费更多的金钱在庞大的应用部署上。第四持续构建比较困难。因为代码库比较大每一次编译重新发布都会花费非常多的时间。有的时候整个CI流程中的某一环节失败而这并不是由运行该CI的开发人员所引入的会更加拖慢流程的进度。第五所谓的系统扩展性好也仅是针对于流量的横向扩展。应用程序的流量可以扩展但背后的数据是不能扩展的。图3-1中有一个单一的MySQL节点所有应用程序均需访问这个单一的数据中心。如果你的数据成几何倍数地增加单一的数据节点往往是不能扩展的最终导致整个应用无法扩展。3.1.3 SkyWalking对单体应用架构的适用性那么对于SkyWalking这种分布式的追踪系统单体应用是不是可以借助它来解决问题呢首先我们要明确的一点是像SkyWalking这种追踪应用是可以应用于单体应用的。但这么做的性价比不高原因如下。第一资源的性价比。第二追踪系统的对手远比它的功能强大。基于以上两点SkyWalking这种追踪系统可以用但是不太适合于单体应用。3.2 SkyWalking与微服务架构由于传统数据交换格式与移动应用程序不兼容而移动应用需求的增加迫使后端架构发生变化这是将单体架构迁移到微服务架构的主要原因。如图3-2所示微服务架构是用多个被称为服务的小单元去构建大型企业级应用集群的架构方法。举例来说一个电商微服务架构集群会包含商品展示、购物车、订单、支付和库存等服务。这些服务都可以单独部署和测试这样这些服务就可以交给不同的团队进行独立维护了。服务之间往往都使用统一的协议进行交互比如Dubbo、gRPC和REST等。它们可以在一台主机或不同的主机上运行并且这些服务都运行在自己独立的进程内部。每个服务可以有自己的数据库或存储层也可以共享公共数据存储。如前所述传统单体架构会逐步产生代码臃肿、维护困难和难以扩展等问题。而针对以上问题微服务架构带来了如下的好处每个微服务都很小并且专注于特定的功能/业务需求微服务可以由小型开发团队通常是25个开发人员独立开发微服务是松散耦合的这意味着服务在开发和部署方面都是独立的微服务可以用不同的编程语言开发微服务允许利用新兴的和最新的技术框架、编程语言、编程实践等​微服务允许使用持续集成工具轻松灵活地集成自动部署微服务很容易根据需求扩展。微服务也有一些不足之处如增加了大量的操作开销需要DevOps技能因分布式系统而导致的管理复杂、bug追踪变得具有挑战性。其中比较重要的问题是系统观察性问题请试着回答如下问题一次调用到底穿越了几个服务在处理这次请求的时候每个服务到底做了什么操作如果请求变慢了瓶颈在哪里如果请求失败了到底是哪个服务或服务中的哪个部分出了问题异常请求与正常请求的区别是什么一次请求中有些经常调用的服务为什么不调用了或者有些不常见的服务为什么被调用了调用的关键路径是什么3.2.1 远程过程调用远程过程调用(RPC)是一类服务之间数据交互模式的统称。通俗来讲RPC通过把网络通信抽象为远程的过程调用使调用远程的过程就像调用本地的子程序一样方便从而屏蔽了通信复杂性使开发人员可以无须关注网络编程的细节将更多的时间和精力放在业务逻辑本身的实现上提高了工作效率。SkyWalking对远程过程调用框架支持的范围是最广的。国内及国际知名的框架如Apache Dubbo、gRPC和Spring Cloud等都是该领域的佼佼者而SkyWalking对这些框架都有比较成熟的解决方案。3.2.2 外部服务外部服务通常包括这几种类型中间件、数据存储和API服务。1. 中间件常见的中间件一般包括以下两种类型。首先是消息队列。Kafka、RocketMQ这些常见的队列都是高性能数据处理的重要手段。SkyWalking对于这种消息队列中间件也有较好的支持可以追踪到数据是如何写入到队列中又是如何被消费掉的。数据在消息队列中是异步处理的这是定位队列问题的难点也是运维消息队列的痛点针对这一点SkyWalking给出了很好的解决方案。其次是与数据存储相关联的也就是数据库中间件。常见的一种使用模式就是分库分表中间件如Apache ShardingSphere。使用SkyWalking可以看到一些数据库中间件是如何将一个请求拆分写入到多个数据库实例中的并能追踪到一次数据库查询是如何在数据实例之间进行执行哪个数据实例的响应是缓慢的哪个数据库实例的执行产生了错误。2. 数据库数据库是一种数据存储服务。SkyWalking的发布版本对主流开源的关系型数据库进行了支持包括常见的H2、MySQL和PG数据库等。对于Oracle等商业数据库SkyWalking借助社区的力量进行了支持相关代码与构建物均放入社区库中这主要是因为具有商业协议的组件是不允许包含在开源项目中。同时对于一些新型的数据库如内存型数据库Redis、文档型数据库MongoDB等SkyWalking也进行了支持。目前SkyWalking均是在数据库驱动内植入相关插件来检查客户端对数据库的访问并没有侵入数据库服务端。3. API服务最后一种外部服务是API服务。通过SkyWalking可以看到调用第三方API的过程并观测到这些服务的质量和对系统关键路径的影响。SkyWalking在插件层面支持了多种API访问通过客户端的自动数据埋点支持HTTP协议、gRPC协议。通过这些插件用户能够很容易地追踪这些外部API服务。最后需要强调的是由于SkyWalking高效且便捷的定制能力用户可以根据自己的系统建设情况扩充已有的开源插件库将企业内部大部分关键组件纳入其追踪范围之内。目前社区内部除核心的Java语言探针之外同时有多种语言探针的实现如.Net、PHP、Node.js和Go。这些探针都是由社区孵化的并拥有广泛的用户群。3.3 实战环境搭建3.3.1 SkyWalking后台搭建3.3.2 实战集群搭建3.4 实战操作这一节将详细解读SkyWalking产生的各种监控指标的含义。本节首先会介绍监控指标的各种维度这些维度是SkyWalking的内置概念了解它们是掌握监控指标的基础。之后会介绍相关监控的核心功能这部分包括一般的查看监控指标和使用拓扑图观察系统架构。最后将介绍生产系统中常见问题的定位包括提取关键路径、查找失败服务或请求以及查找慢服务或请求。3.4.1 观察微服务中的各个维度我们从UI上看一个具体的例子。如图3-4所示projectA就是服务/projectA/{name}是端点{name}表示的是这个端点是个具有路径参数的URL。projectA-pid:23536remote-worker-hk就是服务实例其中remote-worker-hk是机器的主机的hostname, 23536为该实例的进程号。3.4.2 观察指标监控系统的核心功能就是对于监控指标的观察。图3-5展示了服务监控指标的Dashboard如服务数量、平均延迟、吞吐量、服务质量、延迟等高线、服务依赖关系和TopN指标等。UI同时提供对于数据库相关指标展示的Dashboard如图3-6所示。除了与服务监控Dashboard相同的指标外慢SQL查询是一个非常吸引人的功能可以帮助用户快速定位数据库访问类的问题。未来将会有更多中间件包括队列和缓存等指标的展示。另外指标Dashboard是可以进行定制化的。3.4.3 观察系统架构图3-8展示了该实战环境的拓扑关系用户通过projectA服务访问集群其为一个Spring MVC服务。projectA访问projectB和projectC两个Spring MVC服务。projectB访问本地的H2数据库。projectC访问www.baidu.com并同时向一台Kafka消息队列写入数据。projectD从该Kafka消费数据。projectA、projectB和projectC同时访问:8761服务从我们的安装过程可知这是Eureka服务。1. User点的产生把User理解为一个进入监测目标系统的入口2. 访问外部服务可以通过访问服务的Client驱动程序来识别这些外部服务SkyWalking的Agent探针有大量的插件用于识别这些外部服务目前主流的中间件和数据库均涵盖其中。3. 受监控服务的直接访问那么如果是受SkyWalking监控的两个服务直接调用呢答案是Detect Point会同时产生Server和Client两套数据。读者会发现这里大部分指标都类似只有响应时间出现略微的差异Client端的延迟率高一些。这一点很好解释那就是从客户端角度看响应时间还包含网络的延迟故其值要略高于Server端。3.4.4 提取关键路径由于系统是动态变化的SkyWalking的关键路径分析均是与时间相关联的分为对于单次请求的路径分析和对于一段时间内的路径分析。它们分别使用如下两个工具。1. 使用追踪查询图3-14最右侧为延迟时间条形图。通过这个条形图可以很容易发现延迟高的部分同时对链路内各个追踪片的延迟有总体上的印象。故列表视图对观测延迟很有帮助。让我们使用如图3-15所示的表格视图(Table)来定位关键路径。我们可以看到该请求有两个入口分别是projectA和Kafka的consumer。由于Kafka消费不会对用户体验产生影响故我们只关注进入projectA的请求。projectA分别访问了projectB和projectC从Exec(%)列可以看到这两个请求分别大约占到了projectA总延迟的一半故我们可以说projectB和projectC都是关键路径上的点。2. 使用拓扑图如果要观测一段时间内的关键路径拓扑图是一个很好的辅助工具。图3-16和图3-17分别是projectA→projectB和projectA→projectC的调用详情。我们可以使用Avg Latency Avg Response Time × Avg Throughput 来计算请求的流量分布从图中的数据可以推导出projectB和projectC平分了projectA的响应时间。3.4.5 查找失败服务或请求首先最直观的体现就是如图3-19中所示的变化。从图中可以看到不仅projectB变了颜色projectA受其影响也变了颜色。如果你配置了告警的Webhook将会收到相关告警信息从而知道错误的产生。选择状态为Error的追踪数据如图3-23所示。从追踪列表可得主要原因或者说根本原因是projectB报错导致请求失败。我们可以接着点击projectB获得如图3-24所示的具体错误原因。3.4.6 查找慢服务或请求SkyWalking推荐使用如图3-25所示的响应时间百分比图来观测延迟情况该图使用50%、75%、90%、95%和99%请求响应线图中左侧从下往上排列来衡量延迟对于整体的影响帮助用户对当前系统延迟有更精确的把握。我们可以通过拓扑图来查找延迟的根源。这里我们以图3-27中的projectC举例。其平均延迟在1.7s左右。它有两个依赖的外部服务让我们通过图3-28和图3-29分别看一下每个服务的延迟。两个外部服务合计占用了约0.5s, projectC本身消耗了约1.2s那么主要延迟出现在projectC的内部逻辑中。也可以通过追踪数据进一步印证我们的观点如图3-30所示外部服务的延迟确实比较小。最后另外一种常见的慢请求来自慢SQL。如图3-31所示Database的指标页面会列出来最主要的慢SQL以方便用户快速解决主要的慢查询。3.4.7 处理告警SLOService-Level Objective服务级别目标SLO是从Google的SRE体系发展而来的。在谈SLO之前一般用户应该对SLAService-Level Agreement服务级别协议有所了解。SLA 分为SLIService-Level Indicator服务级别指标​大多数服务将请求等待时间返回对请求的响应需要多长时间视为关键SLI。其他常见的SLI包括错误率和系统吞吐量常以每秒请求数衡量​。SLO它是由SLI衡量的服务级别的目标值或值范围。因此SLO的结构是SLI≤目标值或下限值≤SLI≤上限值。例如我们可能决定采用这样的SLO平均查询请求延迟时间应小于100ms。1. SLO设定选择适当的SLO是一件很难的事情。第一你不一定能知道选择什么样的值。对于从互联网而来的HTTP请求每秒查询(QPS)指标基本上由用户的需求决定你不能以此为凭据设置SLO。第二你希望每个请求的平均延迟小于200ms而设置这样的目标可能反过来会激发开发人员去实现更低的延迟或者加大投入购买更多的设备。这样虽然看起来是好事但随着时间的推移原有SLO会变得毫无意义。第三这点是比较微妙的。这两个SLIQPS和延迟可能有一定关联性更高的QPS通常会导致更大的延迟并且服务的性能在超出某些阈值后会出现大范围波动。设置SLO时要充分与用户积极沟通设置合理的目标。用户对性能往往存在过于理想化的需求如果没有设置目标的过程非常容易得到一个不切实际的性能目标甚至性能目标会与系统的设计和维护目标背道而驰。2. 告警阈值设置SLI对应为metrics-name和include-names。如果没有后者该监控指标的所有服务均会被设置上此告警规则。告警阈值只支持数字类型。其中period和count需组合在一起使用。如“period10, count3”表示每10分钟内出现3次满足告警条件的情况告警即被触发。silence-period表示告警触发后如果有持续告警必须超过该时间。默认它与period保持一致。这个参数是为了防止因频繁产生告警而影响维护人员的判断。3. 告警结果通知SkyWalking并没有插件化告警通知机制而是使用Webhook将告警信息推送给一个HTTP服务而后由该HTTP服务决定如何处理信息可以选择发送到各种通知渠道如邮件、微信和手机短信等也可以触发多样的自动故障恢复机制。这些策略完全由用户控制。SkyWalking从6.5.0版本开始可以通过动态配置模块去配置告警规则和结果通知。由于是动态生效规则会在一个时间窗口后才生效。4. 消除告警结果获得通知或者主动发现告警信息后可以通过如图3-32所示的告警页面进行查找。重新打包并部署projectB服务现在我们发现相关告警信息已经消除了。3.5 本章小结下一章我们将开始深入到SkyWalking的实现、模型和设计层面进一步了解SkyWalking如何实现本章介绍的各种特性。