背景 【全链路参数透传】现在的系统大多是基于SOA的分布式应用 。跨服务调用的时候 , 存在线程上线文里的重要信息如traceId,租户id无法传递给下一个应用 。
要解决的问题
- 内部系统通过RocketMQ交互时 , traceId如何透传到消息消费应用
- 内部系统通过Dubbo调用时, traceId如何透传到服务提供方
- http调用这里不做赘述
@Before("execution(* org.apache.rocketmq.client.producer.DefaultMQProducer.send*(..))")public void addTraceId(JoinPoint joinPoint) {Message message = (Message) joinPoint.getArgs()[0];message.getProperties().put("traceId", TraceIdContext.getTraceId());} 收消息时 , 通过aop拦截 MQMessageHandler.handlerMessage 方法 , 将traceId从Message的properties里面写入到threadLocal里@Before("execution(* MQMessageHandler.handlerMessage(..))")public void addTraceId(JoinPoint joinPoint) {MessageExt message = (MessageExt) joinPoint.getArgs()[0];TraceIdContext.put(message.getProperties().get("TraceId"));} 2 dubbo调用透传解决方案 dubbo调用时 , 提供了一个隐式参数传递的功能 , 详见官方文档 https://dubbo.apache.org/zh/docs/v2.7/user/examples/attachment/ , 但是这个功能有一个问题setAttachment 设置的 KV 对 , 在完成下面一次远程调用会被清空 , 即多次远程调用要多次设置 。
这里还需要配合dubbo提供的一个SPI扩展点改造——Filter,每次调用的都时候都从threadLocal取出来进行隐式传递 , 参见官方文档 https://dubbo.apache.org/zh/docs/v2.7/dev/impls/filter/
消费方调用服务时 , 从threadLocal中取出traceId , 然后进行dubbo隐式参数传递
@Activate(group = Constants.CONSUMER)public class TraceIdConsumerFilter implements Filter {@Overridepublic Result invoke(Invoker> invoker, Invocation invocation) throws RpcException {RpcContext.getContext().setAttachment("TraceId", TraceIdContext.getTraceId());return invoker.invoke(invocation);}} 服务提供方处理请求时 , 从隐式参数中取出TraceId , 写入threadLocal 。完成参数透传@Activate(group = Constants.PROVIDER)public class TraceIdProviderFilter implements Filter {@Overridepublic Result invoke(Invoker> invoker, Invocation invocation) throws RpcException {String TraceId = RpcContext.getContext().getAttachment("TraceId");TraceIdContext.put(TraceId);return invoker.invoke(invocation);}} 这两个spi扩展点需要进行配置- 春季老年人吃什么养肝?土豆、米饭换着吃
- 三八妇女节节日祝福分享 三八妇女节节日语录
- 老人谨慎!选好你的“第三只脚”
- 校方进行了深刻的反思 青岛一大学生坠亡校方整改校规
- 脸皮厚的人长寿!有这特征的老人最长寿
- 长寿秘诀:记住这10大妙招 100%增寿
- 春季老年人心血管病高发 3条保命要诀
- 眼睛花不花要看四十八 老年人怎样延缓老花眼
- 香槟然能防治老年痴呆症? 一天三杯它人到90不痴呆
- 老人手抖的原因 为什么老人手会抖
