Shiro & Java8 parallelStream & Dubbo Filter 引发线上问题

在使用Java8 parallelStream调用Dubbo Provider时,由于ForkJoinPool线程池继承了Tomcat线程池的InheritableThreadLocal,导致在Dubbo Filter中获取到的用户上下文可能错误。问题原因是并行流中的ForkJoinPool线程在创建时继承了主线程的用户上下文信息。解决方案包括禁用parallelStream、在Filter中添加兼容代码或改变获取用户上下文的方式。
摘要由CSDN通过智能技术生成

背景描述

需求对Dubbo Provider的返回的数据做一层数据过滤
即Dubbo Provider 接口返回的数据必须和Web层用户登录的信息相同
实现方案比较简单 使用Dubbo官方提供的Filter 机制即可

实现方案

使用Dubbo官方提供的Filter 机制即可
在Web层自定义Dubbo Filter 过滤Dubbo Provider返回的结果信息
然后获取用户上下文信息 比对返回结果的数据是否和用户上下文一致

问题描述

当使用Java8 parallerStream调用Dubbo Provider时会发生用户下文信息错乱的问题
当Controller中使用parallerStream并行调用Dubbo Provider接口时
Dubbo Filter过滤Provider返回的结果时 发现和当前用户上下文不一致

问题排查&定位

  • 首先排查Dubbo Filter中获取用户上下文的方式
    • 项目使用的是Shiro框架 其获取用户上下文代码如下
      • org.apache.shiro.SecurityUtils#getSubject
         public static Subject getSubject() {
                 
                Subject subject = ThreadContext.getSubject();
                if (subject == null) {
                 
                    subject = (new Subject.Builder()).buildSubject();
                    ThreadContext.bind(subject);
                }
                return subject;
            }
        
    • 看到这里可知Shiro将用户上下文存放在线程上下文ThreadLocal中

      ? 其实当时看到这段代码我是很疑惑的 因为parallerStream是基于ForkJoinPooll来实现的
      如果使用了parallerStream 那么在Dubbo Filter我们获取到的用户上下文应该是空的
      因为Shiro框架是运行在Tomcat 线程中的 ForkJoinPoll的线程池

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值