這篇文章主要介紹了Spring Cloud Sleuth Span的示例分析,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

創(chuàng)新互聯(lián)建站自2013年創(chuàng)立以來,是專業(yè)互聯(lián)網(wǎng)技術服務公司,擁有項目網(wǎng)站制作、成都做網(wǎng)站網(wǎng)站策劃,項目實施與項目整合能力。我們以讓每一個夢想脫穎而出為使命,1280元海滄做網(wǎng)站,已為上家服務,為海滄各地企業(yè)和個人服務,聯(lián)系電話:13518219792
感謝SpanInjector和SpanExtractor,您可以自定義spans的創(chuàng)建和傳播方式。
目前有兩種在進程之間傳遞跟蹤信息的內(nèi)置方式:
通過Spring Integration
通過HTTP
Span ids從Zipkin兼容(B3)頭(Message或HTTP頭)中提取,以啟動或加入現(xiàn)有跟蹤。跟蹤信息被注入到任何出站請求中,所以下一跳可以提取它們。
與以前版本的Sleuth相比,重要的變化是Sleuth正在實施Open Tracing的TextMap概念。在Sleuth,它被稱為SpanTextMap。基本上這個想法是通過SpanTextMap可以抽象出任何通信手段(例如消息,http請求等)。這個抽象定義了如何將數(shù)據(jù)插入到載體中以及如何從那里檢索數(shù)據(jù)。感謝這樣,如果您想要使用一個使用FooRequest作為發(fā)送HTTP請求的平均值的新HTTP庫,那么您必須創(chuàng)建一個SpanTextMap的實現(xiàn),它將調(diào)用委托給FooRequest檢索和插入HTTP標頭。
對于Spring Integration,有2個接口負責從Message創(chuàng)建Span。這些是:
MessagingSpanTextMapExtractor
MessagingSpanTextMapInjector
您可以通過提供自己的實現(xiàn)來覆蓋它們。
對于HTTP,有2個接口負責從Message創(chuàng)建Span。這些是:
HttpSpanExtractor
HttpSpanInjector
您可以通過提供自己的實現(xiàn)來覆蓋它們。
我們假設,而不是標準的Zipkin兼容的跟蹤HTTP頭名稱
for trace id - correlationId
for span id - mySpanId
這是SpanExtractor的一個例子
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
你可以這樣注冊:
@Bean
HttpSpanInjector customHttpSpanInjector() {
return new CustomHttpSpanInjector();
}
@Bean
HttpSpanExtractor customHttpSpanExtractor() {
return new CustomHttpSpanExtractor();
}
Spring Cloud為了安全起見,Sleuth不會將跟蹤/跨度相關的標頭添加到Http響應。如果您需要標題,那么將標題注入Http響應的自定義SpanInjector,并且可以使用以下方式添加一個使用此標簽的Servlet過濾器:
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);
}
}
}
你可以這樣注冊:
@Bean HttpSpanInjector customHttpServletResponseSpanInjector() {
return new CustomHttpServletResponseSpanInjector();
}
@Bean
HttpResponseInjectingTraceFilter responseInjectingTraceFilter(Tracer tracer) {
return new HttpResponseInjectingTraceFilter(tracer, customHttpServletResponseSpanInjector());
}有時你想創(chuàng)建一個手動Span,將一個電話包裹到一個沒有被檢測的外部服務。您可以做的是創(chuàng)建一個帶有peer.service標簽的跨度,其中包含要調(diào)用的服務的值。下面你可以看到一個調(diào)用redis的例子,它被包裝在這樣一個跨度里。
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標簽和SA標簽!您只需添加peer.service。 |
|---|
默認情況下,Sleuth假設當您將跨度發(fā)送到Zipkin時,您希望跨度的服務名稱等于spring.application.name值。這并不總是這樣。在某些情況下,您希望為您應用程序中的所有spans提供不同的服務名稱。要實現(xiàn)這一點,只需將以下屬性傳遞給應用程序即可覆蓋該值(foo服務名稱的示例):
spring.zipkin.service.name: foo
1
為了定義與特定跨度對應的主機,我們需要解析主機名和端口。默認方法是從服務器屬性中獲取它。如果由于某些原因沒有設置,那么我們正在嘗試從網(wǎng)絡接口檢索主機名。
如果您啟用了發(fā)現(xiàn)客戶端,并且更愿意從服務注冊表中注冊的實例檢索主機地址,那么您必須設置屬性(適用于基于HTTP和Stream的跨度報告)。
spring.zipkin.locator.discovery.enabled: true
1
您可以通過將spring-cloud-sleuth-stream jar作為依賴關系來累加并發(fā)送跨越Spring Cloud Stream的數(shù)據(jù),并為RabbitMQ或spring-cloud-starter-stream-kafka添加通道Binder實現(xiàn)(例如spring-cloud-starter-stream-rabbit)為Kafka)。通過將spring-cloud-sleuth-stream jar作為依賴關系,并添加RabbitMQ或spring-cloud-starter-stream-kafka的Binder通道spring-cloud-starter-stream-rabbit來實現(xiàn){ 22 /} Stream的累積和發(fā)送范圍數(shù)據(jù)。
Kafka)。這將自動將您的應用程序轉(zhuǎn)換為有效載荷類型為Spans的郵件的制作者。
有一個特殊的便利注釋,用于為Span數(shù)據(jù)設置消息使用者,并將其推入Zipkin SpanStore。這個應用程序
@SpringBootApplication
@EnableZipkinStreamServer
public class Consumer {
public static void main(String[] args) {
SpringApplication.run(Consumer.class, args);
}
}
將通過Spring Cloud StreamBinder(例如RabbitMQ包含spring-cloud-starter-stream-rabbit)來收聽您提供的任何運輸?shù)腟pan數(shù)據(jù),Redis和Kafka的類似起始者) 。如果添加以下UI依賴關系
<groupId>io.zipkin.java</groupId> <artifactId>zipkin-autoconfigure-ui</artifactId>
1
2
然后,您將有一個Zipkin服務器,您的應用程序在端口9411上承載UI和API。
默認SpanStore是內(nèi)存中的(適合演示,快速入門)。對于更強大的解決方案,您可以將MySQL和spring-boot-starter-jdbc添加到類路徑中,并通過配置啟用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注釋,因此該過程還將公開標準的Zipkin服務器端點,以通過HTTP收集spans,并在Zipkin Web UI中進行查詢。 |
|---|
也可以使用spring-cloud-sleuth-stream并綁定到SleuthSink來輕松實現(xiàn)自定義消費者。例:
@EnableBinding(SleuthSink.class)
@SpringBootApplication(exclude = SleuthStreamAutoConfiguration.class)
@MessageEndpoint
public class Consumer {
@ServiceActivator(inputChannel = SleuthSink.INPUT)
public void sink(Spans input) throws Exception {
// ... process spans
}
}| 注意 | 上面的示例消費者應用程序明確排除SleuthStreamAutoConfiguration,因此它不會向其自己發(fā)送消息,但這是可選的(您可能實際上想要將消息跟蹤到消費者應用程序中)。 |
|---|
為了自定義輪詢機制,您可以創(chuàng)建名稱等于StreamSpanReporter.POLLER的PollerMetadata類型的bean。在這里可以找到這樣一個配置的例子。
@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注冊了與spans相關的簡單指標。它使用Spring Boot的指標支持
來計算接受和刪除的數(shù)量spans。每次發(fā)送到Zipkin時,接受的spans的數(shù)量將增加。如果出現(xiàn)錯誤,那么刪除的數(shù)字spans將會增加。
感謝你能夠認真閱讀完這篇文章,希望小編分享的“Spring Cloud Sleuth Span的示例分析”這篇文章對大家有幫助,同時也希望大家多多支持創(chuàng)新互聯(lián),關注創(chuàng)新互聯(lián)行業(yè)資訊頻道,更多相關知識等著你來學習!
網(wǎng)站標題:SpringCloudSleuthSpan的示例分析
網(wǎng)站URL:http://www.chinadenli.net/article24/gpscje.html
成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供搜索引擎優(yōu)化、動態(tài)網(wǎng)站、電子商務、微信小程序、面包屑導航、ChatGPT
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)