Nginx는 일단 SSL을 이용하기위해 사용했던게 첫 만남이었다.
nginx의 어떠한 기능을 기대한다거나 무언가를 알고 사용을 했다기 보다는
certbot으로 빠르게 임시 SSL을 적용시키고 HTTPS를 적용시켜 프론트의 버셀에 대응하기위해 사용했다.
그렇게 시간이 지나 지금 진행하는 프로젝트에서 서버를 분산시키고 서버간의 네트워크를 형성하는 과정을
다루다보니 Nginx라는것이 많은 기능을 내포하고있다는것을 비로소 알게되기시작하였다.
항상 느끼는거지만 멍청하게 남들 쓰니까 따라쓰는게아니라 적절한 상황에 나의 필요로 의해서 nginx를 꺼내어 사용할 수 있게 간단하게 revers proxy 를 정리하고 가보기로 하였다.
nginx를 우분투에 설치하고 설정파일을 파고들어가보면
위와같이 80포트를 default로 listen 하고 있다가 들어온 요청을 적절한 경로로(위 사진에서는 location/ 내부의 proxy_pass 경로 .. ex) 127.0.0.1:3000)
proxy_pass 를 해줌으로써 proxy라는 이름처럼 클라이언트의 요청을 대신 받아 내부 서버로 전달해주는것을 Reverse Proxy 라고 한다.
일단 뒤에 숨겨둔 서버에게 nginx가 대신 클라이언트의 요청을 받아서 전달해주는건 알겠는데
이렇게 하면 어떤 장점이 있을까?
이번 프로젝트를 진행하면서 LoadBalancer를 사용해야할 상황이 생겼는데 그 과정에서 찾다보니
nginx의 reverse_proxy기능을 이용하여 로드밸런싱이 가능하다는 사실을 알게되었다.
upstream powersexy {
server powersexy-server1.com;
server powersexy-server2.com;
server powersexy-server3.com;
}
위 코드를 보면 upstream 바로뒤에 현재 가용가능한 서버집합의 명칭을 설정해주고 (powersexy) 그 안에
분배해줄 서버들을 명시해둘수있다.
이것은 이후에 server 블록범위 내 proxy_pass 에서 참조할수있게된다.
이렇게 기본적인 설정만 해두고 작동시키면 nginx는 기본적으로 Round-robin 방식 알고리즘으로 3개의 서버를 돌아가며 request를 전달해주게된다.
nginx 에는 loadbalancing 알고리즘이 라운드로빈 이외에도 여러가지 존재한다.
■ hash <key>: 바로 뒤에 따라오는 값에 따라 해싱하여 분배한다. hash $remote_addr; 같은 방식으로 쓸 수 있다.
■ ip_hash: 아이피 해시 값에 따라 분배한다. weight를 고려한다.
■ random : 랜덤으로 분배한다. 하지만 weight(가중치)가 있을경우 weight를 고려한다.
■ least_conn: 가장 활성 연결 수가 적은 곳을 선택한다. weight를 고려한다.
■ least_time: 평균 연결시간이 가장 짧으며 활성 연결 수가 적은 곳을 선택한다. weight 고려한다.
또한 각 서버마다 적용할수있는 여러 parameter들이 존재하고 그 기능들을 하나씩 필요에의해 적용시킬수있다.
■ backup
server powersexy-server3.com backup;
backup 파라미터는 해당 서버를 백업 서버로 지정한다. 주요 서버에 장애가 생기면 그때서야 요청이 전달된다.
■ weight=<number>
upstream powersexy {
server powersexy-server1.com weight=3;
server powersexy-server2.com;
server powersexy-server3.com backup;
}
서버의 가중치를 설정한다. 예시 코드에서 powersexy-server1.com은 powersexy-server2.com보다
3배 많은 요청을 분배받게 된다. (powersexy-server3.com은 백업 서버이므로)
■ max_conns=<number>
upstream powersexy {
server powersexy-server1.com weight=3 max_conns=256;
server powersexy-server2.com;
server powersexy-server3.com backup;
}
nginx의 각 worker별로 동시 연결수를 설정한다. 기본값은 0이며, 제한이 없음을 의미한다.
■ max_fails=<number>
server powersexy-server1.com max_fails=3;
설정한 수 만큼 요청이 실패할 경우 다른 서버에게 요청이 넘어간다.
■ fail_timeout=<time(sec)>
server powersexy-server1.com max_fails=3 fail_timeout=30;
설정한 시간동안 서버가 응답하지 못하면 실패로 간주한다.
위와같은 다양한 알고리즘들을 적절히 분배하여 적용시킬수있게된다.
예제 코드를 이용하여 적용되었을 경우를 확인해보자.
upstream powersexy {
ip_hash; # <least_time>
server powersexy-server1.com weight=3;
server powersexy-server2.com;
server powersexy-server3.com backup
}
server {
listen 80;
location / {
proxy_pass http://powersexy;
}
}
위와 같이 upstream 으로 powersexy라는 명칭을 정의해주고
server블록에서는 powersexy를 참조하게하여 해당 집합체안에 있는 서버로 로드밸런싱을 하게된다.
진입시에 ip_hash 옵션으로인해 단시간에 같은 ip로 들어오는 요청은 최초 연결된 서버로 지속적으로 접속시키게될것이다. 이때 weight를 고려하여 접속시키게된다.
1번 파워섹시서버에서는 다른서버에비해 3배의 가중치를 얻게될것이다.
3번 파워섹시서버는 백업서버로 지정이되어있다. 다른 서버들이 장애가 발생하여 아파할때
3번 파워섹시서버가 발동하기시작한다.
이러한 nginx의 기능들을 사용하여 우리의 파워섹시서버를 적절하게 로드밸런싱하여 운용할수있게된다.
위에서 보다보면 감이오겠지만 reverse proxy를 사용하면 클라이언트의 요청을 대신 받아 넘겨주므로
server를 쌩으로 노출시킬 필요가 없어진다.
즉 클라이언트와 서버 IP를 모두 숨길수있게되고 앞단에 프록시 서버만 세워두게 되는것으로 해킹에 어느정도는 대비 할 수 있다.
이부분은 다른 글에서 더 디테일하게 작성하도록 해보겠다.
위으 로드밸런싱 기능을 봐서 알겠지만 여기에 더해
nginx의 캐시설정을 적절히 활용하여 더욱더 빠르게 응답을 꺼내서 보내줄수도있다.
nginx의 캐시도 별도로 1-2 보안과 같이 더 디테일하게 정리해서 게시해보겠다.
그럼 다음에는 더 디테일한 내용으로 정리를 해보도록하자.