java吧 关注:1,248,615贴子:12,731,029
  • 23回复贴,共1
求助

使用redis实现登陆,为什么还要使用ThreadLocal

只看楼主收藏回复

最近在看黑马点评网课,有一个功能是使用redis+token获取用户信息,然后把这些用户信息储存在ThreadLocal里,实现登陆。这里既然已经使用了redis,为什么还要使用ThrealLocal呢,感觉没必要啊😦


IP属地:河南来自Android客户端1楼2024-05-12 23:16回复
    那我反问你个问题 你每次需要时是不是都要去redis取吗? 还是直接给你的好呢


    IP属地:湖北来自iPhone客户端2楼2024-05-12 23:33
    收起回复
      这样就不用每次获取用户信息都从redis里取,从ThreadLocal取快又节省资源


      IP属地:浙江3楼2024-05-12 23:38
      回复
        threadlocal只见过当临时存储的。还可以当缓存用?


        IP属地:重庆来自Android客户端4楼2024-05-13 05:11
        收起回复
          因为ThreadLocal是你这个程序用的,redis是一个中间件,其他程序也可以用。还有就是拓展性和设计。


          IP属地:湖南来自Android客户端5楼2024-05-13 08:59
          收起回复
            上面说了用threadLocal的目的,但实际上不用threallocal也不是不行,但得看你们系统架构咋做的
            如果是分布式的架构,只需要在最外层设计个网关,在网关里解析一下token,拿到一些必要的用户信息,之后把这些信息作为header透传给下游服务就可以了。
            如果是单体应用,也有一招:可以用argumentReslover + 自定义注解 去自定义 controller层的对象解析,在解析器里面获取token,去redis里查询出用户信息,然后根据注解配置去注入对象;这样在api层就能直接通过自定义注解 + 对象去直接拿到用户信息了。
            中心思想就是怎么实现在controller层之前统一拿到token解析用户信息,然后还能保证在controller层获取到用户信息,实现形式可以是五花八门的。


            IP属地:辽宁6楼2024-05-13 09:53
            回复
              确实没啥必要,而且有个问题就是如果要更新用户信息。如果有多个线程保存了这个用户信息,那么怎么通知这些线程去更新用户信息?再加个订阅机制?反正把问题弄复杂了


              IP属地:广东7楼2024-05-13 10:10
              回复
                上面的吧友回复的挺好的 我再补充一句 在软件设计中有一种思想: "immutable(不可变设计)" 这点在缓存中很重要 因为缓存会涉及解决缓存一致性问题。但如果使用缓存的场景 不是强一致性需求 或者说几乎不变 那么就可以使用 immutable(不可变设计) 解决问题
                SourceData(在缓存中 ) -> Copy To -> ThreadObject(不允许修改缓存中SourceData)
                如果 SourceData如果需要修改 需要一个专业的业务函数修改(权限业务 批量修改)
                使用ThreadLocal 的一个意义是私有化Copy 使用SourceData和的ThreadObject 互不影响


                IP属地:湖北8楼2024-05-13 12:39
                回复
                  减少io操作


                  IP属地:浙江来自Android客户端9楼2024-05-13 12:49
                  回复
                    没记错的话,redis存入了登陆态,用拦截器验证是否登陆。
                    在登陆时,拦截器从Redis拿下来存入的threadlocal,相当于存入一个map,减少了之后需要登录信息时,对redis 的多次io


                    IP属地:陕西来自Android客户端10楼2024-05-13 16:41
                    收起回复
                      你可以理解为一个请求就开启一个线程,从redis中取出来数据经过操作之后存到当前线程本地变量,在这个线程结束之前一直可以从线程本地变量中取出数据使用,


                      IP属地:河南来自Android客户端11楼2024-05-18 23:54
                      回复
                        看来没遇见过特殊场景,假如一个接口开头和末尾都要用到用户信息,如果开头能取到,但是末尾突然取不到或取到不正确的值导致业务异常(无论是用户正常的登出或修改用户信息改变了redis数据,redis出现故障),如果在接口一开始从redis里取出放到threadlocal里,接口里后续业务处理能够按照稳定的信息去处理


                        IP属地:福建来自Android客户端12楼2024-05-19 01:34
                        收起回复