以前一直习惯用 ThreadLocal,但在异步下就不知道怎么搞了,InheritableThreadLocal 的话,没有找到清除用户的入口,filter 肯定不行了,请求结束子线程还没完成不可能去把数据清理掉,求各位大佬指点。 现在的问题是很多代码当初只考虑的是单线程,直接 service 层获取登陆用户,现在要异步的话代码全报错了,当初这种写法是不是不能用
1
buzaiyouyu123 2021-04-09 14:57:58 +08:00 1
1.异步线程可以设置上下文,通过上下文传递
2.想办法在子线程前后织入登录用户相关的信息,即 Context 3.阿里的 TTL ( transmittable-thread-local )可以参考 |
2
buzaiyouyu123 2021-04-09 14:59:11 +08:00
或者自己来实现一个线程池的 wrapper
|
3
HariopaNic 2021-04-09 14:59:45 +08:00 via iPhone 1
自愧不如没有 30,只有 18
|
4
lance7in 2021-04-09 15:02:13 +08:00 1
不敢当不敢当
18cm 来观赏各位巨巨的优雅 |
5
Aruforce 2021-04-09 15:03:02 +08:00 via Android
无参过去应该不行…
|
7
sutra 2021-04-09 15:05:36 +08:00
|
10
dqzcwxb 2021-04-09 15:14:09 +08:00
当成参数传递给异步线程,你用其他的方式也不过是 ThreadLocal 的变种
|
12
securityCoding 2021-04-09 15:33:35 +08:00 1
我这边的方案是获取登录态信息只在 controller 层处理,往下层走的时候以方法参数的形式传过去。
具体的流程是: 1. 网关获取请求头中的 token,登录态 filter 解析 token ( isLogin,uid,uname,merchantId )设置到请求头。 2. 网关带着登录态请求头转发请求。 3. 底层服务从来不需要关注登录态,直接获取请求头即可。 |
13
securityCoding 2021-04-09 15:33:59 +08:00
@dengji85 本身属于确定性的参数,就应该显示传
|
14
tsanie 2021-04-09 15:42:23 +08:00
30 怕不是从肛门开始量(
|
15
hzz2 2021-04-09 15:46:47 +08:00 1
现在问个问题都这么骚了吗
|
16
timethinker 2021-04-09 15:53:59 +08:00 1
在同步编程模型下直接通过本地线程变量获取绑定的信息,相当于在这个线程上下文中设定了全局变量。
使用同步编程模型,如果在 service 里面获取当前的信息,就跟使用 service 的环境耦合了(本地线程变量),service 不是无状态的。 当然如果一直使用这种同步编程模型是没什么问题的,但如果想要在异步环境下不改变代码也可以使用 service 的话,就必须要在执行阶段先进行类似环境绑定的操作。 比如在执行前,将之前的全局变量绑定到当前的线程,执行完以后再清除避免下一个执行任务获取到错误的信息。 |
17
CatKiller 2021-04-09 15:55:49 +08:00
无 图 言 弔
|
19
bz5314520 2021-04-09 16:28:36 +08:00
请求来的时候,自己包装个上下文呗。
|
20
liuqitoday 2021-04-09 17:10:20 +08:00 1
与 12 楼一样,获取登录态信息只在 controller 层处理,往下层走的时候以方法参数的形式传过去
|
21
keshawnvan 2021-04-09 17:30:46 +08:00
作为参数传过去,Service 层不应该感知登录态的。
|
22
vacuitym 2021-04-09 17:34:14 +08:00
我们用 dubbo 的时候是放在上下文,然后拦截之后放在 threadlocal
|
23
yisheyuanzhang 2021-04-09 17:38:41 +08:00 1
异步线程是如何创建的呢?线程池?
我们项目使用的全局线程池,方案是线程池每次执行的时候都从父线程中把 1 、Shiro/Spring security 当前用户 context 存放在 InheritableThreadLocal 中 2 、 线程池内线程每次执行任务时都将父线程 InheritableThreadLocal 复制给池内子线程 记了个笔记 https://zhaoydo.gitee.io/2020/08/26/thread-pool-thread-local/ |
24
ychost 2021-04-09 17:45:18 +08:00
Service 层不应该主动感知用户信息,应该是 Controller 层感知到,然后传给 Service 层处理,
|
25
xuanbg 2021-04-09 22:06:55 +08:00
拦截器或网关验证 token 的时候解析出来用户信息,然后放在请求头上面。Controller 里面取出来传给 Service 。
|
26
xuanbg 2021-04-09 22:09:54 +08:00 1
@yisheyuanzhang InheritableThreadLocal 这种只适合单体架构,局限性比较大
|
27
aguesuka 2021-04-10 11:50:23 +08:00 via Android
异步怎么实现的?成熟的同步或者异步方案都有 threadlocal 或者 context(vertx)。如果没有就自己实现一个。
|