CFSDN nhấn mạnh vào giá trị tạo ra nguồn mở và chúng tôi cam kết xây dựng nền tảng chia sẻ tài nguyên để mọi nhân viên CNTT có thể tìm thấy thế giới tuyệt vời của bạn tại đây.
这篇CFSDN的博客文章spring-cloud Sleuth的使用方法由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
一直没弄明白sleuth的tracercontext是如何创建和传递的,闲来无事研究了一下。由于对sleuth的源码不熟悉,准备通过debug brave.tracer的nextid()方法,查看方法调用栈来找来龙去脉.
首先创建两个service a和b,记作srva、srvb,在srva中添加testa controller,sevb中添加testb controller,testa中通过feign调用testb.

先看当用户通过浏览器调用srva的时候,srva是作为server的.
configuration: tracewebservletautoconfiguration==>tracingfilter tracehttpautoconfiguration==>httptracing traceautoconfiguration==>tracing sleuthlogautoconfiguration.slf4jconfiguration==>currenttracecontext 。

配置中,tracingfilter在实例化时需要一个httptracing:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
công cộng
tĩnh
filter create(httptracing httptracing) {
trở lại
mới
tracingfilter(httptracing);
}
cuối cùng
servletruntime servlet = servletruntime.get();
cuối cùng
currenttracecontext currenttracecontext;
cuối cùng
tracer tracer;
cuối cùng
httpserverhandler handler;
cuối cùng
tracecontext.extractor extractor;
tracingfilter(httptracing httptracing) {
tracer = httptracing.tracing().tracer();
currenttracecontext = httptracing.tracing().currenttracecontext();
handler = httpserverhandler.create(httptracing, adapter);
extractor = httptracing.tracing().propagation().extractor(getter);
}
|
httptracing builder模式构造时接收一个tracing:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
tracing tracing;
httpclientparser clientparser;
string servername;
httpserverparser serverparser;
httpsampler clientsampler, serversampler;
builder(tracing tracing) {
nếu như
(tracing ==
vô giá trị
)
ném
mới
ngoại lệ con trỏ null(
"tracing == null"
);
cuối cùng
errorparser errorparser = tracing.errorparser();
cái này
.tracing = tracing;
cái này
.servername =
""
;
cái này
.clientparser =
mới
httpclientparser() {
@ghi đè
được bảo vệ
errorparser errorparser() {
trở lại
errorparser;
}
};
cái này
.serverparser =
mới
httpserverparser() {
@ghi đè
được bảo vệ
errorparser errorparser() {
trở lại
errorparser;
}
};
cái này
.clientsampler = httpsampler.trace_id;
cái này
.serversampler(httpsampler.trace_id);
}
|
tracing实例化:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
@đậu
@conditionalonmissingbean
tracing tracing(
@value
(
"${spring.zipkin.service.name:${spring.application.name:default}}"
) string servicename,
propagation.factory factory,
currenttracecontext currenttracecontext,
reporter reporter,
sampler sampler,
errorparser errorparser,
sleuthproperties sleuthproperties
) {
trở lại
tracing.newbuilder()
.sampler(sampler)
.errorparser(errorparser)
.localservicename(servicename)
.propagationfactory(factory)
.currenttracecontext(currenttracecontext)
.spanreporter(adjustedreporter(reporter))
.traceid128bit(sleuthproperties.istraceid128())
.supportsjoin(sleuthproperties.issupportsjoin())
.xây dựng();
}
|
下面看tracingfilter的dofilter:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
span span = handler.handlereceive(extractor, httprequest);
request.setattribute(spancustomizer.
lớp học
.getname(), span.customizer());
request.setattribute(tracecontext.
lớp học
.getname(), span.context());
throwable error =
vô giá trị
;
scope scope = currenttracecontext.newscope(span.context());
thử
{
chain.dofilter(httprequest, httpresponse);
}
nắm lấy
(ioexception | servletexception | runtimeexception | error e) {
error = e;
ném
Và;
}
Cuối cùng
{
scope.close();
nếu như
(servlet.isasync(httprequest)) {
servlet.handleasync(handler, httprequest, httpresponse, span);
}
khác
{
handler.handlesend(adapter.adaptresponse(httprequest, httpresponse), error, span);
}
}
}
|
在sleuthlogautoconfiguration中如果有slfj的包,则注入currenttracecontext:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
@cấu hình
@conditionalonclass
(mdc.
lớp học
)
@enableconfigurationproperties
(sleuthslf4jproperties.
lớp học
)
được bảo vệ
tĩnh
lớp học
slf4jconfiguration {
@đậu
@conditionalonproperty
(giá trị =
"spring.sleuth.log.slf4j.enabled"
, matchifmissing =
ĐÚNG VẬY
)
@conditionalonmissingbean
công cộng
currenttracecontext slf4jspanlogger() {
trở lại
slf4jcurrenttracecontext.create();
}
...
}
|
slf4jcurrenttracecontext中,delegate就是currenttracecontext.default.inheritable():
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
|
công cộng
tĩnh
cuối cùng
lớp học
mặc định
mở rộng
currenttracecontext {
tĩnh
cuối cùng
threadlocal
mặc định
=
mới
threadlocal<>();
tĩnh
cuối cùng
inheritablethreadlocal inheritable =
mới
inheritablethreadlocal<>();
cuối cùng
threadlocal local;
/** uses a non-inheritable static thread local */
công cộng
tĩnh
currenttracecontext create() {
trở lại
mới
mặc định
(
mặc định
);
}
/**
* uses an inheritable static thread local which allows arbitrary calls to {@link
* thread#start()} to automatically inherit this context. this feature is available as it is was
* the default in brave 3, because some users couldn't control threads in their applications.
*
* this can be a problem in scenarios such as thread pool expansion, leading to data being
* recorded in the wrong span, or spans with the wrong parent. if you are impacted by this,
* switch to {@link #create()}.
*/
công cộng
tĩnh
currenttracecontext inheritable() {
trở lại
mới
mặc định
(inheritable);
}
mặc định
(threadlocal local) {
nếu như
(local ==
vô giá trị
)
ném
mới
ngoại lệ con trỏ null(
"local == null"
);
cái này
.local = local;
}
@ghi đè
công cộng
tracecontext get() {
trở lại
local.get();
}
@ghi đè
công cộng
scope newscope(
@nullable
tracecontext currentspan) {
cuối cùng
tracecontext previous = local.get();
local.set(currentspan);
lớp học
defaultcurrenttracecontextscope
thực hiện
scope {
@ghi đè
công cộng
vô hiệu
close() {
local.set(previous);
}
}
trở lại
mới
defaultcurrenttracecontextscope();
}
}
|
slf4jcurrenttracecontext的delegate使用的就是一个inheritablethreadlocal,inheritablethreadlocal在创建子线程的时候,会将父线程的inheritablethreadlocals继承下来。这样就实现了tracecontext在父子线程中的传递.
看一下currenttracecontext的maybescope:
?
1
2
3
4
5
6
7
8
9
10
11
|
công cộng
scope maybescope(
@nullable
tracecontext currentspan) {
tracecontext currentscope = get();
nếu như
(currentspan ==
vô giá trị
) {
nếu như
(currentscope ==
vô giá trị
)
trở lại
scope.noop;
trở lại
newscope(
vô giá trị
);
}
trở lại
currentspan.equals(currentscope) ? scope.noop : newscope(currentspan);
}
|
tracingfilter中httpserverhandler解析request:请输入代码 。
2.srva请求到servb时作为client.
traceloadbalancerfeignclient-->loadbalancerfeignclient-->feignloadbalancer-->lazytracingfeignclient-->client 。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我.
原文链接:https://segmentfault.com/a/1190000018115247 。
最后此篇关于spring-cloud Sleuth的使用方法的文章就讲到这里了,如果你想了解更多关于spring-cloud Sleuth的使用方法的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
Tôi là một lập trình viên xuất sắc, rất giỏi!