上一篇讲了单机服务器日志跟踪系统,那么如果系统中使用了 RPC 服务,那么整个流程的日志如何来跟踪呢?
方法一:在每个 RPC 方法里面传入 traceId,然后使用 MDC 把传入的 traceId 放入到日志中;这个方法比较 low,代码侵入性比较高,一不小心就忘记传 traceId 了。
那有没有其他方法呢?
以 dubbo 为例,可以给提供者和消费者添加拦截,那想到消费者可以在拦截里面把 traceId 传过去,提供者那边接收到之后再把 traceId 放到 MDC 里面。这里还需要用到 dubbo 的 RpcContext,他的作用就是负责消费者和提供者之前传值,我们会把 traceId 通过 RpcContext 的 setAttachment 方法进行传递。这个方法没有侵入性,写业务代码的时候完全可以不关心这块,只要写自己的业务就可以了。
消费者端代码
@Activate(group = Constants.CONSUMER)
@Slf4j
public class ApiClientFilter implements Filter {
@Override
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
String traceId = MDC.get("traceId");
if (StringUtils.isNotBlank(traceId)) {
RpcContext.getContext().setAttachment("traceId", traceId);
}
return invoker.invoke(invocation);
}
}
resources 下面创建 META-INF.dubbo 文件夹,创建文件 com.alibaba.dubbo.rpc.Filter
在文件里面写 ApiClientFilter 的路径
traceClientFilter=com.xxx.xxx.filter.ApiClientFilter
如
在 application.properties 配置文件里面(项目使用了 springboot)
spring.dubbo.consumer.filter = traceClientFilter
如果是 xml 配置那么使用
<dubbo:consumer filter="traceClientFilter"/>
以上是消费者端的配置
现在来看看提供者这边的配置
@Activate(group = Constants.PROVIDER)
@Slf4j
public class TraceServerFilter implements Filter {
@Override
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
String traceId = RpcContext.getContext().getAttachment("traceId");
if (StringUtils.isNotBlank(traceId)) {
MDC.put("traceId", traceId);
}
Long startTime = System.currentTimeMillis();
Result result = invoker.invoke(invocation);
Long takeTime = System.currentTimeMillis() - startTime;
String className = invoker.getInterface().getName();
log.info("{}======method:{}.{}(), request:{}, response:{}, time:{} ms=====","|***",
className , invocation.getMethodName(), JSON.toJSONString(invocation.getArguments()),
JSON.toJSONString(result), String.valueOf(takeTime));
return result;
}
}
resources 下面创建 META-INF.dubbo 文件夹,创建文件 com.alibaba.dubbo.rpc.Filter
在文件里面写 TraceServerFilter 的路径
traceServerFilter=com.xxx.xxx.filter.TraceServerFilter
在 application.properties 配置文件里面(项目使用了 springboot)
spring.dubbo.provider.filter = traceServerFilter
到这里整个配置就完成了。
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于