Session not replicated on session creation with Spring Boot, Session, and Redis

前端 未结 2 1808
误落风尘
误落风尘 2021-02-06 10:38

I\'m attempting to implement a microservices architecture using Spring Cloud\'s Zuul, Eureka, and my own services. I have multiple services that have UIs and services and each c

相关标签:
2条回答
  • 2021-02-06 11:01

    Thanks to shobull for pointing me to Justin Taylor's answer to this problem. For completeness, I wanted to put the full answer here too. It's a two part solution:

    1. Make Spring Session commit eagerly - since spring-session v1.0 there is annotation property @EnableRedisHttpSession(redisFlushMode = RedisFlushMode.IMMEDIATE) which saves session data into Redis immediately. Documentation here.
    2. Simple Zuul filter for adding session into current request's header:

      import com.netflix.zuul.ZuulFilter;
      import com.netflix.zuul.context.RequestContext;
      import javax.servlet.http.HttpSession;
      import org.slf4j.Logger;
      import org.slf4j.LoggerFactory;
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.session.Session;
      import org.springframework.session.SessionRepository;
      import org.springframework.stereotype.Component;
      
      @Component
      public class SessionSavingZuulPreFilter extends ZuulFilter {
          @Autowired
          private SessionRepository repository;
      
          private static final Logger log = LoggerFactory.getLogger(SessionSavingZuulPreFilter.class);
      
          @Override
          public String filterType() {
              return "pre";
          }
      
          @Override
          public int filterOrder() {
              return 1;
          }
      
          @Override
          public boolean shouldFilter() {
              return true;
          }
      
          @Override
          public Object run() {
              RequestContext context = RequestContext.getCurrentContext();
      
              HttpSession httpSession = context.getRequest().getSession();
              Session session = repository.getSession(httpSession.getId());
      
              context.addZuulRequestHeader("Cookie", "SESSION=" + httpSession.getId());
      
              log.trace("ZuulPreFilter session proxy: {}", session.getId());
      
              return null;
          }
      }
      

    Both of these should be within your Zuul Proxy.

    0 讨论(0)
  • 2021-02-06 11:17

    Spring Session support currently writes to the data store when the request is committed. This is to try to reduce "chatty traffic" by writing all attributes at once.

    It is recognized that this is not ideal for some scenarios (like the one you are facing). For these we have spring-session/issues/250. The workaround is to copy RedisOperationsSessionRepository and invoke saveDelta anytime property is changed.

    0 讨论(0)
提交回复
热议问题