网站建设目的功能,wordpress文章tag,找工作在什么网站找比较好,主题巴巴wordpress问题
在微服务架构中#xff0c;一次业务执行完可能需要跨多个服务#xff0c;这个时候#xff0c;我们想看到业务完整的日志信息#xff0c;就要从各个服务中获取#xff0c;即便是使用了ELK把日志收集到一起#xff0c;但如果不做处理#xff0c;也是无法完整把一次业…问题
在微服务架构中一次业务执行完可能需要跨多个服务这个时候我们想看到业务完整的日志信息就要从各个服务中获取即便是使用了ELK把日志收集到一起但如果不做处理也是无法完整把一次业务请求的日志完整链路串联起来。有人说可以在日志中加入某个业务参数比如订单id等但是不可能所有业务都是有这样的参数给你用的。
解决方案
在打印日志的时候加入一个可以贯穿整个业务请求的唯一标识我们把它称traceId。下面是在一个物联网项目的微服务架构中使用dubbo时的基本流程 拿到traceId该怎么使用呢答案也很简单用过logback的都知道是可以在日志信息里配置一些公共参数的比如方法名类名线程名等我们把traceId也设置进去就可以了。 logback配置如下 encoder classch.qos.logback.classic.encoder.PatternLayoutEncoderpattern%date{yyyy-MM-dd HH:mm:ss} [%-5level] [%X{traceId}] [%thread] [%logger{80}] [%file:%line] [%method] %msg%n/patterncharsetutf-8/charset/encoder代码中设置 web过滤器针对的是HTTP请求
Configuration
public class TraceFilter extends OncePerRequestFilter {Overrideprotected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,FilterChain filterChain) throws IOException, ServletException {try {String uuid UUID.randomUUID().toString();MDC.put(traceId,uuid);filterChain.doFilter(request, response);} finally {// 必须清除MDC.clear();}}
}
跨服务调用走dubbo 消费者过滤器
Activate(group {CommonConstants.CONSUMER})
public class ConsumerDubboFilter implements org.apache.dubbo.rpc.Filter{Overridepublic Result invoke(Invoker? invoker, Invocation invocation) throws RpcException {MapString, Object attachments invocation.getObjectAttachments();// 获取traceIdString traceId MDC.get(traceId);// 传递日志追踪信息attachments.put(traceId,traceId);return invoker.invoke(invocation);}
}生产者过滤器
Activate(group {CommonConstants.PROVIDER})
public class ProviderDubboFilter implements org.apache.dubbo.rpc.Filter{Overridepublic Result invoke(Invoker? invoker, Invocation invocation) throws RpcException {try {// 获取到traceIdString traceId (String)invocation.getObjectAttachment(traceId);// 设置traceIdMDC.put(traceId,traceId);return invoker.invoke(invocation);}finally {// 必须清除MDC.clear();}}
}有聪明的小伙伴此时已经想到了一个问题那就是如果在子线程中打印日志依然是拿不到traceId的没关系照样可以解决子线程传递上下文信息第一个想到的是什么对阿里的TTL 在pom中引入 dependencygroupIdcom.ofpay/groupIdartifactIdlogback-mdc-ttl/artifactIdversion1.0.2/version/dependencylogback的xml配置中加入一行代码
contextListener classcom.ofpay.logback.TtlMdcListener/还有伙伴会问如果用的是OpenFeign呢其实原理一样使用OpenFeign的拦截器在跨服务调用之前拦截拿到traceId再放入HTTP请求头中下游服务在过滤器中再从请求头中获取即可。这里代码就不再展示直接搜feign的拦截器使用就行了。
扩展
既然traceId可以这样透传那么其他的一些公共的信息当然也可以透传比如分页信息用户信息ThreadLocal中上下文信息都可以使用这样的方式去透传让开发人员感觉还是在单服务中一样简便。
下一篇MQTTDisruptor提高并发