본문 바로가기
Spring/Spring Security

Spring Security - Nginx LB + 세션 클러스터링(Session Clustering) ③

by WangTak 2022. 2. 21.
반응형

구성도

 

③ 편을 정리하기 앞서 ①, ② 편에 대해서 정리를 하고 진행하도록 하겠습니다.

 

1. ①, ② 편의 목적은 Nginx의 LB 기능을 이용하여 무중단 배포를 하려고 함입니다.

1-1. ① 편에서는 Session Clustering을 위해 스프링의 Session을 위부 Redis로 이관하였습니다.

1-2. ② 편에서는 로컬에서 개발한 ① 편의 스프링을 개발 서버의 스펙에 맞게 수정과 추가를 하였습니다.

2. 그럼 여기서 무중단 배포를 하려고 하는데 왜 갑자기 Session Clustering이지?라고 생각할 수 있습니다. 혹은 그냥 Nginx conf 파일 설정해서 port 다르게, LB 사용해서 애플리케이션 2개 띄우면 되는 거 아니야?라고 생각할 수도 있습니다.

3. 그러나 제가 프로젝트에서 사용한 인증 & 인가 시스템은 Spring Security이며, Spring Security의 인증 수단 중 form 인증 방식을 사용하였습니다.

4. form 인증 방식은 Session & Cookie 방식이기 때문에 A 애플리케이션에서 로그인한 후에, B 애플리케이션으로 요청을 보냈을 때 Client 입장에서는 이미 로그인했음에도 불구하고 Server 입장에서는 인증되지 못한 사용자로 인식해버리는 문제가 발생했습니다.

5. 고로, 이 문제를 해결하기 위해 Session & Cookie 방식의 인증 & 인가에서는 Session Clustering을 도입해야 한다고 생각했습니다.

6. 그럼 "Session Clustering 이란 것이 뭘까?"라는 질문의 제 대답은 "A, B 각각의 애플리케이션에 존재하는 Session을 한 곳으로 모으는 과정이다"라고 답 할 것 같습니다. => Session을 보관하는 공동의 저장소를 두는 것

 

그럼 개발 서버에 배포하고, 결과를 확인해보도록 하겠습니다. 이번 포스트도 여타 포스트와 마찬가지로 배포 환경은 Docker[CentOS 7]을 사용할 것이며, ①, ② 편에서 준비한 스프링 애플리케이션과 Nginx + Java 11 + MySQL 8.0을 사용할 것입니다.

 

위에서 말씀드린 Docker[CentOS 7], .jar, Nginx, Java 11, MySQL 8.0의 환경 세팅은 제가 이전에 정리한 글을 참조해주시기 바랍니다.

Docker + CentOS 7 + Java 11 + Nginx 설치 - Docker(CentOS 7) + Nginx + Spring Boot + Vue.js 배포하기 - ①

CentOS 7 + MySQL 8.0 설치 - Docker + CentOS 7 + MySQL 8.0 설치하기

 

1. Redis 설치하기

다른 포스트에서는 위와 같은 기술을 다뤘지만 CentOS 7에서 Redis 설치하는 방법에 대해서는 다뤄본 적이 없기 때문에 이 글에서 Redis 설치를 정리하겠습니다.

# yum 최신 버전 업데이트 [root 계정이 아니면 sudo를 붙여주세요]
# sudo 가 명령어가 없다고 뜬 다면 yum install 해주시면 됩니다!
# 혹은 공부인 만큼 root 계정으로 하셔도 상관 없습니다.
sudo yum update 

# redis도 mysql와 마찬가지로 yum repository에 기본적으로 등록되어 있지 않기 때문에
# 별도로 EPEL Repository를 추가해줘야 합니다.
sudo yum install -y epel-release

# redis 설치
sudo yum install -y redis

# redis 시작 & 설정
sudo systemctl start redis # redis 시작
sudo systemctl enable redis # 서버가 재부팅되도 자동으로 시작
sudo systemctl status redis # redis 상태 확인

 

2. 서버 상태 확인

 

3. jar 실행 및 배포

② 편에서 만든 스프링 애플리케이션의 jar 파일을 생성한 후에 개발 서버로 이동시키도록 하겠습니다. 쉘 스크립트를 미리 만들어두면 백 그라운드로 애플리케이션을 실행할 수 있지만 지금은 java -jar를 통해 애플리케이션을 실행하도록 하겠습니다. 이 과정에서 docker container의 cli를 여러 개 사용해야 합니다.

 

Docker Container로 옮긴 session.jar를 다음과 같은 명령어로 실행하도록 하겠습니다. terminal 한 개당 명령어 한 개씩 해주셔야 합니다.

 

# terminal A
java -Dspring.profiles.active=dev -Dserver.port=8080 -jar session.jar

# terminal B
java -Dspring.profiles.active=dev -Dserver.port=8081 -jar session.jar

# terminal C [java application이 정상적으로 수행됐는지 확인]
ps -aux | grep 'java'

java application 확인

 

4. Nginx conf 설정

이제는 nginx 설정만 하면 끝이 납니다.

# nginx의 설정 파일 디렉토리로 이동
cd /etc/nginx/conf.d 

sudo vi default.conf

# nginx 설정 파일을 다음과 같이 수정해주세요.

 

default.conf

upstream sessionweb {
    server 127.0.0.1:8080       weight=3;
    server 127.0.0.1:8081;
}

server {
    listen       80;
    server_name  localhost;

    #access_log  /var/log/nginx/host.access.log  main;

    location / {
        proxy_pass http://sessionweb;
        # root   /usr/share/nginx/html;
        # index  index.html index.htm;
    }

    #error_page  404              /404.html;

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

}

 

nginx의 설정에 대한 자세한 내용은 다른 포스트에서 다루도록 하겠습니다. 위처럼 default.conf를 작성한 후에 저장을 하고 nginx -t 를 통해 conf 파일의 변경된 내용에 문제가 있는지 확인을 한 후에 성공 메시지가 나오면 다음과 같이 재실행해주시면 됩니다.

# nginx conf 파일 상태 체크
nginx -t

# nginx 서비스 재시작 방법 1
sudo systemctl reload nginx

# nginx 서비스 재시작 방법 2
sudo systemctl stop nginx
sudo systemctl start nginx

 

5. 결과 확인

1. host pc에서 web browser를 통해 localhost or localhost:80으로 접속해줍니다.

2. Spring Security에서 지원하는 로그인 화면을 확인하실 수 있으며, InitData 클래스에서 넣어준 계정으로 로그인을 합니다.

3. 로그인에 성공하게 되면 Main 화면으로 이동하게 되며 8080 Port가 나오는 것을 확인하실 수 있습니다.

4. 로그인 성공한 Main 화면에서 새로고침을 지속적으로 해보면 8080의 숫자가 8081로 바뀌는 것을 확인 하실 수 있습니다.

5. port가 바뀌었음에도 로그인 화면으로 이동하지 않았기 때문에 이것은 로그인이 유지되는 것을 의미합니다.

6. CentOS 7으로 이동하여 redis-cli를 통해 redis 서버로 이동하여 keys * 명령어를 사용하면 현재 로그인 한 계정의 정보와 session 정보를 확인할 수 있습니다.

7. redis 서버에서 flush all 명령어를 사용하면 session이 비워지게 되고, host의 web browser를 새로고침 해보면 로그아웃 된 것을 확인 할 수 있습니다.

 

지금까지 ①, ②, ③ 편을 통해서 Nginx의 LB 기능Session Clustering을 사용하여 Spring Security의 form 인증 방식에서 로그인이 끊기지 않는 무중단 배포를 정리해봤습니다.

 

 

반응형