排查日志:apm在网关webflux变量丢失

Posted go大鸡腿

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了排查日志:apm在网关webflux变量丢失相关的知识,希望对你有一定的参考价值。

前言

在自研apm项目中,发现网关traceId会被篡改
具体逻辑,有拦截器,然后在请求处理前,set tarceId,然后set到对应threadlocal里面,然后在mono返回的时候,从threadlocal拿出值,打印日志。

场景

a请求,traceId为123,b请求,traceId为666.在链路监控里头,会发现a的请求traceId被b覆盖了变成666

排查过程

  1. threadlocal本身就会导致变量丢失
    打印对应的日志查看线程名称,发现都是同个线程reactor-http-nio,那不会导致变量丢失

  2. gateway 采用webflux实现,看下其他开源中间件怎么实现
    TLog 框架,总结:通过exchange来传递变量
    https://gitee.com/dromara/TLog/blob/master/tlog-webflux/src/main/java/com/yomahub/tlog/webflux/common/TLogWebFluxCommon.java

    https://gitee.com/dromara/TLog/blob/master/tlog-gateway/src/main/java/com/yomahub/tlog/gateway/filter/TLogGatewayFilter.java

    Sleuth框架:通过context来传递

https://github.com/spring-cloud/spring-cloud-sleuth/issues/1748

  1. webflux知识充电
    reactor线程模型,多线程模型,是不是跟netty很像

    怎样理解阻塞非阻塞与同步异步的区别? - 知乎

https://mp.weixin.qq.com/s/HJ9Kwqw9Bp5zRuWTFWn8Pw

  1. webflux怎么添加上下文

结论

其实上面已经给出解决方案,通过exchange或者context来传递mono变量
其次的话通过第四点,可以看到mono采用背压式来处理数据,有发布者,处理器,订阅者。就像mq一样,整个流程是不会被阻塞的,异步的话主要通过线程池来实现。

导致的原因:其实我还没找到,我觉得比较好的解释是:mono跟背压模式差不多,就是有发布者,处理器,订阅者,但是他们是同个线程。
比如说请求要处理a->b->c步骤,发送到处理器,消费者开始消费,拿一个a处理完,再拿b。另外一个请求进来,他不需要等第一个请求处理完,直接往处理器丢他的a->b->c,这样可以实现非阻塞
那这样的话就有可能造成一个线程变量被其他线程覆盖,注意非阻塞,意思是同个线程可以处理不同的请求!!!

以上是关于排查日志:apm在网关webflux变量丢失的主要内容,如果未能解决你的问题,请参考以下文章

SpringCloudGateway使用Skywalking时日志打印traceId

Spring boot + webflux:并行运行某些步骤时上下文丢失

Azure-如何排查应用程序网关返回 HTTP Code 502 或客户端得到应用程序网关响应慢的问题

微服务海量日志监控平台

微服务海量日志监控平台

运维开发实践——基于Sentry搭建错误日志监控系统