SkyWalking入门之Agent原理初步分析

一、简介

        当前稍微上点体量的互联网公司已经逐渐采用微服务的开发模式,将之前早期的单体架构系统拆分为很多的子系统,子系统封装为微服务,彼此间通过HTTP协议RESET API的方式进行相互调用或者gRPC协议进行数据协作。

        早期微服务只有几个的情况下,我们遇到问题可以直接简单、快速地通过采集日志进行分析,是A服务存在问题还是B服务存在问题,可以快速恢复服务。但是,如果微服务数量已经到达了几十个、甚至上百个,这些微服务之间的调用关系会变得错综复杂。如果某个API接口的业务逻辑很复杂、调用链路长,涉及的微服务较多,那么一旦其中一环出现问题,想要快速定位问题和解决问题,如果还是按照早期一一查看日志的方式进行排查,无疑对运维和开发人员是一场噩梦....., 等把问题定位出来再恢复,影响至少都是几个小时,几个小时对于大型互联网企业的损失不言而喻,可能今年部门年终奖都得凉凉~

        所以作为开发以及运维团队, 我们急需一套APM(应用性能管理(Application Performance Management))系统,将我们业务开发与运维制定规范嵌入APM系统,通过可视化UI面板+告警就可以很快速地通过例如服务调用链的拓扑图进行问题定位,最后解决问题,实现服务的短时间恢复。

        APM系统开源的其实有很多产品,例如韩国主导的Pinpoint、大众点评的CAT、推特的ZipKin、CNCF的Jaeger以及本文重点介绍的Apache SkyWalking. 感兴趣的同学都可以一一了解和使用。

        APM重点关注三个指标或者说三个维度数据: 1、metrics  2、logging  3、tracing

        metrics:  服务指标, 例如Prometheus暴露出来的metrics,我们可以知道服务运行状态、报错数量、异常数量等等

        logging:  日志采集,这个也是APM中重要的维度信息,因为通过metrics我们只是知道某些服务出现了问题,但是具体问题详情,需要靠日志进一步分析具体原因

        tracing:  调用链追踪,我们可以通过将这些服务之间的调用信息记录下来,最终形成调用链有向无循环图,方便我们查看是哪个链路上出现了问题以及也可以看到链路的性能情况

        Aapache SkyWakling目前在tracing方面关注度和擅长度较高,其他2个维度也有在慢慢做起来。

  二、SkyWalking

        SkyWalking 是基于 Apache 开源生态的分布式应用性能监控系统。它提供了面向云原生架构的 APM(Application Performance Management)解决方案,支持多种语言的应用和多种方式的部署,具有以下特点:

                分布式追踪:支持多种语言、多种协议的应用追踪,可获取全链路的请求数据。
                应用拓扑图:根据追踪数据自动生成应用程序拓扑,便于系统管理员快速定位故障。
                监控告警:具有丰富的监控指标和告警规则,支持第三方告警接口。
                插件化体系:可通过插件模块实现对不同类型服务的监控和数据收集。


        SkyWalking 的设计理念是高度灵活和可扩展的,可以自定义仪表板、告警规则、数据接口等。它可以帮助用户诊断系统性能问题、提高系统的可用性和吞吐量,在企业级系统的性能管理、调优和问题排查中发挥重要作用。

        SkyWalking 由中国华为和 Apache 开源社区共同开发,目前已成为 Apache 基金会下的顶级项目之一,作者吴晟。

        SkyWalking 于2017年11月进入 Apache 孵化器(Apache Incubator),成为 Apache 软件基金会的一个开源项目。经过一段时间的发展和孵化,SkyWalking 在2019年2月毕业,成为 Apache 软件基金会的顶级项目。成为顶级项目意味着 SkyWalking 已经发展成熟并受到广泛认可,具有良好的社区治理和持续的技术发展。同时,作为顶级项目,SkyWalking 继续在 Apache 的指导下发展,并得到了更多的关注和支持。

        项目Github地址: https://github.com/apache/skywalking

        官网地址: https://skywalking.apache.org/

       SkyWalking的主要特点和优点,我认为相对其他开源项目是:

       SkyWalking Agent采集调用链信息的客户端对业务是无感的、非侵入式的。 那也就意味着,你的项目代码无须修改一行代码就能加入SkyWalking的采集、监控、调用链追踪。

        这个特点真的很牛逼🐂,那也就意味着你原来的项目接入SkyWalking很轻松、门槛很低。 底层大概得原理是, JAVA本身就提供JAVAAGENT的机制以及采用动态修改字节码技术的方式,Agent在JVM底层帮我们把调用链采集上报的过程透明化了,开发人员作为业务层写代码是无感的。

        我们先记住这个大概的原理,下面我会在入门案例先也会简单做个初步分析和验证。

  三、SpringBoot+SkyWalking+PHP简单入门与分析

1、安装SkyWalking的OAP系统安装包

下载:  SkyWalking的OAP压缩包

下载页面: Downloads | Apache SkyWalking

2、运行OAP

1、解压 apache-skywalking-apm-9.3.0.tar.gz

tar -zxvf apache-skywalking-apm-9.3.0.tar.gz

2、进入apache-skywalking-apm-9.3.0

进入bin目录有启动脚本,我们先启动oapService.sh(服务端)、再启动webappService.sh(UI客户端)

启动完毕,执行jps程序查看进程有没有正常拉起来:

正常会出现上面两个进程,如果没有拉起来在logs目录可以查看错误信息进行排查:

3、访问SkyWalking 8080 UI界面

http://$ip:8080

        目前刚开始服务列表这些是空的, SkyWalking支持多种数据存储介质例如默认内存、MySQL、ES等等,一般生产环境使用ES集群进行存储,我们测试直接不用改什么配置,默认采用内存的形式。那就意味着如果服务重启,则之前的测试数据会丢失

4、Trace调用链追踪的基本原理介绍

        Trace调用链追踪,例如A->B->C->D  存在4个微服务的调用链关系。 假设我们通过HTTP协议进行交互,该怎么把调用链信息拿到呢? 

        Google的Dapper论文中提到了一种分布式调用链追踪的实现方式, 市面上的APM系统调用链追踪大部分是参考这篇论文实现的。 每个调用链可以使用TraceId进行标识,每个服务被调用称为一个Span会伴随一个SpanId, 每当父服务调用子服务的时候会将TraceId以及父层的SpanId往子服务传递,子服务收到后,记录父层传递的SpanId作为自己Span的父id,  最后2个服务都会把调用信息上报到APM的服务端,例如SkyWalking的某个端口.

        最后SkyWalking因为采集到了这些Span的信息,Span信息记录着父子关系、调用时间信息、TraceId等等,经过UI绘制,就能把这一次调用的TraceId的所有Span进行串联,最终形成调用链拓扑图。

        接下来我们部署一个SpringBoot项目和一个PHP项目,很简单的链路,SpringBoot调用PHP项目的HTTP接口,我们来看下SkyWalking的UI界面以及分析原理验证。

5、部署一个PHP项目

代码很简单,一个PHP文件即可, index.php。大家自行安装php环境

<?php$headers = $_SERVER;
$http_sw8 = !empty($headers['HTTP_SW8']) ? $headers['HTTP_SW8'] : '';
// 解析HTTP请求头, SkyWalking在SpringBoot底层字节码做了手脚, 往HTTP Header注入了这么几个Header
// HTTP_SW8_CORRELATION
// HTTP_SW8_X
// HTTP_SW8  一个以 - 分隔的字符串, 每个字符串是base64编码,所以需要解码就能看到明文信息
$params = explode('-', $http_sw8);$vals = [];
foreach ($params as $param) {if (strlen($param) <=1 ) {$vals[] = $param;}else{$decode_val = base64_decode($param);if($decode_val === false) {$vals[] = $param;}else{$vals[] = $decode_val;}}
}
$data = ['raw_header' => $headers,'http_sw8_decode' => ['HTTP_SW8_CORRELATION' => !empty($headers['HTTP_SW8_CORRELATION']) ? $headers['HTTP_SW8_CORRELATION'] : '','HTTP_SW8_X' => !empty($headers['HTTP_SW8_X']) ? $headers['HTTP_SW8_X'] : '','HTTP_SW8' => $vals]
];header("Content-type: application/json;charset=utf-8");
echo json_encode($data);

很简单,大家看下基本就知道,提供的这个index.php做了一件事就是从HTTP请求头拿到一些信息,针对这些信息做一个分析,最终返回给客户端仅此而已。

运行服务: 

php -S 0.0.0.0:8090 index.php

浏览器访问服务看下是否正常: http://$ip:8090 

6、部署一个SpringBoot项目

写了一个简单的Controller, 就是调用PHP项目的index.php URL,拿到数据后返回给用户显示, controller代码如下:

package com.example.controllers;import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;import java.util.HashMap;
import java.util.Map;@RestController
@RequestMapping(path = "/user")
public class User {@GetMapping(value = "/list")public Map<String, Object> list() throws JsonProcessingException {RestTemplate restTemplate = new RestTemplate();String url = "http://192.168.30.15:8090/index.php";ResponseEntity<String> response = restTemplate.getForEntity(url, String.class);String responseBody = response.getBody();Map<String, Object> m = new HashMap<>();ObjectMapper objectMapper = new ObjectMapper();Map<String, Object> resp= objectMapper.readValue(responseBody, new TypeReference<HashMap<String, Object>>() {});m.put("resp", resp);return m;}
}

    代码逻辑很简单

7、运行Springboot+SkyWalking Agent

    SpringBoot项目倒是部署好了,但是如果只是简单运行,那肯定和我们的SkyWalking还没进行结合。那怎么结合起来呢?  那就是通过运行的时候,设置参数,和SkyWalking Agent进行结合。

     我们上面提到过,使用SkyWalking Agent最大的好处就是【无代码侵入】,那也就是意味着我们的源代码无须做任何变更, 只需要在运行java -jar JAR包的时候额外加入一下参数即可:

        下载Agent:

        

        解压skywalking-agent.jar:

        找到skywalking-agent.jar所处的绝对路径, 记录一下.

        运行SpringBoot项目需要加入参数如下:

-javaagent:/root/apache-skywalking-java-agent/skywalking-agent/skywalking-agent.jar
-DSW_AGENT_NAME=sw-springboot
-DSW_AGENT_COLLECTOR_BACKEND_SERVICES=192.168.30.15:11800-javaagent:  这是 java运行命令可以添加的选项参数, :后面是agent jar包的绝对路径地址
-DSW_AGENT_NAME:  这是传递参数SW_AGENT_NAME, 可以理解为这个微服务的名称
-DSW_AGENT_COLLECTOR_BACKEND_SERVICES: 这个就是要将调用链信息上报的SkyWalking的服务端地址+端口

        运行完毕之后,服务正常启动, 和正常的SpringBoot除了加上面的参数,服务启动没任何区别, 我们多次访问部署SpringBoot服务IP:8080端口:

     可以看到 SpringBoot调用PHP的Web接口后返回了数据进行展示

8、查看SkyWakling的UI后台-服务拓扑图和调用链信息

服务列表信息已经有了数据:

查看调用service调用拓扑图:

查看Span调用链详细信息:

9、初步验证和分析调用链信息采集Agent原理

1、疑问

        通过上面我们就能看到调用链信息,真的好神奇,没改一行业务的Java代码就能做到查询调用链的拓扑图。这是到底是怎么实现的?

 2、非侵入式的原理

       我们没改一行代码,只是注入了javaagent和相关SW的参数,这个javaagent就是关键点。 Java本身就支持这种agent技术,可以在main()函数之前做一些钩子操作,例如对要加载到JVM的class字节码可以进行增强或者说修改吧,没错,就是对你的代码进行动态修改。   字节码都能修改了,Agent代码要做个线程或者进程把这些采集的数据进行上报那不是小case么.

        例如可以在某个class的方法前记录调用使用,在方法后记录时间,两者一减,你的调用时间就出来了,然后再进行上报等等,我理解有点像反射技术哈,不用反射的原因我看资料反馈的是性能较差。

3、Trace的上下文(Span信息)是怎么从父层传递到子层的?

        哈哈,这里就有点意思了。 非侵入式将信息上报给SkyWalking可以理解,那一个SpringBoot项目调用PHP项目,你咋知道这两个Span有啥关系? SpringBoot是怎么传递之前说的TraceId、SpanId传递到PHP服务的的? 毕竟这是在进程、跨服务器通信。

        答案:  就是在传输协议HTTP上做了手脚。  我们之前说了Agent有动态修改字节码的能力,那这个太简单了,我直接在HTTP协议的底层类进行拦截,一旦你进行HTTP请求,我就在你的请求之前,请求头Header注入Span信息,如果对端服务(下游服务)也是用了SkyWalking的Agent,那么它也会从HTTP请求的Header中获取Span信息,从而进行处理,最后上报。

        看下刚才调用SpringBoot的响应内容:

        PHP解析HTTP Header有个规则,都以HTTP_开头, 小写转大写,_下划线转-:

        所以Java SpringBoot那边在header里面传递的Header: HTTP_SW8, 实际是传的sw8作为key

4、查看Agent源码,验证下是不是上面说的在HTTP协议做的手脚

       项目地址:  https://github.com/apache/skywalking-java

        全文搜索一下关键词: sw8可以看到定义了这个header信息的类:

        

      发现了关键字样,看起来是SW8携带数据Item class的定义.  OK, 那我们再搜索关键词: HttpURLConnection, 为啥搜索这个词?  你上层HTTP封装再牛逼,也逃不了调用底层HTTP请求吧?

        发现了关键代码, 嘿嘿:

     

      咱们对这段代码不太懂是吧? ChatGPT给我上, 看下GPT是怎么理解这段代码的:

    嗖嘎,和猜想的一模一样, Agent就是在底层HTTP请求的时候搞了钩子手脚,每次HTTP请求都是给我把SkyWalking的header加上,方便给下游服务传递Span和Trace上下文,搞定收工

  四、总结

     经过上面的入门和简单分析验证:

     1、我们知道了原来SkyWalking是通过动态修改字节码的方式来达到无侵入式的调用链追踪上报

     2、并且通过分析各种协议例如GRPC、HTTP等常见协议, 通过底层设置钩子,如一旦发现HTTP请求,在Header上注入调用链Span上下文信息到下游服务,最后将这些Span信息上报到SkyWalking的server端,最后经过SkyWalking整理,通过UI界面就能查看到service的调用链拓扑图。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/133091.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Springboot 实践(15)spring config 配置与运用—自动刷新

目前&#xff0c;网络上讲解spring config的自动刷新&#xff0c;都是通过git服务站的webhook功能执行“actuator/bus-refresh”服务实现的自动刷新。我们的前文讲解的配置中心&#xff0c;配置中心仓库使用的时本地地址&#xff0c;如下图所示&#xff1a; 那么&#xff0c;配…

vim的使用介绍以及命令大全

懒羊羊感谢大家的关注和三连支持~ 目录 前言 一、vim的使用介绍 二、命令大全 1.命令模式 &#xff08;1&#xff09;复制&#xff08;配合粘贴命令p使用&#xff09; &#xff08;2&#xff09;剪切 &#xff08;3&#xff09;粘贴 &#xff08;4&#xff09;删除 …

GIS前端编程-Leaflet插件扩展

GIS前端编程-Leaflet插件扩展 Leaflet插件扩展基本原理Leaflet插件扩展开发方法1. L.Handler扩展2. L.Control扩展为了高效率地进行软件开发 Leaflet插件扩展基本原理 Leaflet是面向移动设备和Web的开源JavaScript库&#xff0c;具有设计简单、性能良好和可用性强的特点&#…

c#.NET技术做到ChatGPT流式响应并实现打字机效果 实现ChatGPT的Stream传输

.NET技术做到ChatGPT流式响应并实现打字机效果 ChatGPT是当前备受瞩目的人工智能产品之一&#xff0c;它具备与人类进行智能对话的能力&#xff0c;同时能够理解人类的想法和需求。在内容创作、营销、智能客服、教育、投资等领域和场景中&#xff0c;ChatGPT都展现出了巨大的…

【openKylin】OpenKylin1.0 x86_64 VMWare安装手册

&#x1f341; 博主 "开着拖拉机回家"带您 Go to New World.✨&#x1f341; &#x1f984; 个人主页——&#x1f390;开着拖拉机回家_大数据运维-CSDN博客 &#x1f390;✨&#x1f341; &#x1fa81;&#x1f341; 希望本文能够给您带来一定的帮助&#x1f338;文…

选择器进阶与表单表格

华子目录 选择器并集选择器后代选择器子代选择器伪类选择器伪元素选择器结构选择器属性选择器相邻选择器 表单&#xff08;form&#xff09;label标签 表格&#xff08;table标签&#xff09;合并单元格 选择器 下面是我们之前学习过的选择器 *{}&#xff1a;通配符选择器&am…

分销小程序商城功能_小程序商城适合谁_OctShop

微信推出小程序后&#xff0c;分销小程序商城就受到了非常多企业和商家的关注&#xff0c;通过分销商城小程序企业或商家就可以获得庞大的用户裂变过来的用户&#xff0c;组成一个不断裂变拉新用户的网络&#xff0c;可以大大提高企业或品牌的曝光度&#xff0c;从而提高企业或…

视频图像处理算法opencv模块硬件设计图像颜色识别模块

1、Opencv简介 OpenCV是一个基于Apache2.0许可&#xff08;开源&#xff09;发行的跨平台计算机视觉和机器学习软件库&#xff0c;可以运行在Linux、Windows、Android和Mac OS操作系统上 它轻量级而且高效——由一系列 C 函数和少量 C 类构成&#xff0c;同时提供了Python、Rub…

LeetCode 1282. Group the People Given the Group Size They Belong To【哈希表】1267

本文属于「征服LeetCode」系列文章之一&#xff0c;这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁&#xff0c;本系列将至少持续到刷完所有无锁题之日为止&#xff1b;由于LeetCode还在不断地创建新题&#xff0c;本系列的终止日期可能是永远。在这一系列刷题文章…

《优化接口设计的思路》系列:第二篇—接口用户上下文的设计与实现

系列文章导航 《优化接口设计的思路》系列&#xff1a;第一篇—接口参数的一些弯弯绕绕 《优化接口设计的思路》系列&#xff1a;第二篇—接口用户上下文的设计与实现 前言 大家好&#xff01;我是sum墨&#xff0c;一个一线的底层码农&#xff0c;平时喜欢研究和思考一些技术…

Peppertype.ai:人工智能内容营销平台

【产品介绍】 名称 Peppertype.ai 具体描述 Peppertype.ai是一个AI驱动的文章生成工具&#xff0c;可以帮助你在几秒钟内为各种渠道创建吸引人 的内容。无论你是想要写广告文案、社交媒体标题、博客大纲还是网站内容&#xff0c;Peppertype…

基于SpringBoot蜗牛兼职网的设计与实现【附PPT|万字文档(LW)和搭建文档】

主要功能 前台界面&#xff1a; ①首页、兼职信息推荐、查看更多等 ②职位申请、申请日期、上传简历、点击下载简历、留言反馈等 ③个人中心、上传图片、更新信息等 后台登录&#xff1a; ①用户登录&#xff1a; 个人中心、修改密码、个人信息、职位申请管理 ②企业登录&…

java在mysql中查询内容无法塞入实体类中,报错 all elements are null

目录 一、问题描述二、解决方案 一、问题描述 java项目中整体配置了mysql的驼峰式字段匹配规则。 mybatis.configuration.map-underscore-to-camel-casetrue由于项目需求&#xff0c;需要返回字段为file_id&#xff0c;file_url&#xff0c;并且放入实体类中&#xff0c;实体…

赢麻了!smardaten闷声干大事,竟然用无代码开发了复杂小程序!

本文目录 一、【前言】二、移动端项目实战&#xff1a;女性关爱云服务平台2.1 项目背景2.2 6大场景功能拆解&#xff08;1&#xff09;场景1-首页&#xff08;2&#xff09;场景2-找活动&#xff08;3&#xff09;场景3-找组织&#xff08;4&#xff09;场景4-找服务&#xff0…

无频闪护眼灯哪个好一点?盘点无频闪减蓝光护眼灯

可以肯定的是&#xff0c;护眼灯一般可以达到护眼的效果。看书和写字时&#xff0c;光线应适度&#xff0c;不宜过强或过暗&#xff0c;护眼灯光线较柔和&#xff0c;通常并不刺眼&#xff0c;眼球容易适应&#xff0c;可以防止光线过强或过暗导致的用眼疲劳。如果平时生活中需…

Unity中 UI Shader的基本功能

文章目录 前言一、实现思路1、暴露一个 2D 类型的属性来接受UI的纹理2、设置shader的层级为TransParent半透明渲染层级&#xff0c;一般UI都是在这个渲染层级3、更改混合模式&#xff0c;是 UI 使用的纹理&#xff0c;该透明的地方透明 二、代码实现 前言 Unity中 UI Shader的…

视频怎么压缩?把视频压缩的小一点这样做

视频压缩在我们的生活和工作中有着广泛的应用需求&#xff0c;是一种减少视频文件大小的方法&#xff0c;可以给我们带来以下几个方面的作用&#xff1a; 1、减少存储空间占用&#xff1a;视频压缩可以显著减少视频的大小&#xff0c;从而腾出更多的存储空间&#xff0c;对于手…

创建一个简单的外卖订餐系统

在今天的快节奏生活中&#xff0c;外卖订餐系统已经成为了人们日常生活中不可或缺的一部分。这些系统通过在线点餐和配送服务&#xff0c;为用户提供了便捷的用餐体验。在本文中&#xff0c;我们将创建一个简单的外卖订餐系统&#xff0c;使用Python和Flask框架构建后端&#x…

华为数通方向HCIP-DataCom H12-821题库(单选题:341-360)

第341题 在BGP中代表对等体之间已经建立连接的状态是以下哪一种? A、Active B、Connect C、Established D、Open 答案:C 第342题 以下关于路由选择工具的描述,错误的是哪一项? A、访问控制列表用于匹配路由信息或者数据包的地址,过滤不符合条件的路由信息或数据包 …

EXE文件加密器

EXE文件加密器V3.0&#xff0c;主要是用于对EXE文件进行加密 有需要的朋友下载 点我下载