4. 分布式链路追踪客户端工具包Starter设计

news2024/11/28 10:39:55

前言

本文将从零搭建分布式链路追踪客户端工具包的Starter,并将在后续文章中逐步丰富支持的场景。这里首先将搭建一个最基础的Starter,能提供的功能和1. 看完这篇文章我奶奶都懂Opentracing了一文中的示例demo类似。

相关版本依赖如下。

opentracing-api版本:0.33.0
opentracing-spring-web版本:4.1.0
jaeger-client版本:1.8.1
Springboot版本:2.7.6

github地址:honey-tracing

正文

一. 基础Starter实现

在基础Starter中,主要是提供Servlet过滤器RestTemplate拦截器,我们后续的复杂功能,就将在这个基础Starter上一点一点的丰富。

首先下图是Starter的工程结构。

在基础Starter中,Servlet的链路过滤器实现如下。

public class HoneyTracingFilter implements Filter {

    private final Tracer tracer;

    public HoneyTracingFilter(Tracer tracer) {
        this.tracer = tracer;
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
            throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;

        SpanContext extractedSpanContext = tracer.extract(Format.Builtin.HTTP_HEADERS,
                new HttpServletRequestExtractAdapter(request));

        Span span = tracer.buildSpan(request.getMethod())
                .asChildOf(extractedSpanContext)
                .withTag(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_SERVER)
                .start();

        try (Scope scope = tracer.activateSpan(span)) {
            filterChain.doFilter(servletRequest, servletResponse);
        } catch (IOException | ServletException e) {
            Tags.ERROR.set(span, Boolean.TRUE);
            throw e;
        } finally {
            span.finish();
        }
    }

}

RestTemplate的链路拦截器实现如下。


 * RestTemplate客户端的分布式链路追踪拦截器。
 */
public class HoneyRestTemplateTracingInterceptor implements ClientHttpRequestInterceptor {

    private final Tracer tracer;

    public HoneyRestTemplateTracingInterceptor(Tracer tracer) {
        this.tracer = tracer;
    }

    @NotNull
    public ClientHttpResponse intercept(@NotNull HttpRequest request, @NotNull byte[] body,
                                        ClientHttpRequestExecution execution) throws IOException {
        Span span = tracer.buildSpan(HONEY_REST_TEMPLATE_NAME)
                .withTag(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_CLIENT)
                .start();
        tracer.inject(span.context(), Format.Builtin.HTTP_HEADERS, new HttpHeadersCarrier(request.getHeaders()));

        try (Scope scope = tracer.activateSpan(span)) {
            return execution.execute(request, body);
        } catch (IOException e) {
            Tags.ERROR.set(span, Boolean.TRUE);
            throw e;
        } finally {
            span.finish();
        }
    }

}

打印链路日志的HoneySpanReporter目前不打印任何日志,后面再添加打印逻辑,实现如下。

public class HoneySpanReporter implements Reporter {

    public void report(JaegerSpan span) {
        
        
    }

    public void close() {

    }

}

我们使用HoneyTracingProperties来读取链路相关的配置,目前仅读取一个开关enabled,如下所示。


 * 分布式链路追踪配置属性类。
 */
@ConfigurationProperties("honey.tracing")
public class HoneyTracingProperties {

    private boolean enabled;

    public boolean isEnabled() {
        return enabled;
    }

    public void setEnabled(boolean enabled) {
        this.enabled = enabled;
    }

}

使用到的一些常量,存放在CommonConstants中,如下所示。

public class CommonConstants {

    public static final double DEFAULT_SAMPLE_RATE = 1.0;

    public static final String HONEY_TRACER_NAME = "HoneyTracer";
    public static final String HONEY_REST_TEMPLATE_NAME = "HoneyRestTemplate";

    public static final String ALL_URL_PATTERN_STR = "/*";

}

再接下来就是三个自动装配类,其中HoneyRestTemplateTracingConfig负责注册HoneyRestTemplateTracingInterceptor给容器中所有的RestTemplateHoneyTracingConfig负责注册TracerSpring容器,HoneyTracingFilterConfig负责注册HoneyTracingFilter,实现如下所示。


 * RestTemplate分布式链路追踪配置类。
 */
@ConditionalOnBean(RestTemplate.class)
@Configuration
@AutoConfigureAfter(HoneyTracingConfig.class)
public class HoneyRestTemplateTracingConfig {

    public HoneyRestTemplateTracingConfig(List<RestTemplate> restTemplates, Tracer tracer) {
        for (RestTemplate restTemplate : restTemplates) {
            
            restTemplate.getInterceptors().add(new HoneyRestTemplateTracingInterceptor(tracer));
        }
    }

}


 * 分布式链路追踪配置类。
 */
@Configuration
@EnableConfigurationProperties({HoneyTracingProperties.class})
@ConditionalOnProperty(prefix = "honey.tracing", name = "enabled", havingValue = "true", matchIfMissing = true)
public class HoneyTracingConfig {

    @Bean
    @ConditionalOnMissingBean(Sampler.class)
    public Sampler sampler() {
        return new ProbabilisticSampler(DEFAULT_SAMPLE_RATE);
    }

    @Bean
    @ConditionalOnMissingBean(Reporter.class)
    public Reporter reporter() {
        return new HoneySpanReporter();
    }

    @Bean
    @ConditionalOnMissingBean(Tracer.class)
    public Tracer tracer(Sampler sampler, Reporter reporter) {
        return new JaegerTracer.Builder(HONEY_TRACER_NAME)
                .withTraceId128Bit()
                .withZipkinSharedRpcSpan()
                .withSampler(sampler)
                .withReporter(reporter)
                .build();
    }

}


 * Servlet过滤器配置类。
 */
@Configuration
@AutoConfigureAfter(HoneyTracingConfig.class)
public class HoneyTracingFilterConfig {

    @Bean
    public FilterRegistrationBean<HoneyTracingFilter> honeyTracingFilter(Tracer tracer) {
        HoneyTracingFilter honeyTracingFilter = new HoneyTracingFilter(tracer);
        FilterRegistrationBean<HoneyTracingFilter> filterFilterRegistrationBean
                = new FilterRegistrationBean<>(honeyTracingFilter);
        filterFilterRegistrationBean.addUrlPatterns(ALL_URL_PATTERN_STR);
        return filterFilterRegistrationBean;
    }

}

最后就是spring.factoriespom文件,内容如下所示。

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
 com.honey.tracing.config.HoneyTracingConfig,\
 com.honey.tracing.config.HoneyTracingFilterConfig,\
 com.honey.tracing.config.HoneyRestTemplateTracingConfig

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>honey-tracing</artifactId>
        <groupId>com.honey</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>honey-starter-tracing</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
        </dependency>
        <dependency>
            <groupId>io.opentracing</groupId>
            <artifactId>opentracing-api</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>io.opentracing.contrib</groupId>
            <artifactId>opentracing-spring-web</artifactId>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>io.jaegertracing</groupId>
            <artifactId>jaeger-client</artifactId>
            <scope>provided</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-source-plugin</artifactId>
                <executions>
                    <execution>
                        <id>attach-sources</id>
                        <goals>
                            <goal>jar</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

还有一点要补充,父工程的pom文件如下所示。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <packaging>pom</packaging>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.6</version>
    </parent>

    <groupId>com.honey</groupId>
    <artifactId>honey-tracing</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>io.opentracing</groupId>
                <artifactId>opentracing-api</artifactId>
                <version>0.33.0</version>
            </dependency>
            <dependency>
                <groupId>io.opentracing.contrib</groupId>
                <artifactId>opentracing-spring-web</artifactId>
                <version>4.1.0</version>
            </dependency>

            <dependency>
                <groupId>io.jaegertracing</groupId>
                <artifactId>jaeger-client</artifactId>
                <version>1.8.1</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <modules>
        <module>honey-starter-tracing</module>
        <module>honey-tracing-example</module>
    </modules>

</project>

二. 测试demo搭建

我们需要一个demo来测试我们的基础Starter,并且随着后续Starter支持的功能的增多,我们的demo也要相应的扩展更多的场景。

首先是demo的目录结构,如下所示。

1. example-service-1

RestTemplateConfig简单的向Spring容器注册了一个RestTemplatebean,如下所示。

@Configuration
public class RestTemplateConfig {

    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

}

RestTemplateController提供了发送接口,如下所示。

@RestController
public class RestTemplateController {

    @Autowired
    private RestTemplate restTemplate;

    @GetMapping("/send")
    public void send(String url) {
        restTemplate.getForEntity(url, Void.class);
    }

}

最后是application.ymlpom文件,如下所示。

server:
  port: 8080

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>honey-tracing-example</artifactId>
        <groupId>com.honey</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>example-service-1</artifactId>

    <dependencies>
        <dependency>
            <groupId>com.honey</groupId>
            <artifactId>honey-starter-tracing</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

        <dependency>
            <groupId>io.opentracing</groupId>
            <artifactId>opentracing-api</artifactId>
            <version>0.33.0</version>
        </dependency>
        <dependency>
            <groupId>io.opentracing.contrib</groupId>
            <artifactId>opentracing-spring-web</artifactId>
            <version>4.1.0</version>
        </dependency>

        <dependency>
            <groupId>io.jaegertracing</groupId>
            <artifactId>jaeger-client</artifactId>
            <version>1.8.1</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>

</project>

2. example-service-2

RestTemplateController提供了接收接口,如下所示。

@RestController
public class RestTemplateController {

    @GetMapping("/receive")
    public void receive() {
        System.out.println();
    }

}

最后是application.ymlpom文件,如下所示。

server:
  port: 8081

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>honey-tracing-example</artifactId>
        <groupId>com.honey</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>example-service-2</artifactId>

    <dependencies>
        <dependency>
            <groupId>com.honey</groupId>
            <artifactId>honey-starter-tracing</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

        <dependency>
            <groupId>io.opentracing</groupId>
            <artifactId>opentracing-api</artifactId>
            <version>0.33.0</version>
        </dependency>
        <dependency>
            <groupId>io.opentracing.contrib</groupId>
            <artifactId>opentracing-spring-web</artifactId>
            <version>4.1.0</version>
        </dependency>

        <dependency>
            <groupId>io.jaegertracing</groupId>
            <artifactId>jaeger-client</artifactId>
            <version>1.8.1</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>

</project>

总结

在本文,首先实现了一个基础的Starter包,为分布式链路追踪提供了Servlet过滤器和RestTemplate拦截器,其次实现了一个demo,后续分布式链路追踪Starter的功能,将用该demo完成测试。
原文:https://juejin.cn/post/7337216565097562149

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

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

相关文章

三、四线城市也能开店做真人手办定制?会不会亏?

时下&#xff0c;真人手办定制项目加盟热&#xff0c;消费端需求伴随网络效应指数心增加&#xff0c;作为真人手办定制底层技术供应商&#xff0c;博雅仔在与一些创业中的伙伴的沟通过程中了解到&#xff0c;位于一、二线城市的伙伴朋友很有信心&#xff0c;他们坦言&#xff0…

教你免费通配符/泛域名SSL证书怎么申请

申请免费的通配符SSL证书可以让您的主域名及其所有二级子域名都受到安全套接层(SSL)的加密保护&#xff0c;提高网站的整体安全性和用户信任度。以下是一个基于通用流程的简明教程&#xff0c;以JoySSL为例&#xff0c;因为他提供全类别的免费SSL证书。 1、创建证书服务商账号…

STM32自制雾化器

1.1 介绍&#xff1a; 108KHZ雾化器&#xff0c;由驱动模块和雾化器组成&#xff0c;主要作用是把水雾化加湿&#xff1b;它的使用方法有两种&#xff1b;方式1.电源接口供电DC3-4.5V&#xff0c;按下按键&#xff0c;开启雾化器,再按住关&#xff1b;方式2.单片机控制低电平2…

Linux实验 系统管理(二)

实验目的&#xff1a; 了解RPM软件包&#xff1b;掌握使用rpm命令查询、安装、更新、卸载、验证软件包的方法&#xff1b;掌握使用yum命令查询、安装、更新、卸载软件包的方法&#xff1b;了解TAR软件包&#xff1b;掌握使用tar命令创建&#xff08;并压缩&#xff09;、查询、…

SSM校园疫情防控系统JAVA计算机毕业设计项目【附源码】

SSM校园疫情防控系统JAVA计算机毕业设计项目 &#x1f345; 作者主页 网顺技术团队 &#x1f345; 欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; &#x1f345; 文末获取源码联系方式 &#x1f4dd; &#x1f345; 查看下方微信号获取联系方式 承接各种定制系统 &#x1…

python+cv2+gstreamer 推流<500ms低延迟的处理策略

1.一份可用的推流配置 self.out cv2.VideoWriter(appsrc is-liveTrue stream-type0 emit-signalsFalse max-latency1 \ ! videoconvert ! video/x-raw, formatI420 \ ! x264enc speed-presetultrafast bitrate1200 tune"zerolatency" key-int-m…

吉林事业编报名照要求<50kb怎么压缩

吉林事业编报名照要求&#xff1c;50kb怎么压缩

美港通正规股票炒股市场超100亿元!北上资金爆买A股!

查查配今日早盘,A股震荡上扬,上证指数再创年内新高,创业板指、科创50、沪深300等指数均涨超1%。 盘面上,新能源产业全线走强,锂电池、光伏、高压快充、储能等板块涨幅居前,ST、公共交通、通信设备、酿酒等板块小幅调整。 美港通证券以其专业的服务和较低的管理费用在市场中受…

2024年想要开一家抖音小店,需要多少钱?一篇详解!

大家好&#xff0c;我是电商糖果 随着抖音卖货的持续火爆&#xff0c;抖音小店也成了电商行业讨论度最大的项目之一。 不少朋友都想知道&#xff0c;如果今年开抖音小店大概需要多少钱。 糖果做小店的时间也比较长&#xff0c;也经营了多家小店。 对于开一家抖音小店需要多…

【深度学习】【Lora训练0】StabelDiffusion,Lora训练,kohya_ss训练

文章目录 环境数据自动标注kohya_ss BLIP2kohya_ss WD14 后续 资源&#xff1a; &#xff08;1&#xff09;训练ui kohya_ss&#xff1a; https://github.com/bmaltais/kohya_ss &#xff08;2&#xff09;kohya_ss 的docker 其他docker https://github.com/ashleykleynhans…

书生第三课作业

视频&#xff1a;https://www.bilibili.com/video/BV1QA4m1F7t4/ 教程&#xff1a;https://github.com/InternLM/Tutorial/blob/camp2/huixiangdou/readme.md 作业&#xff1a;https://github.com/InternLM/Tutorial/blob/camp2/huixiangdou/homework.md 项目地址&#xff1a;h…

基于Opencv的车牌识别系统(毕业设计可用)

系统架构 图像采集&#xff1a;首先&#xff0c;通过摄像头等设备捕捉车辆图像。图像质量直接影响后续处理的准确性&#xff0c;因此高质量的图像采集是基础。 预处理&#xff1a;对获取的原始图像进行预处理&#xff0c;包括灰度化、降噪、对比度增强和边缘检测等。这些操作旨…

什么是内存泄漏?什么是内存溢出?

我们讲内存溢出时&#xff0c;首先看一下上面这张图&#xff0c;比如说你要往一个500ml的杯子里倒800ml的水&#xff0c;这样肯定是装不下的&#xff0c;水会溢出来&#xff0c;在我们电脑内存中也是一样的&#xff0c;你这个内存中就只有5M的内存空间&#xff0c;可是你要将8M…

如何编辑百度百科并提供参考资料

大家都知道参考资料是创建百度百科中最重要的一步&#xff0c;百度百科只收录可以找到资料来源的事实&#xff0c;参考资料的意义在于&#xff0c;指出该部分内容的来源/出处&#xff0c;从而保障这段内容是客观真实的。 注册和登录百度账号 首先&#xff0c;你需要在百度百科…

腿式移动机器人

腿式运动以一系列机器人和地面之间的点接触为特征。其主要优点包括在粗糙地形上的自适应性和机动性。 因为只需要一组点接触,所以只要机器人能够保持适当的地面步距,这些点之间的地面质量是无关紧要的。另外,只要行走机器人的步距大于洞穴的宽度&#xff0c;它就能跨越洞穴或者…

软件工程复习之软件定义时期

1.什么是软件&#xff1f; 答&#xff1a;软件是程序&#xff0c;数据和文档的集合。 程序是完成指定功能的计算机可执行的指令序列。 数据是程序进行信息处理的数据结构。 文档是开发&#xff0c;使用&#xff0c;维护的图文资料。 2.软件有何特点&#xff1f; 答&#…

Python远程连接Linux执行操作

一、任务要求 要使用Python编写代码来远程给Linux主机上传一个文件&#xff0c;可以使用paramiko库&#xff0c;这是一个实现了SSHv2协议的Python库&#xff0c;它支持SSH连接&#xff08;包括客户端和服务端&#xff09;&#xff0c;并且提供SFTP&#xff08;SSH File Transf…

无线充电宝哪个比较好?哪些充电宝牌子比较值得入手?充电宝排名

在智能科技飞速发展的当下&#xff0c;智能手机已成为我们生活中不可或缺的一部分。然而&#xff0c;手机电量的限制却时常让我们陷入窘境&#xff0c;担心错过重要信息或无法完成关键操作。为了应对这一挑战&#xff0c;充电宝应运而生&#xff0c;成为了我们出行的得力助手。…

PSoc™62开发板之IoT应用

实验目的 使用PSoc62™开发板驱动OLED模块&#xff0c;实时监控室内的光照强度、温度信息 实验准备 PSoc62™开发板SSD1309 OLED模块DS18B20温度传感器BH1750光照传感器 模块电路 SSD1309 OLED模块的电路连接和模块配置教程请参考之前的文章&#xff0c;这里不详细展开描…

通配符证书是什么意思?使用起来有什么优势?

通配符证书就像是一个万能钥匙&#xff0c;但它专门用于网站的安全。当你运营一个网站时&#xff0c;特别是有很多子网站&#xff0c;每个都需要安全连接&#xff08;比如开头是https的网址&#xff09;&#xff0c;通常你需要为每个子网站买一个证书来保证访问者的安全。但是&…