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.xdnf.cn/news/139112.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

Amazon Lightsail——兼具亚马逊云科技的强大功能与 VPS 的简易性

对于开发者而言&#xff0c;当你想构建系统架构时&#xff0c;你的面前就出现了两种选择&#xff0c;选择一&#xff1a;花时间去亲手挑选每个亚马逊云科技组件&#xff08;云服务器、存储、IP 地址等&#xff09;&#xff0c;然后自己组装起来&#xff1b;选择二是只需要一个预…

个人博客网站一揽子:Docker搭建图床(Lsky Pro)

Lsky Pro 介绍 Lsky Pro 是一个用于在线上传、管理图片的图床程序&#xff0c;中文名&#xff1a;兰空图床&#xff0c;你可以将它作为自己的云上相册&#xff0c;亦可以当作你的写作贴图库。 兰空图床始于 2017 年 10 月&#xff0c;最早的版本由 ThinkPHP 5 开发&#xff0…

【ICCV 2023】FocalFormer3D : Focusing on Hard Instance for 3D Object Detection

原文链接&#xff1a;https://arxiv.org/abs/2308.04556 1. 引言 目前的3D目标检测方法没有显式地去考虑漏检问题。   本文提出了困难实例探测&#xff08;HIP&#xff09;。受目标检测的级联解码头启发&#xff0c;HIP逐步探测误检样本&#xff0c;极大提高召回率。在每个阶…

第三天:实现网络编程基于tcp/udp协议在Ubuntu与gec6818开发板之间双向通信

互联网地址 每一台设备接入互联网后&#xff0c;都会举报一个唯一的地址编号 IP地址 INTERNET地址 internet地址 &#xff1a;它是协议上的一个逻辑地址 目前来说&#xff0c;我们主要的IP地址有两类 IPV4 IPV6 IPV4 其实就是使用一个32bit整数作为IP IPV6 其实就是使用一…

【C++】模板初阶

今天开始将图片的水印全部去掉&#xff0c;以方便大家的观看和知识截屏分享&#xff0c;希望对大家都有所帮助 模板初阶目录&#xff1a; 一、什么是泛型编程&#xff08;编写与类型无关的代码&#xff09; 二、函数模板 2.1概念与格式 2.2底层原理 2.3实例化&#xff08;…

基于Spring Boot的网上购物商城系统

目录 前言 一、技术栈 二、系统功能介绍 用户功能模块的实现 管理员功能模块的实现 商家功能模块的实现 三、核心代码 1、登录模块 2、文件上传模块 3、代码封装 前言 本课题是根据用户的需要以及网络的优势建立的一个基于Spring Boot的网上购物商城系统&#xff0c;…

记录一次错误---想让U-net网络输入大小不一致的图片

最近在看Deeplab系列的论文&#xff0c;文中提到了语义分割领域的一个难题是&#xff1a;将图片输入网络之前需要resize成统一大小&#xff0c;但是resize的话会造成细节信息的损失&#xff0c;所以想要网络处理任意大小的图片输入。我之前训练的U-net网络都是resize成224*224大…

极简解析!IP计费的s5爬虫IP

大家好&#xff01;今天我将为大家分享关于s5爬虫IP服务的知识。对于经常做爬虫的小伙伴来说&#xff0c;需要大量的爬虫IP支持爬虫业务&#xff0c;那么对于选择什么样的爬虫IP&#xff0c;我想我有很多发言权。 下面我们一起了解下IP计费的s5爬虫IP的知识&#xff0c;废话不…

uniapp 内容展开组件

uni-collapse折叠面板并不符合需求&#xff0c;需要自己写一个。 效果展示&#xff1a; 代码&#xff1a; &#xff08;vue3版本&#xff09; <template><view class"collapse-view"><view class"collapse-content"><swiper:autopl…

AIMS医院手术麻醉信息系统全套源码,自主版权,开箱即用

手术麻醉临床信息系统有着完善的临床业务功能&#xff0c;能够涵盖整个围术期的工作&#xff0c;能够采集、汇总、存储、处理、展现所有的临床诊疗资料。通过该系统的实施&#xff0c;能够规范麻醉科的工作流程&#xff0c;实现麻醉手术过程的信息数字化&#xff0c;自动生成麻…

Dubbo3应用开发—Dubbo序列化方案(Kryo、FST、FASTJSON2、ProtoBuf序列化方案的介绍和使用)

Dubbo序列化方案&#xff08;Kryo、FST、FASTJSON2、ProtoBuf序列化方案的介绍和使用&#xff09; 序列化简介 序列化是Dubbo在RPC中非常重要的一个组成部分&#xff0c;其核心作用就是把网络传输中的数据&#xff0c;按照特定的格式进行传输。减小数据的体积&#xff0c;从而…

数据中心液冷服务器详情说明

目录 前言 何为液冷服务器&#xff1f; 为什么需要液冷&#xff1f; 1.数据中心降低PUE的需求 2.政策导向 3.芯片热功率已经达到风冷散热极限 4.液冷比热远大于空气 液冷VS风冷&#xff0c;区别在哪&#xff1f; 1.液冷服务器跟风冷服务器的区别 2.液冷数据中心跟风冷…

前端技术社区总目录

前端技术社区欢迎您的订阅。订阅后&#xff0c;您将可以查看以下所有博客内容。 注&#xff1a;专栏内容主要面向新手 注&#xff1a;每个示例都有相对应的完整代码 注&#xff1a;该专栏博客内容将会逐步迁移至https://blog.csdn.net/m0_60387551/article/details/128017725 …

Ubuntu修改静态IP、网关和DNS的方法总结

Ubuntu修改静态IP、网关和DNS的方法总结 ubuntu系统&#xff08;其他debian的衍生版本好像也可以&#xff09;修改静态IP有以下几种方法。&#xff08;搜索总结&#xff0c;可能也不太对&#xff09; /etc/netplan (use) Ubuntu 18.04开始可以使用netplan配置网络&#xff0…

数学建模——统计回归模型

一、基本知识 1、基本统计量 总体&#xff1a;研究对象的某个感兴趣的指标。样本&#xff1a;从总体中随机抽取的独立个体X1,X2,…,Xn&#xff0c;一般称(X1,…,Xn)为一个样本&#xff0c;可以看成一个n维随机向量&#xff0c;它的每一取组值(x1,…,xn)称为样本的观测值。统计…

哈希 -- 开散列

unordered_map和unordered_set 哈希/散列 -- 值跟存储位置建立映射关系 当不同的值映射到了相同的位置 -- 哈希冲突 / 哈希碰撞 开放定址法&#xff1a; a.线性探测 b.二次探测 负载因子&#xff1a; 越大冲突概率越大 越小冲突的概率越小 但是当负载因子到一个基准值…

yolov5的改进思想

Yolo v5一共有四个模型,分别为Yolov5s、Yolov5m、Yolov5l、Yolov5x。 Yolov5s网络最小,速度最少,AP精度也最低,如果检测的以大目标为主,追求速度,倒也是个不错的选择。 其他的三种网络,在此基础上,不断加深加宽网络,AP精度也不断提升,但速度的消耗也在不断增加。 …

黄金代理如何选择平台?窍门在这儿

作为一个黄金代理平台&#xff0c;什么才是最重要的呢&#xff1f;笔者认为以下三个方面是最重要的&#xff0c;一个是资质&#xff0c;第二个是口碑&#xff0c;第三个是平台的软件。这三者是成为黄金代理要考虑的最重要的三个因素&#xff0c;也直接关系大黄金代理的职业生涯…

ESP32低功耗蓝牙BLE通信

ESP32低功耗蓝牙BLE通信 蓝牙分类GATT协议GATT角色ESP32蓝牙简介ESP32开发板作为BLE服务设备或扫描设备手机APP连接作为BLE Server的ESP32总结 蓝牙分类 经典蓝牙Classic Bluetooth&#xff09;&#xff1a;用于数据量比较大的传输&#xff0c;如&#xff1a;图像、视频、音乐…

GaussDB技术解读系列:性能调优

近日&#xff0c;在第14届中国数据库技术大会&#xff08;DTCC2023&#xff09;的GaussDB“五高两易”核心技术&#xff0c;给世界一个更优选择专场&#xff0c;华为数据库技术专家李士福详细解读了GaussDB性能调优的相关技术和应用实践。 本篇为大家分享GaussDB性能调优的实践…