Post

Spring Session JDBC ๋„์ž…๊ธฐ

๐ŸŽฌ Intro

๋ถ„์‚ฐ ํ™˜๊ฒฝ์—์„œ Session ๊ด€๋ฆฌ๋ฅผ ์œ„ํ•œ Spring Session JDBC๋ฅผ ๋„์ž…ํ•˜๋Š” ๊ณผ์ •์„ ์†Œ๊ฐœํ•ฉ๋‹ˆ๋‹ค.

๊ฒฐ๋ก 

Spring Session JDBC๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ถ„์‚ฐํ™˜๊ฒฝ์—์„œ Session ๋ถˆ์ผ์น˜๋ฅผ ํ•ด๊ฒฐํ•˜๊ณ , EC2 ์ถ”๊ฐ€ ์ธํ”„๋ผ ๋น„์šฉ ์›” ์•ฝ 20% ์ ˆ๊ฐ ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

ํ˜„์žฌ ์ƒํ™ฉ

  • ๋‹จ์ผ ์„œ๋ฒ„ ํ™˜๊ฒฝ์—์„œ ๋ถ„์‚ฐ ํ™˜๊ฒฝ์œผ๋กœ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜
  • Session์ด ์„œ๋ฒ„ ๋ฉ”๋ชจ๋ฆฌ์—์„œ ๊ด€๋ฆฌ

ํ˜„์žฌ ์ƒํ™ฉ์ด ์™œ ๋ฌธ์ œ๊ฐ€ ๋˜๋Š”๊ฐ€?

์„œ๋ฒ„ ๋ฉ”๋ชจ๋ฆฌ์—์„œ Session์„ ๊ด€๋ฆฌํ•˜๊ณ  ์žˆ์–ด ๋ถ„์‚ฐํ™˜๊ฒฝ์—์„œ๋Š” Session ๋ถˆ์ผ์น˜๊ฐ€ ๋ฐœ์ƒํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๋•Œ๋ฌธ์— ๋กœ๊ทธ์ธํ•œ ์‚ฌ์šฉ์ž๊ฐ€ ์„ธ์…˜์ด ๋งŒ๋ฃŒ๋˜๊ธฐ์ „์— ๊ฐ„ํ—์ ์œผ๋กœ ๋กœ๊ทธ์•„์›ƒ์ด ๋˜๋Š” ์ƒํ™ฉ์ด์—ˆ์Šต๋‹ˆ๋‹ค.

๊ฐœ์„  ๊ณผ์ •

โœ… Session ๊ด€๋ฆฌ ๋ฐฉ๋ฒ•

๋ถ„์‚ฐํ™˜๊ฒฝ์˜ Session ๋ถˆ์ผ์น˜๋ฅผ ํ•ด๊ฒฐ ํ•˜๊ธฐ ์œ„ํ•ด์„  ์ด 3๊ฐ€์ง€์˜ ์„ ํƒ์ง€๊ฐ€ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

1. Sticky Session

๋กœ๋“œ ๋ฐธ๋Ÿฐ์„œ๊ฐ€ ์ฟ ํ‚ค๋‚˜ IP ๊ธฐ๋ฐ˜์œผ๋กœ ์‚ฌ์šฉ์ž๋ฅผ ์‹๋ณ„ํ•˜๊ณ , ํ•ด๋‹น ์‚ฌ์šฉ์ž์˜ ์š”์ฒญ์„ ํ•ญ์ƒ ๋™์ผํ•œ ์„œ๋ฒ„๋กœ ๋ผ์šฐํŒ…

์žฅ์ : ๊ตฌํ˜„์ด ๋งค์šฐ ๊ฐ„๋‹จํ•˜๊ณ  ๊ธฐ์กด ์ฝ”๋“œ ๋ณ€๊ฒฝ์ด ๊ฑฐ์˜ ์—†์Œ. ์„ธ์…˜ ์ผ๊ด€์„ฑ์ด ์™„๋ฒฝํ•˜๊ฒŒ ๋ณด์žฅ.

๋‹จ์ : ํŠน์ • ์„œ๋ฒ„์— ๋ถ€ํ•˜๊ฐ€ ์ง‘์ค‘๋  ์ˆ˜ ์žˆ๊ณ , ๊ทธ ์„œ๋ฒ„์— ์žฅ์• ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ํ•ด๋‹น ์‚ฌ์šฉ์ž๋“ค์˜ ์„ธ์…˜์ด ๋ชจ๋‘ ์‚ฌ๋ผ์ง. ๋˜ํ•œ ์ง„์ •ํ•œ ์˜๋ฏธ์˜ ๋ถ€ํ•˜ ๋ถ„์‚ฐ์ด ์ด๋ฃจ์–ด์ง€์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Šต

2. Session Replication

๊ฐ ์„œ๋ฒ„๊ฐ€ ํด๋Ÿฌ์Šคํ„ฐ๋ฅผ ๊ตฌ์„ฑํ•˜์—ฌ ์„ธ์…˜ ์ •๋ณด๋ฅผ ์‹ค์‹œ๊ฐ„์œผ๋กœ ๋™๊ธฐํ™”

์žฅ์ : ์™„์ „ํ•œ ๋ถ€ํ•˜ ๋ถ„์‚ฐ์ด ๊ฐ€๋Šฅํ•˜๊ณ  ์„œ๋ฒ„ ์žฅ์• ์— ๊ฐ•ํ•จ

๋‹จ์ : ์„œ๋ฒ„ ๊ฐ„ ๋„คํŠธ์›Œํฌ ํŠธ๋ž˜ํ”ฝ์ด ์ฆ๊ฐ€ํ•˜๊ณ , ์„œ๋ฒ„ ์ˆ˜๊ฐ€ ๋Š˜์–ด๋‚ ์ˆ˜๋ก ๋ณต์ œ ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ ๊ธฐํ•˜๊ธ‰์ˆ˜์ ์œผ๋กœ ์ปค์ง

3. External Session Store

์„ธ์…˜ ์ •๋ณด๋ฅผ ์„œ๋ฒ„์˜ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ์•„๋‹Œ ๋ณ„๋„์˜ ์™ธ๋ถ€ ์ €์žฅ์†Œ์— ์ €์žฅ

์žฅ์ : ํ™•์žฅ์„ฑ์ด ๋›ฐ์–ด๋‚˜๊ณ  ์„œ๋ฒ„๋ฅผ ์ž์œ ๋กญ๊ฒŒ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ์Œ. ๋˜ํ•œ ์„ธ์…˜ ๋ฐ์ดํ„ฐ๋ฅผ ์˜์†์ ์œผ๋กœ ์ €์žฅํ•  ์ˆ˜๋„ ์žˆ์–ด์„œ ์„œ๋ฒ„ ์žฌ์‹œ์ž‘ ์‹œ์—๋„ ์„ธ์…˜์ด ์œ ์ง€

๋‹จ์ : ์™ธ๋ถ€ ์ €์žฅ์†Œ๋กœ์˜ ๋„คํŠธ์›Œํฌ ์ง€์—ฐ์ด ๋ฐœ์ƒํ•˜๊ณ , ์ถ”๊ฐ€ ์ธํ”„๋ผ ๋น„์šฉ์ด ํ•„์š”

๊ฒฐ๊ณผ์ ์œผ๋กœ ์ €ํฌ๋Š” 3๋ฒˆ ๋ฐฉ๋ฒ•์„ ์ฑ„ํƒํ•˜์˜€์Šต๋‹ˆ๋‹ค. ๊ทธ ์ด์œ ๋Š” AutoScaling ๊ธฐ๋ฐ˜์˜ ๋ถ„์‚ฐ ํ™˜๊ฒฝ์œผ๋กœ ๋˜์–ด ์žˆ์–ด ๊ฐœ๋ณ„ ์„œ๋ฒ„๊ฐ€ ์„ธ์…˜์„ ์ง์ ‘ ๊ด€๋ฆฌํ•˜๊ธฐ ์–ด๋ ค์šด ๊ตฌ์กฐ์ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๋˜ํ•œ ์Šค์ผ€์ผ ์•„์›ƒ์ด๋‚˜ ์ธ์Šคํ„ด์Šค ๊ต์ฒด๊ฐ€ ์ˆ˜์‹œ๋กœ ์ผ์–ด๋‚˜๋Š” ์ƒํ™ฉ์—์„œ ์„œ๋ฒ„ ๋ฉ”๋ชจ๋ฆฌ์— ์„ธ์…˜์„ ๋‘๊ฒŒ ๋˜๋ฉด, ์‚ฌ์šฉ์ž๋Š” ์„ธ์…˜์ด ์‚ฌ๋ผ์ ธ ์žฌ๋กœ๊ทธ์ธ์„ ๋ฐ˜๋ณตํ•ด์•ผ ํ•˜๊ณ  ์žฅ์• ๋‚˜ ์žฌ๋ฐฐํฌ ์‹œ ์ผ๊ด€์„ฑ์„ ๋ณด์žฅํ•˜๊ธฐ๋„ ์–ด๋ ต์Šต๋‹ˆ๋‹ค.

โœ… ์™ธ๋ถ€ ์ €์žฅ์†Œ ์„ ํƒ MySQL vs Redis

์™ธ๋ถ€ ์ €์žฅ์†Œ๋กœ๋Š” Redis(์ถ”๊ฐ€ํ•„์š”) vs MySQL(๊ธฐ์กด์‚ฌ์šฉ) 2๊ฐ€์ง€ ์„ ํƒ์ง€๊ฐ€ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ ์™ธ๋ถ€ ์„ธ์…˜ ์ €์žฅ์†Œ๋กœ Redis๋ฅผ ๋งŽ์ด ์‚ฌ์šฉํ•˜์ง€๋งŒ, ์ €ํฌ ์„œ๋น„์Šค์— ํ•ฉ๋‹นํ•œ์ง€ ํ•œ๋ฒˆ ์กฐ์‚ฌํ•ด๋ดค์Šต๋‹ˆ๋‹ค.

Redis ๋น„์šฉ ์ฒดํฌ

img.png

์ €ํฌ ์„œ๋น„์Šค์—์„œ๋Š” Redis๋ฅผ ์‚ฌ์šฉํ•œ์ ์ด ์—†๊ธฐ ๋•Œ๋ฌธ์—, ์šฐํ…Œ์ฝ”์˜ ๋‹ค๋ฅธ ํŒ€ ์ค‘ Redis๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ํŒ€์˜ ์ธ์Šคํ„ด์Šค ๋น„์šฉ์„ ๊ฒ€์ƒ‰ํ•ด๋ดค์Šต๋‹ˆ๋‹ค. ํŠน์ • ์ธ์Šคํ„ด์Šค๋กœ ๋น„์šฉ์„ ๊ฒ€์ƒ‰ํ•  ๊ฒฝ์šฐ 14์ผ์น˜์˜ ๋น„์šฉ๋งŒ ๊ณ„์‚ฐ์ด ๋์—ˆ๊ณ , ๋น„์šฉ์€ ์•ฝ 6$ ์˜€์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿผ ์›” ์‚ฌ์šฉ๋ฃŒ๋Š” ์•ฝ 12$ ์ด๊ณ , ์ €ํฌ์—๊ฒŒ ์ œํ•œ๋œ ์›” ์‚ฌ์šฉ๋ฃŒ 70$์˜ ์•ฝ 20%๊ฐ€ Redis ์‚ฌ์šฉ ๋น„์šฉ์œผ๋กœ ๋‚˜๊ฐ€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

Session์ด ํ•„์š”ํ•œ API ํ˜ธ์ถœ ํšŸ์ˆ˜ ์ฒดํฌ

img.png

Session์ด ํ•„์š”ํ•œ admin ์‚ฌ์šฉ์ž์˜ api ํ˜ธ์ถœ ํšŸ์ˆ˜๋ฅผ ๋ณด๋ฉด, ์ „์ฒด์˜ ์•ฝ 25% ์ •๋„ ์˜€์Šต๋‹ˆ๋‹ค.

์œ„ ์ƒํ™ฉ์„ ์ข…ํ•ฉํ–ˆ์„๋•Œ Redis๋ฅผ ์‚ฌ์šฉํ•˜๋Š”๊ฒƒ์€ ๋น„ํšจ์œจ์ ์ด๋ผ๊ณ  ํŒ๋‹จ์„ ํ–ˆ์—ˆ๊ณ  ๊ธฐ์กด MySQL์„ ์‚ฌ์šฉํ•˜๋Š”๊ฒƒ์œผ๋กœ ํŒ€์›๋“ค๊ณผ ํ•จ๊ป˜ ๊ฒฐ์ •ํ–ˆ์Šต๋‹ˆ๋‹ค.

โœ… Spring Session ํ•™์Šต

img.png Spring์—์„œ ์ด๋Ÿฌํ•œ ๋ถ„์‚ฐํ™˜๊ฒฝ์—์„œ Session์„ ์–ด๋–ป๊ฒŒ ๊ด€๋ฆฌํ•˜๋Š”์ง€ ์ฐพ์•„๋ณด๋˜ ์ค‘, Spring ๊ณต์‹ ๋ฌธ์„œ์—์„œ ์œ„์™€ ๊ฐ™์€ ๋‚ด์šฉ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ์ฆ‰, Spring Session์„ ์‚ฌ์šฉํ•˜๋ฉด ์„ธ์…˜๊ด€๋ฆฌ๋ฅผ DB์—์„œ ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์˜๋ฏธ์ž…๋‹ˆ๋‹ค. ๊ทธ ๋™์ž‘ ์›๋ฆฌ๋ฅผ ํ•œ๋ฒˆ ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

img.png Spring Session์€ SessionRepositoryFilter๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์š”์ฒญ์„ ๊ฐ€๋กœ์ฑ•๋‹ˆ๋‹ค. ํ•ด๋‹น ํ•„ํ„ฐ๋Š” HttpServletRequest, HttpServletResponse ์˜ ๊ตฌํ˜„์ฒด๋ฅผ ๊ฐ๊ฐ SessionRepositoryRequestWrapper, SessionRepositoryResponseWrapper ๋กœ ์ƒ์„ฑํ•˜๋Š”๋ฐ, ์ด๋ฅผ Wrapping ์ด๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ๋ž˜ํ•‘์„ ํ•˜๋Š” ์ด์œ ๋Š” Tomcat์ด ๊ด€๋ฆฌํ•˜๋Š” ๋ฉ”๋ชจ๋ฆฌ ์„ธ์…˜์„ Spring Session์ด ๊ด€๋ฆฌํ•˜๋„๋ก ํ•˜๊ธฐ ์œ„ํ•จ์ž…๋‹ˆ๋‹ค.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
    throws ServletException, IOException {
  request.setAttribute(SESSION_REPOSITORY_ATTR, this.sessionRepository);
  // 1. Request์™€ Response๋ฅผ Wrapping
  SessionRepositoryRequestWrapper wrappedRequest = new SessionRepositoryRequestWrapper(request, response);
  SessionRepositoryResponseWrapper wrappedResponse = new SessionRepositoryResponseWrapper(wrappedRequest,
      response);

  try {
    // 2. ๋‹ค์Œ ํ•„ํ„ฐ๋กœ ์ „๋‹ฌ (๋ž˜ํ•‘๋œ request ์‚ฌ์šฉ)
    filterChain.doFilter(wrappedRequest, wrappedResponse);
  }
  finally {
    // 3. ์š”์ฒญ ๋๋‚  ๋•Œ ์„ธ์…˜์„ DB์— ์ปค๋ฐ‹
    wrappedRequest.commitSession();
  }
}

Spring ๊ณต์‹ github ์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด ์œ„์™€ ๊ฐ™์ด HttpServletRequest ๋ฐ HttpServletResponse๊ฐ€ Wrapping ๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

1
2
3
4
5
6
7
class SessionRepositoryRequestWrapper extends HttpServletRequest {
    @Override
    public HttpSession getSession() {
        // Tomcat ์„ธ์…˜ ๋Œ€์‹  Repository ์„ธ์…˜ ๋ฐ˜ํ™˜
        return repositorySession;
    }
}

๋˜ํ•œ ํ•ด๋‹น ๊ตฌํ˜„์ฒด๋Š” ์œ„์™€ ๊ฐ™์ด Session์„ DB๋ฅผ ์ด์šฉํ•ด์„œ ๊ด€๋ฆฌํ•˜๋„๋ก ๋ฉ”์†Œ๋“œ๋ฅผ ์˜ค๋ฒ„๋ผ์ด๋“œ ํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๊ฒฐ๊ณผ์ ์œผ๋กœ Wrapping๋œ HttpServletRequest, HttpServletResponse๋Š” DispatcherServlet์„ ํ†ตํ•ด ์ปจํŠธ๋กค๋Ÿฌ๋กœ ์ „๋‹ฌ๋˜๊ฒŒ ๋˜๊ณ , ์ตœ์ข…์ ์œผ๋กœ ๋‹คํ˜•์„ฑ์„ ํ†ตํ•ด Session์„ DB๋ฅผ ํ†ตํ•ด ์กฐํšŒ, ์ €์žฅํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

โœ… Spring Session ์ ์šฉ

Spring Session์„ ์ ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ์ •๋ง ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค. session ํ…Œ์ด๋ธ” ์ƒ์„ฑ๊ณผ ์–ด๋…ธํ…Œ์ด์…˜ ์ถ”๊ฐ€๋งŒ ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

@EnableJdbcHttpSession ์–ด๋…ธํ…Œ์ด์…˜์œผ๋กœ Spring Session ํ™œ์„ฑํ™”

1
2
3
4
5
6
@Configuration
@EnableJdbcHttpSession(
        maxInactiveIntervalInSeconds = 14 * 24 * 60 * 60  // ์„ธ์…˜ ๋งŒ๋ฃŒ 2์ฃผ
)
public class SessionConfig {
}

@EnableJdbcHttpSession๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๋ฉด Spring์€ SessionRepositoryFilter ๋นˆ์„ ์ƒ์„ฑํ•˜๊ณ  Servlet Container์— ๋“ฑ๋กํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

Session ํ…Œ์ด๋ธ” ์ƒ์„ฑ

1
2
3
4
5
6
7
8
9
10
11
12
CREATE TABLE IF NOT EXISTS SPRING_SESSION (
    PRIMARY_ID CHAR(36) NOT NULL PRIMARY KEY,
    SESSION_ID CHAR(36) NOT NULL,
    CREATION_TIME BIGINT NOT NULL,
    LAST_ACCESS_TIME BIGINT NOT NULL,
    MAX_INACTIVE_INTERVAL INT NOT NULL,
    EXPIRY_TIME BIGINT NOT NULL,
    PRINCIPAL_NAME VARCHAR(100),
    UNIQUE INDEX spring_session_ix1 (SESSION_ID),
    INDEX spring_session_ix2 (EXPIRY_TIME),
    INDEX spring_session_ix3 (PRINCIPAL_NAME)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
1
2
3
4
5
6
7
CREATE TABLE IF NOT EXISTS SPRING_SESSION_ATTRIBUTES (
    SESSION_PRIMARY_ID CHAR(36) NOT NULL,
    ATTRIBUTE_NAME VARCHAR(200) NOT NULL,
    ATTRIBUTE_BYTES BLOB NOT NULL,
    PRIMARY KEY (SESSION_PRIMARY_ID, ATTRIBUTE_NAME),
    FOREIGN KEY (SESSION_PRIMARY_ID) REFERENCES SPRING_SESSION(PRIMARY_ID) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

img.png

Session ๊ด€๋ฆฌ์— ํ•„์š”ํ•œ ํ…Œ์ด๋ธ”์€ 2๊ฐ€์ง€ ์ž…๋‹ˆ๋‹ค. ๊ฐ ํ…Œ์ด๋ธ”์˜ ์—ญํ• ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • SPRING_SESSION : ์„ธ์…˜์˜ ์ƒ์„ฑ์‹œ๊ฐ„, ๋งŒ๋ฃŒ์‹œ๊ฐ„ ๋“ฑ ๊ธฐ๋ณธ ์ •๋ณด๋ฅผ ์ €์žฅํ•˜๋Š” ๋ฉ”์ธ ํ…Œ์ด๋ธ”
  • SPRING_SESSION_ATTRIBUTES : ์„ธ์…˜์— ์ €์žฅ๋œ ์‹ค์ œ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๋Š” ํ…Œ์ด๋ธ”
1
2
3
4
5
INSERT INTO SPRING_SESSION_ATTRIBUTES VALUES (
    'abc-123-def',           -- SESSION_PRIMARY_ID
    'user',                  -- ATTRIBUTE_NAME
    <์ง๋ ฌํ™”๋œ User ๊ฐ์ฒด>      -- ATTRIBUTE_BYTES
);

์˜ˆ๋ฅผ ๋“ค์–ด session.setAttribute("user", user)๋กœ ์œ ์ € ์„ธ์…˜ ์ •๋ณด๋ฅผ ์ €์žฅํ•œ๋‹ค๋ฉด, ์œ„์™€ ๊ฐ™์€ ์ฟผ๋ฆฌ๊ฐ€ ๋ฐœ์ƒํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

์„ฑ๊ณผ

โœ… ์ถ”๊ฐ€ ์ธํ”„๋ผ ๋น„์šฉ 20% ์ ˆ๊ฐ

โœ… ๋ถ„์‚ฐํ™˜๊ฒฝ Session ๋ถˆ์ผ์น˜ ๋ฌธ์ œ ํ•ด๊ฒฐ

๋งˆ๋ฌด๋ฆฌํ•˜๋ฉฐ

ํŒ€์› ๋ชจ๋‘ ๋งŒ์กฑํ•˜๋Š” ๊ฒฐ๊ณผ๋ผ ๋ฟŒ๋“ฏํ–ˆ๊ณ , ๊ธฐ์ˆ ์„ ์„ ํƒํ•จ์— ์žˆ์–ด ๋น„์šฉ๊ณผ ๋ณต์žก๋„๋ฅผ ๊ณ ๋ คํ•˜๋Š”๊ฒƒ์ด ์–ผ๋งˆ๋‚˜ ์ค‘์š”ํ•œ์ง€๋ฅผ ๊นจ๋‹ฌ์•˜์Šต๋‹ˆ๋‹ค. ๋‹จ์ˆœํžˆ ์ข‹๋‹ค ๋ผ๋Š” ๊ด€์ ์—์„œ Redis๋ฅผ ์‚ฌ์šฉํ–ˆ๋‹ค๋ฉด, ๊ด€๋ฆฌ ๋น„์šฉ๊ณผ ๋ณต์žก๋„ ๋ชจ๋‘ ์˜ฌ๋ผ๊ฐ”์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋˜ํ•œ ์ด๋ฒˆ ๊ธฐํšŒ์— Spring Session์˜ ์›๋ฆฌ์— ๋Œ€ํ•ด์„œ๋„ ๊นŠ๊ฒŒ ํ•™์Šตํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. Wrapping ํŒจํ„ด์„ ํ†ตํ•ด Tomcat์˜ ์„ธ์…˜ ๊ด€๋ฆฌ๋ฅผ ํˆฌ๋ช…ํ•˜๊ฒŒ ๋Œ€์ฒดํ•˜๋Š” ์„ค๊ณ„๊ฐ€ ํŠนํžˆ ์ธ์ƒ์ ์ด์—ˆ๊ณ , ์–ด๋…ธํ…Œ์ด์…˜ ํ•˜๋‚˜๋กœ ์„ธ์…˜ ์ €์žฅ์†Œ๋ฅผ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์—์„œ ์ถ”์ƒํ™”์™€ ๋‹คํ˜•์„ฑ์˜ ์ค‘์š”์„ฑ์„ ํ•œ๋ฒˆ ๋” ๊นจ๋‹ฌ์„ ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

This post is licensed under CC BY 4.0 by the author.