背景描述
需求对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; }
- org.apache.shiro.SecurityUtils#getSubject
- 看到这里可知Shiro将用户上下文存放在线程上下文ThreadLocal中
? 其实当时看到这段代码我是很疑惑的 因为parallerStream是基于ForkJoinPooll来实现的
如果使用了parallerStream 那么在Dubbo Filter我们获取到的用户上下文应该是空的
因为Shiro框架是运行在Tomcat 线程中的 ForkJoinPoll的线程池
- 项目使用的是Shiro框架 其获取用户上下文代码如下