這篇文章主要介紹了Spring Cloud Sleuth Span的示例分析,具有一定借鑒價(jià)值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。
創(chuàng)新互聯(lián)建站自2013年創(chuàng)立以來(lái),是專業(yè)互聯(lián)網(wǎng)技術(shù)服務(wù)公司,擁有項(xiàng)目網(wǎng)站制作、成都做網(wǎng)站網(wǎng)站策劃,項(xiàng)目實(shí)施與項(xiàng)目整合能力。我們以讓每一個(gè)夢(mèng)想脫穎而出為使命,1280元海滄做網(wǎng)站,已為上家服務(wù),為海滄各地企業(yè)和個(gè)人服務(wù),聯(lián)系電話:13518219792
感謝SpanInjector和SpanExtractor,您可以自定義spans的創(chuàng)建和傳播方式。
目前有兩種在進(jìn)程之間傳遞跟蹤信息的內(nèi)置方式:
通過(guò)Spring Integration
通過(guò)HTTP
Span ids從Zipkin兼容(B3)頭(Message或HTTP頭)中提取,以啟動(dòng)或加入現(xiàn)有跟蹤。跟蹤信息被注入到任何出站請(qǐng)求中,所以下一跳可以提取它們。
與以前版本的Sleuth相比,重要的變化是Sleuth正在實(shí)施Open Tracing的TextMap概念。在Sleuth,它被稱為SpanTextMap?;旧线@個(gè)想法是通過(guò)SpanTextMap可以抽象出任何通信手段(例如消息,http請(qǐng)求等)。這個(gè)抽象定義了如何將數(shù)據(jù)插入到載體中以及如何從那里檢索數(shù)據(jù)。感謝這樣,如果您想要使用一個(gè)使用FooRequest作為發(fā)送HTTP請(qǐng)求的平均值的新HTTP庫(kù),那么您必須創(chuàng)建一個(gè)SpanTextMap的實(shí)現(xiàn),它將調(diào)用委托給FooRequest檢索和插入HTTP標(biāo)頭。
對(duì)于Spring Integration,有2個(gè)接口負(fù)責(zé)從Message創(chuàng)建Span。這些是:
MessagingSpanTextMapExtractor
MessagingSpanTextMapInjector
您可以通過(guò)提供自己的實(shí)現(xiàn)來(lái)覆蓋它們。
對(duì)于HTTP,有2個(gè)接口負(fù)責(zé)從Message創(chuàng)建Span。這些是:
HttpSpanExtractor
HttpSpanInjector
您可以通過(guò)提供自己的實(shí)現(xiàn)來(lái)覆蓋它們。
我們假設(shè),而不是標(biāo)準(zhǔn)的Zipkin兼容的跟蹤HTTP頭名稱
for trace id - correlationId
for span id - mySpanId
這是SpanExtractor的一個(gè)例子
static class CustomHttpSpanExtractor implements HttpSpanExtractor { @Override public Span joinTrace(SpanTextMap carrier) { Map<String, String> map = TextMapUtil.asMap(carrier); long traceId = Span.hexToId(map.get("correlationid")); long spanId = Span.hexToId(map.get("myspanid")); // extract all necessary headers Span.SpanBuilder builder = Span.builder().traceId(traceId).spanId(spanId); // build rest of the Span return builder.build(); } } static class CustomHttpSpanInjector implements HttpSpanInjector { @Override public void inject(Span span, SpanTextMap carrier) { carrier.put("correlationId", span.traceIdString()); carrier.put("mySpanId", Span.idToHex(span.getSpanId())); } }
14
15
16
17
18
19
20
21
你可以這樣注冊(cè):
@Bean HttpSpanInjector customHttpSpanInjector() { return new CustomHttpSpanInjector(); } @Bean HttpSpanExtractor customHttpSpanExtractor() { return new CustomHttpSpanExtractor(); }
Spring Cloud為了安全起見,Sleuth不會(huì)將跟蹤/跨度相關(guān)的標(biāo)頭添加到Http響應(yīng)。如果您需要標(biāo)題,那么將標(biāo)題注入Http響應(yīng)的自定義SpanInjector,并且可以使用以下方式添加一個(gè)使用此標(biāo)簽的Servlet過(guò)濾器:
static class CustomHttpServletResponseSpanInjector extends ZipkinHttpSpanInjector { @Override public void inject(Span span, SpanTextMap carrier) { super.inject(span, carrier); carrier.put(Span.TRACE_ID_NAME, span.traceIdString()); carrier.put(Span.SPAN_ID_NAME, Span.idToHex(span.getSpanId())); } } static class HttpResponseInjectingTraceFilter extends GenericFilterBean { private final Tracer tracer; private final HttpSpanInjector spanInjector; public HttpResponseInjectingTraceFilter(Tracer tracer, HttpSpanInjector spanInjector) { this.tracer = tracer; this.spanInjector = spanInjector; } @Override public void doFilter(ServletRequest request, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { HttpServletResponse response = (HttpServletResponse) servletResponse; Span currentSpan = this.tracer.getCurrentSpan(); this.spanInjector.inject(currentSpan, new HttpServletResponseTextMap(response)); filterChain.doFilter(request, response); } class HttpServletResponseTextMap implements SpanTextMap { private final HttpServletResponse delegate; HttpServletResponseTextMap(HttpServletResponse delegate) { this.delegate = delegate; } @Override public Iterator<Map.Entry<String, String>> iterator() { Map<String, String> map = new HashMap<>(); for (String header : this.delegate.getHeaderNames()) { map.put(header, this.delegate.getHeader(header)); } return map.entrySet().iterator(); } @Override public void put(String key, String value) { this.delegate.addHeader(key, value); } } }
你可以這樣注冊(cè):
@Bean HttpSpanInjector customHttpServletResponseSpanInjector() { return new CustomHttpServletResponseSpanInjector(); } @Bean HttpResponseInjectingTraceFilter responseInjectingTraceFilter(Tracer tracer) { return new HttpResponseInjectingTraceFilter(tracer, customHttpServletResponseSpanInjector()); }
有時(shí)你想創(chuàng)建一個(gè)手動(dòng)Span,將一個(gè)電話包裹到一個(gè)沒有被檢測(cè)的外部服務(wù)。您可以做的是創(chuàng)建一個(gè)帶有peer.service標(biāo)簽的跨度,其中包含要調(diào)用的服務(wù)的值。下面你可以看到一個(gè)調(diào)用redis的例子,它被包裝在這樣一個(gè)跨度里。
org.springframework.cloud.sleuth.Span newSpan = tracer.createSpan("redis"); try { newSpan.tag("redis.op", "get"); newSpan.tag("lc", "redis"); newSpan.logEvent(org.springframework.cloud.sleuth.Span.CLIENT_SEND); // call redis service e.g // return (SomeObj) redisTemplate.opsForHash().get("MYHASH", someObjKey); } finally { newSpan.tag("peer.service", "redisService"); newSpan.tag("peer.ipv4", "1.2.3.4"); newSpan.tag("peer.port", "1234"); newSpan.logEvent(org.springframework.cloud.sleuth.Span.CLIENT_RECV); tracer.close(newSpan); }
重要 | 記住不要添加peer.service標(biāo)簽和SA標(biāo)簽!您只需添加peer.service。 |
---|
默認(rèn)情況下,Sleuth假設(shè)當(dāng)您將跨度發(fā)送到Zipkin時(shí),您希望跨度的服務(wù)名稱等于spring.application.name值。這并不總是這樣。在某些情況下,您希望為您應(yīng)用程序中的所有spans提供不同的服務(wù)名稱。要實(shí)現(xiàn)這一點(diǎn),只需將以下屬性傳遞給應(yīng)用程序即可覆蓋該值(foo服務(wù)名稱的示例):
spring.zipkin.service.name: foo
1
為了定義與特定跨度對(duì)應(yīng)的主機(jī),我們需要解析主機(jī)名和端口。默認(rèn)方法是從服務(wù)器屬性中獲取它。如果由于某些原因沒有設(shè)置,那么我們正在嘗試從網(wǎng)絡(luò)接口檢索主機(jī)名。
如果您啟用了發(fā)現(xiàn)客戶端,并且更愿意從服務(wù)注冊(cè)表中注冊(cè)的實(shí)例檢索主機(jī)地址,那么您必須設(shè)置屬性(適用于基于HTTP和Stream的跨度報(bào)告)。
spring.zipkin.locator.discovery.enabled: true
1
您可以通過(guò)將spring-cloud-sleuth-stream jar作為依賴關(guān)系來(lái)累加并發(fā)送跨越Spring Cloud Stream的數(shù)據(jù),并為RabbitMQ或spring-cloud-starter-stream-kafka添加通道Binder實(shí)現(xiàn)(例如spring-cloud-starter-stream-rabbit)為Kafka)。通過(guò)將spring-cloud-sleuth-stream jar作為依賴關(guān)系,并添加RabbitMQ或spring-cloud-starter-stream-kafka的Binder通道spring-cloud-starter-stream-rabbit來(lái)實(shí)現(xiàn){ 22 /} Stream的累積和發(fā)送范圍數(shù)據(jù)。
Kafka)。這將自動(dòng)將您的應(yīng)用程序轉(zhuǎn)換為有效載荷類型為Spans的郵件的制作者。
有一個(gè)特殊的便利注釋,用于為Span數(shù)據(jù)設(shè)置消息使用者,并將其推入Zipkin SpanStore。這個(gè)應(yīng)用程序
@SpringBootApplication @EnableZipkinStreamServer public class Consumer { public static void main(String[] args) { SpringApplication.run(Consumer.class, args); } }
將通過(guò)Spring Cloud StreamBinder(例如RabbitMQ包含spring-cloud-starter-stream-rabbit)來(lái)收聽您提供的任何運(yùn)輸?shù)腟pan數(shù)據(jù),Redis和Kafka的類似起始者) 。如果添加以下UI依賴關(guān)系
<groupId>io.zipkin.java</groupId> <artifactId>zipkin-autoconfigure-ui</artifactId>
1
2
然后,您將有一個(gè)Zipkin服務(wù)器,您的應(yīng)用程序在端口9411上承載UI和API。
默認(rèn)SpanStore是內(nèi)存中的(適合演示,快速入門)。對(duì)于更強(qiáng)大的解決方案,您可以將MySQL和spring-boot-starter-jdbc添加到類路徑中,并通過(guò)配置啟用JDBC SpanStore,例如:
spring: rabbitmq: host: ${RABBIT_HOST:localhost} datasource: schema: classpath:/mysql.sql url: jdbc:mysql://${MYSQL_HOST:localhost}/test username: root password: root # Switch this on to create the schema on startup: initialize: true continueOnError: true sleuth: enabled: false zipkin: storage: type: mysql
注意 | @EnableZipkinStreamServer還用@EnableZipkinServer注釋,因此該過(guò)程還將公開標(biāo)準(zhǔn)的Zipkin服務(wù)器端點(diǎn),以通過(guò)HTTP收集spans,并在Zipkin Web UI中進(jìn)行查詢。 |
---|
也可以使用spring-cloud-sleuth-stream并綁定到SleuthSink來(lái)輕松實(shí)現(xiàn)自定義消費(fèi)者。例:
@EnableBinding(SleuthSink.class) @SpringBootApplication(exclude = SleuthStreamAutoConfiguration.class) @MessageEndpoint public class Consumer { @ServiceActivator(inputChannel = SleuthSink.INPUT) public void sink(Spans input) throws Exception { // ... process spans } }
注意 | 上面的示例消費(fèi)者應(yīng)用程序明確排除SleuthStreamAutoConfiguration,因此它不會(huì)向其自己發(fā)送消息,但這是可選的(您可能實(shí)際上想要將消息跟蹤到消費(fèi)者應(yīng)用程序中)。 |
---|
為了自定義輪詢機(jī)制,您可以創(chuàng)建名稱等于StreamSpanReporter.POLLER的PollerMetadata類型的bean。在這里可以找到這樣一個(gè)配置的例子。
@Configuration public static class CustomPollerConfiguration { @Bean(name = StreamSpanReporter.POLLER) PollerMetadata customPoller() { PollerMetadata poller = new PollerMetadata(); poller.setMaxMessagesPerPoll(500); poller.setTrigger(new PeriodicTrigger(5000L)); return poller; } }
目前Spring Cloud Sleuth注冊(cè)了與spans相關(guān)的簡(jiǎn)單指標(biāo)。它使用Spring Boot的指標(biāo)支持
來(lái)計(jì)算接受和刪除的數(shù)量spans。每次發(fā)送到Zipkin時(shí),接受的spans的數(shù)量將增加。如果出現(xiàn)錯(cuò)誤,那么刪除的數(shù)字spans將會(huì)增加。
感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享的“Spring Cloud Sleuth Span的示例分析”這篇文章對(duì)大家有幫助,同時(shí)也希望大家多多支持創(chuàng)新互聯(lián),關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,更多相關(guān)知識(shí)等著你來(lái)學(xué)習(xí)!
網(wǎng)站標(biāo)題:SpringCloudSleuthSpan的示例分析
網(wǎng)站URL:http://jinyejixie.com/article24/gpscje.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供搜索引擎優(yōu)化、動(dòng)態(tài)網(wǎng)站、電子商務(wù)、微信小程序、面包屑導(dǎo)航、ChatGPT
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)