Spring session integrates redis principle to find out the cause of failure

Keywords: Java Redis Spring

After a spring session is configured on the Internet and redis is integrated as a session, it is found that the session acquisition fails and there is value in redis. The login module can also be obtained, but other services cannot be obtained. Record it and follow the source code to find out why it failed
auth service configuration

  1. Introduce dependency
        <dependency>
            <groupId>org.springframework.session</groupId>
            <artifactId>spring-session-data-redis</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>io.lettuce</groupId>
                    <artifactId>lettuce-core</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
        </dependency>
  1. Write configuration
spring:
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.0.94:8848
  application:
    name: eshop-auth
  thymeleaf:
    cache: false
  session:
    store-type: redis
  redis:
    host: 192.168.0.94
  1. Use annotation @ enablereredishttpsession
  2. Expand the domain name of the cookie
@Configuration
public class SessionConfig {
    @Bean
    public CookieSerializer cookieSerializer(){
        DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer();
        cookieSerializer.setDomainName("gulimall.com");
        return cookieSerializer;
    }
}
  1. Set session after successful login
    @PostMapping("/login")
    public String login(UserLoginVo loginVo, HttpSession session) {
        session.setAttribute("user","123");
        return "redirect:http://gulimall.com";
    }

Other modules

Search principle

  1. Starting from the @ enablereredishttpsession annotation, you can see that it introduces another configuration RedissonHttpSessionConfiguration

  2. RedissonHttpSessionConfiguration introduces a RedissonSessionRepository

  3. RedissonHttpSessionConfiguration inherits from SpringHttpSessionConfiguration. This class creates a filter

  4. First, analyze RedissonSessionRepository
    It encapsulates some operations of adding, deleting, modifying and querying session s

  5. Let's take a look at the filter. First, get it from the RedissonSessionRepository just created and put it inside

  6. There is one way

  7. This method belongs to the abstract method OncePerRequestFilter of its parent class

  8. Inside the dofilterinternal method, both request and response are wrapped and passed to the next layer

  9. At this time, let's look at how spring MVC sessions are obtained. Directly using session and getsession of request are the same thing

  10. So let's see how the getsession in the wrapped request is implemented

  11. Because my problem this time is that the logged in session cannot be found on the home page, there must be a session. The problem lies in the getRequestedSession method
    This sessionRepository is the class introduced in the initial annotation

  12. Operation on session in RedisSessionRepository

So far, in the process of tracking the source code, I found that
S session = SessionRepositoryFilter.this.sessionRepository.findById(sessionId);
The data returned in this method is null
After careful investigation, it is found that the implementation class has become RedissonSessionRepository
Because redisson is used as a distributed lock in this module, when annotations are used, @ enablereredishttpsession automatically prompts a bug caused by @ enablereredisonhttpsession. If you don't understand the source code, this problem may take a long time to find out

Posted by Kunax on Sun, 03 Oct 2021 13:29:31 -0700