Spring은 분산 세션을 처리하기 위한 솔루션인 Spring-Session을 제공합니다. Spring-Session은 Redis, MongoDB, MySQL 등과 같은 일반적인 저장소에 대한 지원을 제공합니다. Spring-Session은 HttpSession과의 투명한 통합을 제공합니다. 이는 개발자가 Spring-Session에서 지원하는 구현을 사용하여 HttpSession을 Spring-Session으로 전환할 수 있음을 의미합니다.
1단계. 종속성 추가
프로젝트의 pom.xml 파일에 Redis 및 Spring-Session의 종속성 패키지를 추가합니다.
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>org.springframework.session</groupId> <artifactId>spring-session-data-redis</artifactId> </dependency>
2단계. Redis 및 Spring-Session 지속성 방법 구성
작성자는 application.properties를 SpringBoot 구성 파일로 사용하는 데 익숙하며, application.yml을 사용하여 구성할 수도 있습니다. application.properties 구성 파일에 다음 구성을 추가합니다.
# 配置 Redis 服务器地址(此处是一个虚假地址) spring.redis.host=10.211.12.6 # 配置 Redis 端口 spring.redis.port=6379 # 配置 Redis 密码 spring.redis.password=123456 # 其他 Redis 的配置还有很多,例如 Redis 连接池的配置,此处暂时只配置上述几项关键点 # spring session 配置 spring.session.store-type=redis
3단계. JSON 직렬화 메커니즘 사용
Spring-Session은 기본적으로 JDK 직렬화 메커니즘을 사용합니다. 이를 위해서는 직렬화 가능 인터페이스를 구현하는 클래스가 필요하며, 이는 이해하기 어려운 바이너리 바이트 배열입니다. JSON 직렬화 메커니즘을 사용하면 직렬화된 문자열을 쉽게 이해할 수 있습니다.
package com.test.conf; import com.alibaba.fastjson.support.spring.GenericFastJsonRedisSerializer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.serializer.RedisSerializer; // spring session 使用 json 序列化机制 @Configuration public class SessionConfig { @Bean public RedisSerializer<Object> springSessionDefaultRedisSerializer() { return new GenericFastJsonRedisSerializer(); } }
4단계. @EnableRedisHttpSession 주석을 SpringBoot 시작 클래스에 추가하여 Spring-Session을 엽니다.
package com.test; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession; @SpringBootApplication // 开启 Spring-Session @EnableRedisHttpSession // @EnableRedisHttpSession(maxInactiveIntervalInSeconds = 1800, redisNamespace = "test:session") public class TestSessionAppApplication { public static void main(String[] args) { SpringApplication.run(TestSessionAppApplication.class, args); } }
@EnableRedisHttpSession 주석을 추가하여 Spring-Session을 엽니다. 주석에는 개별적으로 설정할 수 있는 여러 매개변수가 있습니다. 그 중 maxInactiveIntervalInSeconds는 세션 만료 시간을 나타내며, 기본값은 30분입니다. redisNamespace는 세션이 Redis에 저장될 때의 네임스페이스, 즉 저장된 세션의 키 이름 접두사를 나타냅니다. Redis에서 기본값은 "spring :session"이며, 실제 프로젝트에서는 서로 다른 시스템이 리소스를 절약하기 위해 동일한 Redis를 사용할 수 있습니다. 서로 다른 시스템의 세션을 구별하기 위해 각 시스템마다 별도의 네임스페이스를 설정할 수 있습니다.
2.1 컨트롤러 레이어 작성 테스트 데모
@RequestMapping(value = "testSession") public String testSession(HttpServletRequest request) { HttpSession session = request.getSession(); log.info("sessionId:[{}]", session.getId()); session.setAttribute("name", "Lucy"); session.setAttribute("age", "20"); return session.getAttribute("name").toString(); }
2.2 테스트 프로세스
동시에 여러 포트 9001/9002를 사용하여 SpringBoot 프로젝트를 시작하여 로컬 컴퓨터의 분산 클러스터에 있는 여러 노드를 시뮬레이션합니다. Google Chrome을 사용하여 http://localhost:9001/testSession 링크를 엽니다. 서버는 아래와 같이 로그를 인쇄합니다.
sessionId:[5c417104-4f6d-430d-b569-cbc1e19cdf02]
클라이언트는 Redis 서버에 로그인하고 Redis에서 세션 콘텐츠를 봅니다.
[testuser@vm ~]$ redis-cli -h 10.211.12.6 -p 6379 10.211.12.6:6379> auth 123456 OK 10.211.12.6:6379> keys * 1) "spring:session:expirations:1658127780000" 2) "spring:session:sessions:5c417104-4f6d-430d-b569-cbc1e19cdf02" 3) "spring:session:sessions:expires:5c417104-4f6d-430d-b569-cbc1e19cdf02"
Redis는 각 RedisSession에 대해 세 개의 키-값 쌍(이하 키-값이라고 함)을 저장합니다.
첫 번째 키-값은 Set 유형의 Redis 데이터 구조인 이 세션의 ID를 저장합니다. 이 키의 마지막 1658127780000 값은 다음 분으로 롤링된 세션 만료 순간을 기반으로 계산된 타임스탬프입니다.
두 번째 키-값은 세션의 세부 정보를 저장하는 데 사용됩니다. 세션의 마지막 액세스 시간(lastAccessedTime), 만료 시간 간격(기본값인 maxInactiveInterval)을 포함하는 해시형 Redis 데이터 구조입니다. 30분이며 여기에 초 값이 저장됨), 생성 시간(creationTime), sessionAttr 등이 있습니다.
세 번째 키-값은 Redis에서 Session의 만료 시간을 나타내는 데 사용되며 String 유형의 Redis 데이터 구조입니다. 이 키-값은 유용한 데이터를 저장하지 않으며 단지 세션 만료를 나타내도록 설정됩니다. Redis에서 이 키의 만료 시간은 세션의 만료 간격입니다. ttl 명령을 사용하면 세션의 만료 시간인 키의 만료 시간을 볼 수 있습니다.
이 테스트 동안 Redis의 데이터 세부 정보는 다음과 같습니다.
10.211.12.6:6379> type spring:session:expirations:1658127780000 set 10.211.12.6:6379> smembers spring:session:expirations:1658127780000 1) "\"expires:5c417104-4f6d-430d-b569-cbc1e19cdf02\"" 10.211.12.6:6379> 10.211.12.6:6379> type spring:session:sessions:5c417104-4f6d-430d-b569-cbc1e19cdf02 hash 10.211.12.6:6379> hgetall spring:session:sessions:5c417104-4f6d-430d-b569-cbc1e19cdf02 1) "lastAccessedTime" 2) "1658125969794" 3) "maxInactiveInterval" 4) "1800" 5) "creationTime" 6) "1658125925139" 7) "sessionAttr:age" 8) "\"20\"" 9) "sessionAttr:name" 10) "\"Lucy\"" 10.211.12.6:6379> 10.211.12.6:6379> type spring:session:sessions:expires:5c417104-4f6d-430d-b569-cbc1e19cdf02 string 10.211.12.6:6379> get spring:session:sessions:expires:5c417104-4f6d-430d-b569-cbc1e19cdf02 "" 10.201.42.26:6379>
브라우저 쿠키를 확인하세요. 이때 브라우저에는 아래 그림과 같이 이미 쿠키가 사용 중입니다.
브라우저를 새로 고치면 백엔드에 인쇄된 SessionId는 변경되지 않고 그대로 유지되며 Redis의 세션 콘텐츠는 추가되지 않으며 브라우저는 콘텐츠를 정상적으로 반환합니다. 이는 해당 노드의 세션 동작이 정상임을 의미합니다.
동일한 브라우저에서 다른 테스트 포트 링크인 http://localhost:9002/testSession을 엽니다. 브라우저는 자동으로 쿠키를 전달하며 백엔드 인쇄 콘텐츠도 동일하며 Redis 콘텐츠도 동일합니다(만료 시간이 업데이트되었습니다). , 클러스터 노드가 공유 세션임을 나타냅니다.
Spring-Session은 클러스터 세션 지원을 간단하게 만드는 사용하기 쉽고 거의 투명한 통합 방법을 제공하지만 실제로 Spring-Session에는 몇 가지 결함이 있습니다.
세션 만료 및 소멸 이벤트를 실시간으로 게시하는 것은 불가능합니다.
직렬화 방법은 일부 특정 유형의 세션을 잘 지원하지 않을 수 있습니다.
Redis는 세션 값을 저장하는 데 3개의 키가 필요합니다. 약간 더 큰 공간을 차지합니다.
높은 동시성 시나리오에서는 세션이 CAS(비교 및 설정) 작업이 아니기 때문에 일부 동시성 문제(사소한 문제)가 발생할 수 있습니다.
Spring-Session에는 몇 가지 단점이 있지만 전반적으로 여전히 매우 유용합니다. 또한 Spring-Session의 단점을 최적화하고 분산 세션을 구현하기 위해 필터 세트를 직접 작성할 수 있습니다.
위 내용은 SpringBoot가 Spring 세션을 통합하여 분산 세션을 구현하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!