我们正在运行一个Web应用程序,它本身由几个微服务组成,对于每个请求,我们需要最终调用第三方服务,这非常耗时,通常需要几秒钟。 我们需要使用请求traceId跟踪每个请求的所有服务中的所有处理日志。
在当前实现中,我们使用基于线程的并发模型,分配线程以在每个服务中从头到尾处理请求,并在等待远程服务的响应时被阻止。 将traceId放入ThreadLocal是非常自然的,这样我们就可以随时随地将其取回。
但基于线程的并发模型不能很好地扩展,我们倾向于改为NIO /事件驱动模型,并尝试使用非常大的性能改进Netty。 但是每个请求处理的不同阶段可能由Netty的不同线程处理,使得日志的跟踪非常棘手。
我们当前的考虑包括:
将traceId作为方法参数传递,无论如何它已经在请求中,但如果深层嵌套方法需要它,则非常不方便。 在每个回调开始时将traceId设置为ThreadLocal 。 但我个人认为这种方法容易出错,可能会引入难以发现的竞争条件错误。那么在NIO /事件驱动模型中解决这种跟踪问题的复杂/优雅方法是什么?
We're running a web application which itself consists of several micro services, and for each request we need to call a 3rd-party service finally, which is time-consuming and typically costs couple seconds. We have a requirement that need to trace all processing logs among all services for each request, using a request traceId.
In current implementation we're using thread-based concurrency model, a thread is assigned to handle a request from beginning to the end in each service, and blocked when waiting remote service's response. It's very natural to put the traceId into ThreadLocal so that we can get it back whenever/wherever we need it.
But the thread-based concurrency model doesn't scale well, we tend to change to a NIO/Event-driven model and tried Netty with a very big performance improvement. But different phases for each request processing might be handled by different threads with Netty, making the logs' tracing very tricky.
Our current considerations include:
Pass traceId as method parameter, it's already in request anyway, But it's very un-convenient if a deep-nested method needs it. Set traceId into ThreadLocal at the beginning of every callbacks. But personally I believe this approach is error-prone and could potentially introduces hard-to-find race-condition bugs.So what's the sophisticated/elegant way to resolve such a tracing problem in NIO/Event-driven model?
更多推荐
发布评论