在Brave(zipkin tracer)中,我们通过控制Dispatcher的ExecutorService来附加拦截器读取的状态。
就像这样......
这适用于同步请求(因为它们不使用调度程序线程)和正常的异步请求。
当有超过允许的飞行连接时,它不起作用,因为异步请求在执行之前被推入就绪队列。就绪队列不会被请求的调用线程处理,因此重新连接将不起作用。当拦截器在延迟的请求上运行时,它无法看到它的调用跨度会破坏跟踪。
我在想,也许应用程序拦截器可能没有这个问题。如果在网络级强制执行主机/连接限制(通过提到的队列),我将能够通过双重注册拦截器来协调状态。这个拦截器可以通过映射应用程序/网络级请求来重新连接状态,而不依赖于线程本地。
可悲的是,这不起作用,因为在应用程序级别强制执行主机/连接限制(通过提到的队列),所以我很难过。
我希望能够跟踪请求,尤其是在积压时。有什么想法吗?
向brianm致敬,发现这个问题,btw
答案 0 :(得分:3)
我们有一个实现Call.Factory的内部OkHttpClient包装器,它添加了一个初始拦截器:
public class HttpClient implements Call.Factory {
private final OkHttpClient ok;
HttpClient(final OkHttpClient ok) {
this.ok = ok;
}
/**
* Implements Call.Factory, uses implicit (thread local) Ctx
*/
public Call newCall(final Request request) {
return newCall(Ctx.fromThread().orElseGet(Ctx::empty), request);
}
public Call newCall(Ctx ctx, final Request request) {
OkHttpClient.Builder b = this.ok.newBuilder();
b.interceptors().add(0, new CtxInterceptor(ctx));
return b.build().newCall(request);
}
解决这个问题。然而,它并不透明,因此可能不适合勇敢。它工作正常,因为在实践中,一旦配置了客户端,您只能真正使用Call.Factory
接口: - )
Ctx
位只是我们想要传播的东西的上下文,我们可以隐式或显式执行,因此需要额外的方法来明确地使用它。