Jun's note

Nginx를 이용한 로드밸런싱 본문

Computer Science/Network

Nginx를 이용한 로드밸런싱

junning 2023. 3. 5. 23:53
728x90

프로젝트 리팩토링 단계 중, 로드밸런싱 기술에 대해 알게되어 이를 정리해볼려고 한다!
 
1. 로드밸런싱이란?
한마디로 서버 부하를 분산하는 것이다. 
한 대의 서버로 부하가 집중되지 않도록, 트래픽을 여러 서버로 분산하는 것이다. 
로드밸런싱하는 방법은 웹서버를 통한 로드밸런싱, AWS 서비스를 통한 로드밸런싱 이렇게 2가지 방식으로 구현할 수 있다. 

1 - 1) 웹서버를 통한 로드밸런싱
- Nginx를 예로 들 수 있다.
Nginx는 웹서버로, 하는 일은 크게 2가지가 있다.
첫번째는 클라이언트로부터 요청받은 정적파일(html,js,이미지파일 등)을 처리한다. 이를 통해 WAS의 부담을 줄여줘  좀더 안정적인 서버를 구축할 수 있다. WAS는 동적인 데이터를 처리하기 때문에 웹서버보다 잘 죽는다고 한다. 만약 웹서버 없이 WAS 한대만 있는 상황에서 WAS가 죽게되면 서비스 또한 장애를 겪게 된다. 웹서버를 설치하면 WAS의 부담을 줄일 수 있고, WAS가 죽더라도 웹서버가 이를 감지하여 에러페이지를 반환할 수도 있다.
두번째는 프록시 서버 역할을 한다. 프록시란? '대리'라는 의미를 가진다. 클라이언트가 바로 WAS로 요청하는 것이 아닌 대리로 중간에 한번 거쳐가는 서버라고 생각하면 좋을거같다. 
프록시 서버는 클라이언트 쪽에 존재하는 포워드 프록시 서버와 서버 쪽에 존재하는 리버스 프록시 서버가 있다. 

포워드 프록시 서버
리버스 프록시 서버

nginx는 리버스 프록시 서버 역할을 한다. 클라이언트로부터 받은 요청을 리버스 프록시 서버가 먼저 받은 다음 WAS로 넘겨준다. 이를 통해 nginx는 클라이언트로부터 받은 요청을 WAS서버에 분산해서 보낼 수 있다. 이 때 어떤 기준으로 WAS에게 넘겨줄지에 대한 몇몇 알고리즘(라운드로빈, Least-connected)이 있다. 
 
이렇게 nginx를 도입하면 '무중단 배포'를 수행할 수 있다.
무중단 배포란? 
원래 서버를 배포할때 서버를 중지한 다음에 배포작업을 수행하는데, nginx를 두면 서버가 여러대 작동중이기 때문에 하나 서버를 중지해도 서비스가 중단되지 않기 때문에 무중단 배포가 가능해진다. 이는 안정적인 서비스를 구축하는데 도움을 준다.
 
1 - 2) AWS 서비스를 통한 로드밸런싱
AWS의 NLB와 ALB 서비스가 있다.
NLB(Network Load Balancing)은 이름에서부터 볼 수 있듯이 Layer4단에서 로드밸런싱을 하고, ALB(Application Load Balancing)은 Layer7단에서 로드밸런싱을 한다.
 
위 서비스를 통해 구현하려면 ec2가 여러개 필요하며 nginx는 한 개의 ec2로 구현할 수 있다. 후자에 대해 다시 설명하면 ec2안에 웹서버(nginx)를 설치해 WAS를 여러개두는 방식으로 구현한다. 
aws프리티어를 쓰는 입장으로 ec2여러개가 필요하면 비용측면에서 부담이 되니 nginx를 통한 로드밸런싱을 프로젝트에 적용하기로 했다!
 
NLB와 ALB의 장단점도 기억해두자!
 

ALB

  1. ALB는 L7단의 로드 밸런서를 지원합니다.
  2. ALB는 HTTP/HTTPS 프로토콜의 헤더를 보고 적절한 패킷으로 전송합니다.
  3. ALB는 IP주소 + 포트번호 + 패킷 내용을 보고 스위칭합니다.
  4. ALB는 IP 주소가 변동되기 때문에 Client에서 Access 할 ELB의 DNS Name을 이용해야 합니다.
  5. ALB는 L7단을 지원하기 때문에 SSL 적용이 가능합니다.

NLB

  1. NLB는 L4단의 로드 밸런서를 지원합니다.
  2. NLB는 TCP/IP 프로토콜의 헤더를 보고 적절한 패킷으로 전송합니다.
  3. NLB는 IP + 포트번호를 보고 스위칭합니다.
  4. NLB는 할당한 Elastic IP를 Static IP로 사용이 가능하여 DNS Name과 IP주소 모두 사용이 가능합니다.
  5. NLB는 SSL 적용이 인프라 단에서 불가능하여 애플리케이션에서 따로 적용해 주어야 합니다.

속도 측면에서도 차이가 난다. NLB가 ALB보다 빠르다. 왜냐하면 4계층까지만 확인하기 때문이다.
유연성 측면에서도 차이가 난다. ALB가 NLB보다 보안, 유연성 측면에서 좋다. 왜냐하면 ALB는 7계층까지 확인하니 패킷을 더 유연하게 다룰 수 있기 때문이다.
 


2. 프로젝트 상황

1) 현재 상황
- ec2 : 1개
- Spring boot Application
WAS만 있고 웹서버는 없는 상태
 
2) 구현 목표 & 과정
(목표)
웹서버를 설치하여 한 개의 WAS를 여러개 WAS로 분산하자!
 
(과정)
1. nginx(웹서버) 설치
2. nginx코드 
   
3. 스프링 코드 (서버 잘 작동되는지 확인)

nginx conf파일

upstream변수는 server설정에서 nginx가 받아들이는 요청을 어떤 서버로 보내줄 것인가를 설정한다.
nginx는 어떤 기준으로 서버를 분산할것인지에 대해 여러 알고리즘이 있는데, upstream 부분에 해당 알고리즘을 선택할 수 있다. nginx는 라운드로빈 알고리즘이 default다. (나는 따로 설정해주지않아 라운드로빈 알고리즘을 사용한다.) 
 
여기까지 nginx 설정이 끝났다. 서버가 분산돼서 잘 작동하는지를 확인하기 위해, 현재 작동중인 서버이름을 확인하는 api를 구현해보려한다.
'/current-profile' api를 통해 현재 작동중인 서버이름을 반환한다. (api를 current-profile로 한 이유는 현재 하고있는 프로젝트 기능 중 회원 프로필 기능이 있어 profile이라는 api가 있기때문에 current-profile로 지었다)

작동중인 서버 이름을 반환해주는 로직
application.yml

설정파일(yml)에 서버이름과 서버 포트 번호를 설정해주었다.
 

로드밸런싱 성공~

새로고침해서 확인해보면 서버가 분산돼서 실행되는 것을 볼 수 있다! 성공!! 
 

(구현하면서 고민했던 점)
- listen 80 이 아닌 8080으로 설정
nginx 기본값이 원래 80이다. 이렇게 했는데 서버가 분산되지 않아서 곰곰히 생각해보니 내가 http, https로 들어오는 요청은 8080으로 포트포워드를 했었다. (타겟그룹을 이용해서 포트포워드를 구현했었다)
그래서 80이 아닌 8080포트로 listen을 해야한다.
(추가로 http, https에 포트포워드를 한 이유는 스프링이 내장서버로 톰캣을 사용하는데, 톰캣은 포트번호 8080을 사용해 사용자가 우리서버로 요청할때 도메인뒤에 항상 8080을 붙여서 요청해야한다는 불편함이 있기 때문에 포트포워딩을 했었다) 
 
- 서버 IP가 아닌 포트번호를 바꿔서 
nginx에 대해 잘 정리되어있는 글들이 엄청 많았다. 근데 많은 예시들이 포트번호가 아닌 IP주소를 바꿔서 서버를 분산했다. '이 둘은 어떤 차이가 있을까?' '어떻게 구현하는것이 서버 구조 측면에서 좋을까?' 라는 고민을 많이 했었다.
그래서 여러가지 깊이 생각한 결과...
IP주소는 동일하게, 포트번호는 다르게 설정했다. 왜냐하면 나는 'WAS를 분산'하고 싶었기 때문이다.
한개의 ec2안에서 WAS만 분리하고 싶어서 스프링 톰캣 서버 포트 번호를 다르게 설정했다. 
내가 생각했을 때 IP주소를 다르게 여러 서버로 분리하는 것은 ec2처럼 퍼블릭IP가 존재하는 ec2를 분리하는 것과 비슷하다 생각했다. 만약 이 과정이 맞다면 이것은 aws에서 지원하는 ALB나 NLB를 사용하는것과 비슷하다 생각했다.
우리의 목적은 WAS의 부담을 덜어주고자 웹서버(nginx)를 설치한것이었고 더불어 WAS를 분산해주면서 무중단 배포가 가능하도록 하는것이었다. 
그리고 또 하나 중요한 것은 내 프로젝트 상황에 맞는 기술을 사용하는 것이다. 나는 aws 프리티어이기 때문에 ec2를 여러개 생성하는데 부담이 있었다. 하나의 ec2만으로도 로드밸런싱을 할 수 있는 방법은 포트번호를 다르게 하는것이라 생각했다. 
기술에는 장단점이 있다. aws프리티어는 사용할 수 있는 자원이 한정적이어서 하나의 ec2에 여러 서버를 구동하는 것이 쉽지 않다. 그래서 프리티어 입장에서 여러 서버를 켜놓으면 실행중인 서비스마저 장애를 겪을 수 있기 때문에 현실적으로는 하나의 서버 즉 하나의 WAS로만 동작을 해야할 것 같다.
 


3. 회고
보안이나 안정적인 서버 구조에 대해 생각해보고, 공부해보고, 적용해봐서 흥미롭고 신기했다.
실제 실무에서는 어떻게 서버관리를 안정적으로 하는지 궁금해졌다.
컴퓨터세상엔 신기하고 대단한 기술들이 많아 배움에 즐거움이 항상 담겨있다.
그리고 구글링하다보면 기술에 대해 잘 설명해놓은 글들이 되게 많다. 나도 언젠가 사람들에게 도움될만한 정보들을 알려주고싶다. 그러기위해서는 글 잘쓰는 노력을 해야겠다..! 
우선 지금은 정보공유 글보다는 내가 기록하고 싶은 것들 위주로 적어봐야겠다.
빠르게 변화하는 IT속에서 하루하루 성장하는 내 모습들을 담아보고자, 내가 깊이 고민했던 생각들을 하나하나 적어볼거다.
 
 
(혹시 잘못된 정보가 있다면 편하게 알려주시면 감사하겠습니다)

Comments