jjzjj

有了这款工具,定位线上问题事半功倍|云效工程师指北

云效DevOps平台 2023-11-19 原文

大家好,我叫刘玄,负责云效流水线的开发。程序员在日常工作中经常会遇到一些线上问题需要排查,本文的主人公程序员小张也不例外。但排查的过程却时常令他困扰不已。让我们一起看看他遇到了哪些问题,又是怎么解决的。

焦头烂额的一天

那是一个阳光明媚的上午,小张来到工位,打开电脑,备上咖啡,精神满满的开始了一天的工作。正在小张噼里啪啦的敲着键盘,认真Coding之时,钉钉群里的一个钉,打破了宁静。客服人员反馈,有客户遇到了一个问题,需要开发人员排查。小张排查了线上日志,发现用户的请求比较多,日志也比较多,没有定位到关键信息。小张只能又让客服找用户提供更具体的信息。在和用户反复进行沟通之后,小张最终花了半个多小时才定位到了问题。

忙碌的一天很快结束,正当小张准备下班,筹划着下班之后怎么happy时,电话报警的声音,又把他拉回了现实。小张收到后端服务RT高的告警后,赶紧排查多个后台应用的监控信息和日志。虽然很快从Nginx日志定位到了有问题的请求信息,但小张很难精确的找到这个请求对应的应用日志,所以花费了很长时间才定位到问题:一个第三方服务异常,导致部分功能受影响。定位到原因后,及时采取了降级手段,系统恢复正常。

寻求解决问题的方案

过完了焦头烂额的一天,小张觉得现在处理问题的效率太低,大把的时间花在了问题定位上。而之所以排查的这么慢,是因为系统采用微服务架构,一个请求会涉及到多个服务,并且每个服务还会调用DB、缓存以及其他第三方服务。大致链路如下:

小张想,应该有成熟的技术方案,能够标识整个请求链路,将异常服务节点清晰标注。小张借助搜索工具,发现有一种解决方案,链路追踪,刚好适合自己的场景。

链路追踪工具可以将一次分布式请求还原成完整的调用链路,将整个请求的调用情况进行展示,比如各个服务上的耗时、各个服务的请求状态、具体调度到各个服务的哪台机器上等信息。

改造系统

期望的效果

根据前面遇到的两个问题,小张期望:

  1. 用户请求遇到问题时候,可以获取到一个traceId,只要提供了这个traceId,就可以看到这个请求在各个服务之间的调用路径。并且可以通过这个traceId查到所有应用中相关的日志。
  2. 当收到RT告警时,也能够从Nginx的日志中找到这个traceId。

接入链路追踪

经过技术选型,小张选择阿里云的产品链路追踪Tracing Analysis作为自己链路追踪的服务端。

阿里云链路追踪Tracing Analysis提供了完整的调用链路还原、调用请求量统计、链路拓扑、应用依赖分析等工具,可以帮助用户快速分析和诊断分布式应用架构下的性能瓶颈,提高微服务时代下的开发诊断效率。

阿里云链路追踪Tracing Analysis支持多种常见的链路追踪工具,例如Zipkin、Skywalking、Jaeper等。小张选择使用Skywalking作为链路追踪数据埋点。

在阿里云上开通完链路追踪Tracing Analysis 产品之后,就可以在集群配置中获取到Skywalking的接入点。更详细的接入指南参考阿里云官方文档

由于小张的系统是基于spring boot,所以只需要在启动命令中加入以下内容即可。

重新启动应用后,链路追踪埋点数据就会收集到链路追踪Tracing Analysis 上了。

日志中打印traceId

为了能够通过traceId搜索到所有的日志,也需要在的应用的日志中展示traceId信息,具体方式如下:

在应用中引入以下依赖:

修改logback配置文件,例如:tid即为 Skywalking 的traceId。

<property name="LOG_PATTERN" value="[%d{'yyyy-MM-dd HH:mm:ss,SSS',GMT+8:00}] %-5p [%.10t][%X{CU}][%X{tid}]    %logger{36}[%L] - %m%n"/>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
    <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
        <layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.mdc.TraceIdMDCPatternLogbackLayout">
            <pattern>${LOG_PATTERN}</pattern>
        </layout>
    </encoder>
</appender>

以上改动就可以在日志中看到traceId了。如下图所示:图中标红的TID值即为traceId。

同时小张也在系统出现异常信息时,将traceId透出给用户,用户反馈问题时只需要提供traceId即可。相应的,需要在代码中把traceId写入到响应体中,如下所示:

String traceId = TraceContext.traceId();
result.setTraceId(traceId);

Nginx日志中打印traceId

为了在收到系统RT告警时,也可以获得traceId,需要修改Nginx配置。

接入Skywalking之后,系统间调用的请求都会带上名称为sw6的header (其中6为对应的Skywalking版本号),Header值的的格式为:1-TRACEID-SEGMENTID-3-PARENT_SERVICE-PARENT_INSTANCE-PARENT_ENDPOINT-IPPORT从这个值中提取出TRACEID,也就是第一个和第二个横杠之间的部分,再进行BASE64 decode就可以获取到traceId。

然后需要在Nginx 的log_format 配置添加对应的Header,如下如下:

log_format main 'http_sw6:$http_sw6; http_ns_client_ip:$http_ns_client_ip; time_local:$time_local; request_time:$request_time; upstream_response_time:$upstream_response_time; request:$request_method http://$host$request_uri; request_length:$request_length; upstream_cache_status:$upstream_cache_status; httpStatus:$status; body_bytes_sent:$body_bytes_sent; http_referer:$http_referer; http_user_agent:$http_user_agent; http_x_forwarded_for:$http_x_forwarded_for; remote_addr:$remote_addr;';

然后就可以在Nginx日志中看到了相应的值了,如图:

解决链路追踪多线程丢失traceId 的问题

小张在测试链路追踪时,发现在多线程的使用场景中,只有一个子线程能够正确获取到traceId,而其它线程中的traceId会出现丢失。为了解决上述问题,小张使用@TraceCrossThread注解对Callable和Runnable进行增强,@TraceCrossThread为Skywalking提供的注解,Skywalking通过增强被此注解注释的类,以此来实现traceId的跨线程传递。示例代码如下。

后续提交线程任务时使用改造后的TraceableCallable和TraceableRunnable 即可解决多线程丢失traceId 的问题。

完成以上改造后,以下图为例,用户每一次的请求都会有对应的traceId,便于将整个请求链路展示出来。

轻松应对线上问题

又一个阳光明媚的早上,小张埋头工作时,又有客服反馈用户问题,这个时候小张不慌不忙的根据用户提供traceId,在阿里链路追踪https://tracing.console.aliyun.com/上查看调用链路,很快定位到异常节点,示例如下:图中状态为红色的节点就是异常节点,图中示例表示由于某个sql执行出现异常。

轻松应对一天工作后,小张在下班前又收到应用RT过高的告警, 由于Nginx日志中打印了traceId信息,很快就可以定位到耗时的请求,示例如下:

图中耗时比较长的节点,是由于调用第三方服务造成,小张根据情况,对服务进行降级,很快就解决RT过高的问题,防止问题扩散。

接入了链路追踪以后,小张在定位线上问题的耗时大大缩短,可以有更多的时间专注其他工作。

以上就是小张是如何通过使用链路追踪从焦头烂额的排查线上问题到从容定位线上问题的转变,希望对仍未使用链路追踪技术的同学有些帮助。本故事纯属虚构,如有雷同,纯属巧合。


点击下方链接,即可免费体验云效流水线Flow。

https://www.aliyun.com/product/yunxiao/flow?

关于我们

了解更多关于云效DevOps的最新动态,可微信搜索关注【云效】公众号;

福利:公众号后台回复【指南】,可获得《阿里巴巴DevOps实践指南》&《10倍研发效能提升案例集》;

看完觉得对您有所帮助别忘记点赞、收藏和关注呦;

有关有了这款工具,定位线上问题事半功倍|云效工程师指北的更多相关文章

  1. 世界前沿3D开发引擎HOOPS全面讲解——集3D数据读取、3D图形渲染、3D数据发布于一体的全新3D应用开发工具 - 2

    无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD

  2. 基于C#实现简易绘图工具【100010177】 - 2

    C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.

  3. 「Python|Selenium|场景案例」如何定位iframe中的元素? - 2

    本文主要介绍在使用Selenium进行自动化测试或者任务时,对于使用了iframe的页面,如何定位iframe中的元素文章目录场景描述解决方案具体代码场景描述当我们在使用Selenium进行自动化测试的时候,可能会遇到一些界面或者窗体是使用HTML的iframe标签进行承载的。对于iframe中的标签,如果直接查找是无法找到的,会抛出没有找到元素的异常。比如近在咫尺的例子就是,CSDN的登录窗体就是使用的iframe,大家可以尝试通过F12开发者模式查看到的tag_name,class_name,id或者xpath来定位中的页面元素,会抛出NoSuchElementException异常。解决

  4. postman接口测试工具-基础使用教程 - 2

    1.postman介绍Postman一款非常流行的API调试工具。其实,开发人员用的更多。因为测试人员做接口测试会有更多选择,例如Jmeter、soapUI等。不过,对于开发过程中去调试接口,Postman确实足够的简单方便,而且功能强大。2.下载安装官网地址:https://www.postman.com/下载完成后双击安装吧,安装过程极其简单,无需任何操作3.使用教程这里以百度为例,工具使用简单,填写URL地址即可发送请求,在下方查看响应结果和响应状态码常用方法都有支持请求方法:getpostputdeleteGet、Post、Put与Delete的作用get:请求方法一般是用于数据查询,

  5. ruby-on-rails - 有没有一种工具可以在编码时自动保存对文件的增量更改? - 2

    我最喜欢的Google文档功能之一是它会在我工作时不断自动保存我的文档版本。这意味着即使我在进行关键更改之前忘记在某个点进行保存,也很有可能会自动创建一个保存点。至少,我可以将文档恢复到错误更改之前的状态,并从该点继续工作。对于在MacOS(或UNIX)上运行的Ruby编码器,是否有具有等效功能的工具?例如,一个工具会每隔几分钟自动将Gitcheckin我的本地存储库以获取我正在处理的文件。也许我有点偏执,但这点小保险可以让我在日常工作中安心。 最佳答案 虚拟机有些人可能讨厌我对此的回应,但我在编码时经常使用VIM,它具有自动保存功

  6. ruby - 使用 Ruby 开发工具包将文件上传到 Amazon S3 - 2

    我正在尝试上传文件。一个简单的hello.txt。我正在关注文档,但无法将其上传到我的存储桶。#STARTAWSCLIENTs3=Aws::S3::Resource.newbucket=s3.bucket(BUCKET_NAME)begins3.buckets[BUCKET_NAME].objects[KEY].write(:file=>FILE_NAME)puts"Uploadingfile#{FILE_NAME}tobucket#{BUCKET_NAME}."bucket.objects.eachdo|obj|puts"#{obj.key}=>#{obj.etag}"endresc

  7. ruby - 在 StockChart (highchart) 中以编程方式显示柱形图的工具提示 - 2

    我有一个Highstock图表(带有标记和阴影的线条),并且想以编程方式显示一个highstock工具提示,例如,当我选择某个表上的一行(包含图表数据)我想显示相应的highstock工具提示。这可能吗? 最佳答案 股票图表thissolution不起作用:在thisexample你必须更换这个:chart.tooltip.refresh(chart.series[0].data[i]);为此:chart.tooltip.refresh([chart.series[0].points[i]]);解决方案可用here.

  8. ABB-IRB-1200运动学分析MATLAB RVC工具分析+Simulink-Adams联合仿真 - 2

    一、机器人介绍        此处是基于MATLABRVC工具箱,对ABB-IRB-1200型号的微型机械臂进行正逆向运动学分析,并利Simulink工具实现对机械臂进行具有动力学参数的末端轨迹规划仿真,最后根据机械模型设计Simulink-Adams联合仿真。 图1.ABBIRB 1200尺寸参数示意图ABBIRB 1200提供的两种型号广泛适用于各作业,且两者间零部件通用,两种型号的工作范围分别为700 mm 和 900 mm,大有效负载分别为 7 kg 和5 kg。 IRB 1200 能够在狭小空间内能发挥其工作范围与性能优势,具有全新的设计、小型化的体积、高效的性能、易于集成、便捷的接

  9. Ruby & Syslog & 自定义工具 - 2

    我是syslog的新手。我们决定使用系统日志来跟踪Rails应用程序中的一些特殊事件。问题是我不想使用默认的/var/log/system.log文件,而是使用自定义文件,例如/var/log/myapp_events.log.我看到我必须像这样在/etc/syslog.conf中定义我自己的设施:myapp_events.*/var/log/myapp_events.log重新启动syslogd后,我发现我可以直接在bash控制台中使用它:syslog-s-kFacilitymyapp_eventsMessage"thisismymessage"该消息按预期出现在/var/log/m

  10. ruby - 使用 Gatling 作为集成测试工具 - 2

    目前我有一小套针对我的网络服务器运行的集成测试,它发出请求并断言一些关于响应应该是什么的假设。这些是用Ruby编写的,生成http请求。我一直在看Gatling作为压力测试工具,但我想知道它是否也可以用于集成测试。这样,所有端点请求都可以在压力测试和集成测试中重复使用。我可能在这里失去了一些东西,因为没有RSpec的BDD,但不必两次创建相同的测试。有没有人有这样使用gatling的经验? 最佳答案 您可以使用AssertionAPI并设置验收标准。但是,Gatling不是浏览器,不会运行/测试您的Javascript,因此这种方法

随机推荐