Queue + ThreadLocal丟失

將資料寫入數據庫時發現丟MQ 的 ThreadLocal.get 不到 因為是新的進程了所以要重set 於是將 userId 丟進MQ,在MQ重set 就能拿得到了

  1. filter

     @Override
        protected void doFilterInternal(HttpServletRequest request,
                                        HttpServletResponse response,
                                        FilterChain chain) throws ServletException, IOException {
            try {
                String userId = request.getHeader("X-User-Id");
                log.info("Processing request for userId: {}", userId);
                // 設置到 ThreadLocal
                UserContext.setUserId(userId);
    
                if(ipService.getClientIp(request) == null) {
                    log.info("未取得公網IP...");
                }
    
                //RabbitTemplate 默认使用 SimpleMessageConverter,它能够处理基本类型和 Serializable 接口的对象。
                rabbitTemplate.convertAndSend("userLogQueue", userId); // 1. 這個
    
                chain.doFilter(request, response);
            } finally {
                // 清理 ThreadLocal
                UserContext.clear();
            }
        }
    

  2. MQ

            @RabbitListener(queues = "${rabbitmq.user-log-queue}")
        public void handlUserLog(String userId) {
            try {
                UserContext.setUserId(userId); // 2. 補上這句
                log.info("開始取得當前公網IP loc...");
                String redisLocation = ipService.getRedisLocation();
                if(redisLocation == null){
                    log.info("未取得公網IP loc...");
                    ipService.saveUserLog();
                }
            } catch (Exception e) {
                log.error("公網IP loc任務失敗...", e);
            }
        }
    

  3. Service

    @Service
    @Transactional
    public class IpService {
            public String getRedisLocation() {
            String userId = UserContext.getUserId(); // 3. 這個原本拿不到 是null
            String key = RedisConstants.USERLOG_IP_KEY + userId;
            HashOperations<String, String, String> hashOps = stringRedisTemplate.opsForHash();
            return hashOps.get(key, "loc");
        }
    }