4. 分布式鏈路追蹤客戶端工具包Starter設計

前言

本文將從零搭建分布式鏈路追蹤客戶端工具包的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;}@Overridepublic 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;}@NotNullpublic 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 {@Beanpublic 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 {@Beanpublic RestTemplate restTemplate() {return new RestTemplate();}}

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

@RestController
public class RestTemplateController {@Autowiredprivate 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.pswp.cn/web/13397.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/13397.shtml
英文地址,請注明出處:http://en.pswp.cn/web/13397.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Scala學習2: 控制結構和函數

目錄 第二章 控制結構和函數1- 條件表達式2- 語句終止3- 塊表達式和賦值4- 輸入和輸出5- 循環6- 高級for循環和for推到式7- 函數8- 默認參數和帶名參數9- 可變參數10- 過程11- 懶值12- 異常end 第二章 控制結構和函數 1- 條件表達式 Scala的 if/esle 語法結構與java一樣, 但是…

MySQL表突然卡死,刪、查操作加載不停解決辦法

今天遇到了MySQL刪表的時候卡死情況。然后通過網上查閱資料和項目組溝通&#xff0c;了解到了有多人同時對同一張表進行了操作。我和另一個同事同時進行了刪除操作&#xff0c;然后另兩位同時進行了查詢操作&#xff0c;然后還有一位同事用dolphin調度&#xff0c;用datax采集數…

【SQL】SQL常見面試題總結(4)

目錄 1、空值處理1.1、統計有未完成狀態的試卷的未完成數和未完成率1.2、0 級用戶高難度試卷的平均用時和平均得分 2、高級條件語句2.1、篩選限定昵稱成就值活躍日期的用戶&#xff08;較難&#xff09;2.2、篩選昵稱規則和試卷規則的作答記錄&#xff08;較難&#xff09;2.3、…

SmartEDA助力電工基礎實驗:打造高效、智能的學習新體驗

在電工基礎實驗的教學與學習中&#xff0c;傳統的實驗設備往往存在著操作復雜、數據處理繁瑣等問題&#xff0c;給學生的學習帶來了不小的挑戰。然而&#xff0c;隨著科技的不斷發展&#xff0c;一種名為SmartEDA的智能電工實驗輔助設備正逐漸走入課堂&#xff0c;以其高效、智…

Es6-對象新增了哪些擴展?

?&#x1f308;個人主頁&#xff1a;前端青山 &#x1f525;系列專欄&#xff1a;Javascript篇 &#x1f516;人終將被年少不可得之物困其一生 依舊青山,本期給大家帶來Javascript篇專欄內容:Es6-對象新增了哪些擴展&#xff1f; 目錄 一、參數 二、屬性 函數的length屬性 …

Unsupervised Out-of-Distribution Detection with Diffusion Inpainting

Unsupervised Out-of-Distribution Detection with Diffusion Inpainting 摘要1.介紹2 背景3 3. Lift, Map, Detect摘要 無監督的異常分布檢測(OOD)旨在通過僅從未標記的域內數據中學習來識別域外數據。我們提出了一種用于此任務的新方法——提升、映射、檢測(LMD),該方法…

數據結構-棧(帶圖)

目錄 棧的概念 畫圖理解棧 棧的實現 fun.h fun.c main.c 棧的概念 棧&#xff08;Stack&#xff09;是一種基本的數據結構&#xff0c;其特點是只允許在同一端進行插入和刪除操作&#xff0c;這一端被稱為棧頂。遵循后進先出&#xff08;Last In, First Out, LIFO&#…

瀏覽器下載附件流建議

大文件下載可采用附件流的方式&#xff0c;后端設置一下響應參數&#xff0c;然后以流的方式返回前端 res.set({ "Content-Type": "application/octet-stream", "Content-Disposition": "attachment;filename* UTF-8"fixedEncodeUR…

【論文粗讀|arXiv】GaSpCT: Gaussian Splatting for Novel CT Projection View Synthesis

Abstract 本文提出了一種新穎的視圖合成和3D場景表示方法&#xff0c;用于為計算機斷層掃描&#xff08;CT&#xff09;生成新的投影視圖。 方法采用了Gaussian Splatting 框架&#xff0c;基于有限的2D圖像投影集&#xff0c;無需運動結構&#xff08;SfM&#xff09;方法&am…

CSPM-4是什么?報考條件有哪些?

2021年10月&#xff0c;《國家標準化發展綱要》明確提出構建多層次從業人員培養培訓體系&#xff0c;開展專業人才培養培訓和國家質量基礎設施綜合教育。建立健全人才的職業能力評價和激勵機制。由中國標準化協會&#xff08;CAS&#xff09;組織開展的項目管理專業人員能力評價…

Swift 5.9 中 if 與 switch 語句簡潔新語法讓擼碼更帶勁

概覽 在實際代碼開發中&#xff0c;可能初學 Swift 語言的小伙伴們在擼碼時最常用的得數 if 和 switch…case 條件選擇語句了。不過在某些場景下它們顯得略有那么一丟丟“矯揉造作”&#xff0c;還好從 Swift 5.9 開始蘋果知趣的為其簡化了語法且增強了它們的表現力。 在本篇…

Vitis HLS 學習筆記--優化本地存儲器訪問瓶頸

目錄 1. 簡介 2. 代碼解析 2.1 原始代碼 2.2 優化后 2.3 分析優化措施 3. 總結 1. 簡介 在Vitis HLS中&#xff0c;實現II&#xff08;迭代間隔&#xff09; 1是提高循環執行效率的關鍵。II1意味著每個時鐘周期都可以開始一個新的迭代&#xff0c;這是最理想的情況&…

Java實現音頻轉文本(語音識別)

在Java中實現音頻轉文本&#xff08;也稱為語音識別或ASR&#xff09;通常涉及使用專門的語音識別服務&#xff0c;如Google Cloud Speech-to-Text、IBM Watson Speech to Text、Amazon Transcribe、Microsoft Azure Speech Services&#xff0c;或者一些開源庫如CMU Sphinx。 …

2024年第四屆長三角高校數學建模競賽C題思路

賽道C:汽后配件需求預測問題 在汽后行業的供應鏈管理中, 精準的需求預測是后續管理及決策的基礎。 各個汽后配件即為一個庫存單位(SKU, Stock Keeping Unit), 如果可以準確預知未來對于各個配件的市場需求, 就可以提前將庫存放在靠近需求的倉庫中, 從而降低庫存成本,…

HNCTF ——baby_python

H&NCTF 2024 官方WP (qq.com) OpCodes Pickle.jl (juliahub.com) nc之后 PS D:\ForCode\pythoncode\.idea> nc hnctf.yuanshen.life 33267 # Python 3.10.12 from pickle import loads main b"\x80\x04ctypes\nFunctionType\n(ctypes\nCodeType\n(I1\nI0\nI0\n…

[Linux] 常用服務器命令(持續更新)

文件操作 # 顯示文件系統的磁盤空間使用情況 df -h全局查找文件 find / -type f -iname "java"find / -name libncurses*拷貝整個文件夾 cp -r /home/a/ /home/b/ 解壓&#xff0c;撤銷解壓 撤銷zip解壓 zipinfo -1 path/xx.zip | xargs rm -rf 撤銷tar解壓 tar …

【Vim】

一、什么是Vim&#xff1f; Vim 是一個歷史悠久的文本編輯器&#xff0c;可以追溯到 qed。 Bram Moolenaar 于 1991 年發布初始版本。Vim 有著悠久的歷史;它起源于 Vi 編輯器&#xff08;1976 年&#xff09;&#xff0c;至今仍在開發中。(Vim has a rich history; it origina…

css+html 愛心?

效果 代碼實現 html <div class"main"><div class"aixin"></div></div>css .main {transform: rotate(-45deg);}.aixin {height: 100px;width: 100px;background-color: red;margin: auto;margin-top: 200px;position: relativ…

MySQL第一次作業(基本操作)

目錄 一、登陸數據庫 二、創建數據庫zoo 三、修改數據庫zoo字符集為gbk 四、選擇當前數據庫為zoo 五、查看創建數據庫zoo信息 六、刪除數據庫zoo 一、登陸數據庫 指令&#xff1a; mysql -u root -p 二、創建數據庫zoo 指令&#xff1a; create database zoo; 三、修改數…

基于PHP+MySQL組合開發的多用戶自定義商城系統源碼 附帶源代碼包以及搭建教程

系統概述 互聯網技術的飛速發展&#xff0c;電子商務已成為人們日常生活中不可或缺的一部分。商城系統作為電子商務的核心&#xff0c;其開發技術和用戶體驗直接影響著電商平臺的競爭力和用戶滿意度。本文旨在介紹一個基于PHPMySQL組合開發的多用戶自定義商城系統&#xff0c;…