上一篇讲了单机服务器日志跟踪系统,那么如果系统中使用了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
到这里整个配置就完成了。
注意:本文归作者所有,未经作者允许,不得转载