skywalking源码分析第二十三篇一扩展篇:全链路压测_skywalking 标签透传-程序员宅基地

技术标签: java  全链路压测  skywalking  skywalking6.x源码分析  

前言

全链路压测时一项系统性工程,包含数据工厂,影子环境,压测脚本,数据偏移,压测平台,链路路由等等
本文重点介绍其中一环,业务应用代码增强

原理

  • 红色表示压测流量
  • 黑色表示业务流量
  • 红色的流量由压测平台[比如jmeter压测集群]发起
  • http发送请求需要在请求头设置一个标记,此标记可以被skywalking识别,后skywalking在TracerContext中标记该请求为压测请求[俗称流量染色]
  • 同时该标记能够从应用一透传到应用二透传到应用三
  • 在写入db时,根据流量染色情况进行路由,业务流量写入正常db,压测流量写入影子库
  • redis,es等也是同理,实现上存储层如db都是同一台物理节点,逻辑存储位置不同,比如同一个mysql,其业务db是biz_db,则影子库是shadow_biz_db
  • mq影子流量和业务流量共用topic
    在这里插入图片描述

基于skywalking的压测实现

本文重点介绍基于skywalking的影子传播机制与存储如何落入影子库表

数据容器改造

  • 除去skywalking源码后,新增压测标记字段

public class TraceSegment {
    
    /**
     * 压测标:表明当前链路是业务流量还是压测流量
     */
    private  boolean pressureTest ;
}
public class ContextCarrier implements Serializable {
    
  /**
     * 全链路压测标志
     */
    private boolean pressureTest;
}

public class ContextSnapshot {
    
  
    /**
     * 全链路压测标志
     */
    private boolean pressureTest;
 
}

对Segment的序列化反序列化改造

public class TracingContext implements AbstractTracerContext {
    
    @Override
    public void inject(ContextCarrier carrier) {
    
        ...... 删除skywalking源码
        跨进程级别的压测标传递
        carrier.setPressureTest(segment.isPressureTest());
        ...... 删除skywalking源码
    }

     
    @Override
    public void extract(ContextCarrier carrier) {
    
        ...... 删除skywalking源码
        跨进程级别的压测标志注入
        this.segment.setPressureTest(carrier.isPressureTest());
    }

    @Override
    public ContextSnapshot capture() {
    
        ...... 删除skywalking源码
        跨线程级别的压测标志注入
        snapshot.setPressureTest(segment.isPressureTest());
        return snapshot;
    } 

    @Override
    public void continued(ContextSnapshot snapshot) {
    
        ...... 删除skywalking源码
        this.segment.setPressureTest(snapshot.isPressureTest());
    }
}

说明

  • 基于上述方案后Segment如果有pressureTest压测标记
  • 则跨进程时先序列化成ContextCarrier,进入下一进程在转为Segment时,能够完成pressureTest压测标记跨进程传递
  • ContextSnapshot同理完成跨线程传递

染色一压测流量识别

  • http请求时,获取其请求头pressureTest标记,给Segment进行染色
  • 标志当前流量是压测流量还是业务流量
  • 注意该请求头只有压测流量携带,业务流量不可以出现,否则造成干扰
public class TomcatInvokeInterceptor implements InstanceMethodsAroundInterceptor {
    
    @Override public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments,
        Class<?>[] argumentsTypes, MethodInterceptResult result) throws Throwable {
    
        ...... 删除skywalking源码
        压测流量识别 染色
        String pressureTest = request.getHeader("pressureTest");
        if(!StringUtil.isEmpty(pressureTest)){
    
            Boolean isPressureTest = Boolean.FALSE;
            try {
    
                isPressureTest = Boolean.valueOf(pressureTest);
            } catch (Exception e) {
    

            }
            TracingContext abstractTracerContext = (TracingContext) ContextManager.get();
            TraceSegment segment = abstractTracerContext.getSegment();
            segment.setPressureTest(isPressureTest);
        }
    }
}

小结

  • 通过对skywalking的改造和tomcat流量的改造
  • 我们的流量具有了识别染色能力和传递压测标能力
  • 则当流量进入http和dubbo以及mq到达jdbc时,压测流量的pressureTest始终是true,业务流量始终是false

核心一影子路由

  • 以下为mysql8.x的jdbc插件影子路由实现
  • 当我们发现是压测流量时,修改业务库为压测库,在库名前增强"shadow_’
  • 此时,业务流量写入db.影子流量写入shadow_db
  • 影子库需要和业务库在同一台db实例上,影子库需提前创建,表与业务库相同
public class StatementCreateInterceptor implements InstanceConstructorInterceptor {
    
    @Override
    public void onConstruct(EnhancedInstance objInst, Object[] allArguments) {
    
        TracingContext abstractTracerContext = (TracingContext) ContextManager.get();
        boolean pressureTest = abstractTracerContext.getSegment().isPressureTest();
        if(pressureTest) {
    
            if (objInst instanceof ClientPreparedStatement) {
    
                第三个参数
                allArguments[2] = "shadow_" + allArguments[2];
                ((ClientPreparedStatement) objInst).setCurrentCatalog((String) allArguments[2]);
            }
            if (objInst instanceof StatementImpl) {
    
                第二个参数
                allArguments[1] = "shadow_" + allArguments[1];
                ((StatementImpl) objInst).setCurrentCatalog((String) allArguments[1]);

            }
        }
    }
}

总结

  • 综上,我们完成了流量染色,链路携带染色标记,基于染色标记完成影子库写入,从而实现了全链路压测中最重要的一环,业务应用字节码增强改造
  • 需要注意,实际环境要覆盖所有的技术组件,比如redis,es等等
  • 还需要考虑类似定时任务等各种业务场景的处理,安全问题等等
  • 本文重点在于引路,如读者有兴趣可以自行专研其他组件压测实现[如有疑问可留言]
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_35529969/article/details/123412991

智能推荐

hdu 3496 二维费用背包_hdu - 3496-程序员宅基地

文章浏览阅读1k次。题意:求在一定l时间内看完n中电影中的m是否可能,若可能则最后快乐度是多少。之前错了好多遍,一直找不到原因,后来在百度上看了很多别人的代码发现只有初始化不同我的初始化: memset(f,0,sizeof(f));别人的: for(int i=0;i for(int j=0;j一开始认为没什么影响,但是苦于一直找不到原因,所以我将自_hdu - 3496

Random、SecurityRandom、Math.random()_securerandom和math.random()-程序员宅基地

文章浏览阅读2k次。下面可以不看,一句话,为了其安全起见,以后我们就用SecurityRandom就好了。JDK中有两个随机数类。一个是PRNG,也就伪随机数类java.util.Random,是采用线性同余算法产生的。另一个是RNG,也就是java.util.Random的子类强随机数java.security.SecureRandom,这是一个SPI类,也就是说具体的算法由Pro..._securerandom和math.random()

npm安装vue报错:npm ERR! code ETIMEDOUT-程序员宅基地

文章浏览阅读8k次,点赞8次,收藏8次。npm安装vue报错npm ERR! code ETIMEDOUT_code etimedout

Linux解决Warning: mysql_connect(): Headers and client library minor version mismatch. 警告_mysql headers:50647-程序员宅基地

文章浏览阅读5k次。这两天用阿里云服务器重新部署网站服务器后,打开某php页面出现了如下警告:Warning: mysql_connect(): Headers and client library minor version mismatch. Headers:50547 Library:50631 in /XXX(某某目录)/wp-db.php on line 1520,虽然是警告,但是有的界面会因此打不开,无法..._mysql headers:50647

Java开发工具评测——后端-程序员宅基地

文章浏览阅读17次。它提供了丰富的功能和工具,帮助开发者编写高效且易于维护的代码。Maven 是一种流行的项目管理工具,用于构建和管理 Java 项目的依赖关系。Eclipse 是另一个受欢迎的 Java IDE,被广泛用于后端开发。每个工具都有其独特的优势和适用场景,开发者可以根据自己的需求和偏好选择合适的工具。这些工具的使用可以提高开发效率、简化开发流程,并改善代码的可维护性和可读性。Java是一种广泛使用的编程语言,用于开发各种类型的应用程序,包括后端服务。在Java开发中,使用合适的工具可以提高开发效率和代码质量。

【牛客】9、青蛙变态跳台阶(斐波那契数列)_牛客网青蛙跳台阶-程序员宅基地

文章浏览阅读156次。一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。思路:当n=1时,f(1)=1当n=2时,f(2)=2当n=3时,第一步可以跳一阶,剩下的是f(2);或者第一步可以跳两节,剩下的是f(1)。即f(3)=f(2)+f(1)…当n阶台阶,第一步可以跳一阶,剩下的是f(n-1);或者第一步可以跳两节,剩下的是f(n-2);第一步可..._牛客网青蛙跳台阶

随便推点

php 解压安装程序,解压缩各种安装程序包-程序员宅基地

文章浏览阅读97次。解压缩各种安装程序包文:tracky来源:http://bbs.hanzify.org/index.php?showtopic=24638&hl=点击:2578解压缩各种安装程序包1 微软的Installer制作的安装包,后缀一般是msi,mspA 可以用totalcmd 的msiplus插件,可以解压。不可以修改msi。B 可以用WinINSTALL LE 2003,在w..._php软件压缩包安装

ChatGPT-GPT4:提升科研、论文写作与AI绘图效率的新契机_最新chatgpt/gpt4科研技术应用与ai绘图及论文高效写作-程序员宅基地

文章浏览阅读295次。2023年我们进入了AI2.0时代。微软创始人比尔盖茨称ChatGPT的出现有着重大历史意义,不亚于互联网和个人电脑的问世。360创始人周鸿祎认为未来各行各业如果不能搭上这班车,就有可能被淘汰在这个数字化时代,如何能高效地处理文本、文献查阅、PPT编辑、编程、绘图和论文写作已经成为您成功的关键。而 ChatGPT,作为一种强大的自然语言处理模型,具备显著优势,能够帮助您在各个领域取得突破。ChatGPT 在论文写作与编程方面也具备强大的能力。_最新chatgpt/gpt4科研技术应用与ai绘图及论文高效写作

Nginx---静态资源处理_nginx静态资源释放-程序员宅基地

文章浏览阅读2.5k次。NginxNginx服务器基础配置实例Nginx服务操作的问题Nginx配置成系统服务Nginx命令配置到系统环境Nginx静态资源部署Nginx静态资源概述Nginx静态资源的配置指令listen指令default_server说明server_name指令配置方式一:精确匹配配置方式二:使用通配符配置配置三:使用正则表达式配置匹配执行顺序server_name总结location指令设置请求资源的目录root / aliasindex指令error_page指令静态资源优化配置语法sendfile,用来开_nginx静态资源释放

U盘使用TransMac软件格式化之后用不了,已解决!_transmac格式化u盘导致无法读取-程序员宅基地

文章浏览阅读2.9w次,点赞2次,收藏4次。有一天,上网查查Android的知识点(我是初学者),不经意的碰到黑苹果这个概念,因为没用过白苹果,所以有个想折腾的想法,于是从此深入大坑。教程是网上的,是用TransMac格式化的U盘,后面折腾了半天,启动卡在苹果LOGO,生命在于折腾。我不怕。。。。。—___—这个是题外话了。后面因为要用到U盘(不是黑苹果的事了),突然发现U盘用不了了,格式化也不行,用DG也不行(有人说可以),然后网上找..._transmac格式化u盘导致无法读取

毕设问题杂谈_blender怎么解除蒙皮-程序员宅基地

文章浏览阅读3k次。一、maya模型通过mixamo绑定后,发现有模型重叠需要删改,在Maya中删除后导出fbx后总是空集。发现是个fbx导出问题,MAYA做了动画的模型导出FBX,动画好好的,但部分模型没了???【maya吧】_百度贴吧这样操作后会取消蒙皮绑定,于是我去blender里 通过betterfbx插件导入,在编辑模式中删除了多余模型,之后再betterfbx导出,fbx模型绑定都在,进入unity也没问题,应该就是个Mayafbx插件问题。(小白见解)二、..._blender怎么解除蒙皮

基于手机蓝牙的arduino遥控小车_sumjess-程序员宅基地

文章浏览阅读4.1w次。遥控小车是每个人童年的最爱,不仅好奇它的奇妙,更是喜欢它带来的刺激。小编为大家带来几篇博客,来给大家讲讲制作遥控小车的程序。看大标题可知我们一共有五个方法去制作一款带有遥控功能的小车,小编分开来给大家讲解。本文为基于arduino的手机蓝牙遥控小车基于arduino的手机蓝牙遥控小车基于arduino的红外遥控小车基于arduino的无线NRF24L01遥控小车基于ardu..._sumjess