HTTP 요청에는 상태가 없습니다. 이 말은 각각의 요청이 독립적으로 이뤄지며, 서버는 사용자가 보낸 몇번째 요청인지에 대한 정보 같은걸 저장되지 않는다는 의미입니다. 다른 방향에서 해석하면, 사용자 브라우저 측에서 자신을 식별할 수 있는 정보를 서버에 요청할 때 마다 알려줘야 한다는 의미입니다.
이때 사용자의 브라우저에 응답을 보내면서, 브라우저에 특정 데이터를 저장하도록 전달할 수 있습니다. 이때 서버에서 작성해서 응답을 받은 브라우저가 저장하는 데이터를 쿠키라고 부릅니다.

저희는 응답을 보내면서 쿠키에 요청을 보낸 브라우저를 특정지을 값을 보내줄 수 있습니다. 이후 사용자가 요청을 보낼때, 해당 값을 보내주면 서버에서 저장 해놓은 정보를 기반으로 브라우저에 로그인한 사용자가 누구인지를 구분할 수 있습니다. 이런식으로 상태를 저장하지 않는 HTTP 통신을 사용하면서, 이전에 요청을 보낸 사용자를 기억하는 상태를 유지하는 것을 세션이라고 부릅니다.
간단하게 세션을 작동을 봅시다.
package com.example.redis;
import jakarta.servlet.http.HttpSession;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class SessionController {
@GetMapping("/set")
public String set(
@RequestParam("q")
String q,
HttpSession session
) {
session.setAttribute("q", q);
return "Saved: " + q;
}
@GetMapping("/get")
public String get(
HttpSession session
) {
return String.valueOf(session.getAttribute("q"));
}
}
이제 요청을 하면

jsessionid 항목에 값이 들어가 있습니다.
이건 내장 tomcat이 만들어줍니다.
그럼 세션을 사용자가 쿠키에 저장을하고 요청시 같이보내어 서버에 누구인지 표시를하게되고 세션에 저장된 정보를 사용할 수 있습니다.
사용자가 많아지고 서버의 성능 개선의 한계가 오면 개발자는 서버의 수를 늘려 분산처리를 해야합니다. 그럼 서버1에서 발급된 jsessionid는 서버2에서는 사용 할 수 없습니다.
여러 서버가 있고 사용자는 서버1에서 jsessionid를 발급했다면 르드벨러서에서 자동으로 서버1로만 요청을 보낸다. 하지만 Sticky Session은 서버1에 계속 사용자가 증가하면 부하가 걸린다. 그럼 서버가 다운 될 수 있고 그럼 처리중이던 요청에도 문제가 생기기 때문에 문제가 된다.
이는 여러 서버들이 하나의 저장소를 공유하고, 해당 저장소에 세션에 대한 정보를 저장함으로서, 요청이 어느 서버로 전달이 되든 세션 정보가 유지될 수 있도록 하는 방법입니다.
아무 사용자나 저희 서버(의 로드밸런서)로 요청을 보낸다고 가정해 봅니다. 그러면 저희 서버는 세션을 생성하되, 이 세션에 연결된 정보를 내부에 저장하는게 아닌 외부의 저장소에 저장을 하는 겁니다.

dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
// 세션 클러스터링
implementation 'org.springframework.session:spring-session-data-redis'
}
denpendencies에 세션 클러스터링을 위해 의존성을 추가해줍니다.
그럼 바로 사용해볼 수 있다.

그럼 새롭게 SESSION이 추가 되는데 이게 redis에 저장되어 사용된다.
jsessionid는 더이상 사용되지안하아 지우고 요청해보면 정상작동 되는걸 볼 수 있다.

데이터를 보면 이상하게 나온데 그 이유는 자바에서 직렬화를 하면서 바이트 코드때문에 그렇다.
@Configuration
public class RedisConfig {
// ...
@Bean
public RedisSerializer<Object> springSessionDefaultRedisSerializer() {
return RedisSerializer.json();
}
}
을 적어주면 해결된다.

나중에 spring security와 조합하여 사용할 때 Security Context가 세션에 저장된다.
그런데 위에 json형식으로 저장을 하면 생성자가 없어서 에러가 일어날 수 있다.
RedisSerializer.json()을 RedisSerializer.java()로 변경하면 문제 없이 동작한다.