트래픽이 많은 웹사이트의 서버(WAS)를 도와주는 비동기 이벤트 기반구조의 경량화 웹 서버 프로그램
클라이언트로부터 요청을 받았을 때 요청에 맞는 정적 파일을 응답해주는 HTTP Web Server로 활용되기도 하고, 또는 Reverse Proxy Server로 활용하여 WAS의 부하를 줄일 수 있는 로드밸런서 역할을 하기도 함.
Nginx가 만들어진 배경
1995년 UNIX 기반으로 만들어진 NCSA HTTPd(CERN httpd 웹 서버가 먼저 나옴). 하지만 이 프로그램은 버그가 굉장히 많아서 개발자들이 사용할 때 불편함을 많이 느낌. 그래서 문제를 해결하기 위해서 만들어진 것이 바로 Apache Server. Apache 같은 경우 요청이 들어오면 connection을 생성. 그래서 새로운 클라이언트의 요청이 올 때마다 새로운 process를 생성.
그런데 프로세스를 생성하는 과정은 시간이 오래 걸리기 때문에 프로세스를 미리 만들어 놓는 PREFORK라는 방식을 이용. 그래서 새로운 클라이언트의 요청이 오면 미리 만들어놓은 프로세스를 할당. 만약 만들어놓은 프로세스가 없다면 추가로 프로세스를 생성.
이런 구조 덕분에 개발자는 다양한 모듈을 만들어서 서버에 빠르게 기능을 추가할 수 있었습니다. 즉, 확장성이 높았고, Apache Server는 동적 컨텐츠를 처리할 수 있게 됨. 확장성이 좋다는 장점은 결국 요청을 받고 응답을 처리하는 과정을 하나의 서버에서 해결하기 좋음.
하지만 1999년에 들어오면서 컴퓨터가 많이 보급됨에 따라 요청이 많아져서 서버에 동시에 연결된 connection이 많을 때 더 이상 새로운 connection을 생성하지 못하게 됨.
이를 C10K(connection 10000 problem)문제라고 하는데 connection 10000개의 문제라는 뜻 입니다. Apache Server는 구조적으로 아래와 같은 문제점이 있었음.
즉, Apache Server는 현대로 올수록 사용하기 꺼려졌고, 이러한 구조적 문제점을 해결한 Nginx가 2004년에 나왔습니다.
초창기 Nginx는 Apache와 함께 사용하기 위해 만들어짐. 웹 서버이기는 하지만 아파치 서버를 완전히 대체할 목적은 아님. 아파치 서버가 지닌 구조적 한계를 Nginx를 사용하면서 극복하려고 함.
위 이미지와 같이 수많은 동시 connection을 Nginx가 유지하고, Nginx도 웹 서버이기에 정적 파일에 대한 요청은 스스로 처리하고, 클라이언트로부터 동적 파일의 요청을 받았을 때만 아파치 서버와 connection을 형성하여 아파치 서버의 부하를 줄임.
Nginx의 구조
그렇다면 Nginx는 어떠한 구조로 되어있길래 그 많은 동시 connection을 유지할 수 있을까?
Nginx에서는 이러한 connection 형성과 제거, 그리고 새로운 요청을 처리하는 것을 이벤트(event)라고 함.
그리고 이 이벤트들은 os커널이 queue형식으로 worker process에게 전달. 이 이벤트들은 queue에 담긴 상태에서 비동기 상태로 대기. 그리고 worker process는 하나의 스레드로 이벤트를 꺼내서 처리해 나감. 이런 방식은 worker process가 쉬지 않고 일을 하기에, 요청이 없을 때 프로세스를 방치시키는 Apache Server보다 훨씬 효율적으로 자원을 사용할 수 있음.
위 이미지를 보면 알 수 있듯이 Apache 방식인 스레드 기반은 하나의 커넥션 당 하나의 스레드를 잡아먹지만 이벤트 기반 방식은 여러 개의 connection을 전부 Event Handler를 통해 비동기 방식으로 처리해 먼저 처리되는 것부터 로직이 진행.
이러한 이벤트 기반 구조가 바로 Nginx의 핵심.
Nginx의 장단점
Nginx 단점
Nginx 장점
성능 비교
위 이미지는 동시 connection 수 당 메모리 사용률을 나타냄. Apache Server에 비해 Nginx는 동시 connection 수가 늘어나도 메모리 사용률이 낮고 일정한 사실을 알 수 있음.
동시 connection 수가 많아졌을 때 처리하는 초당 요청 수는 Nginx가 Apache에 비해 압도적으로 높은 모습을 보여줌.
정리
Apache의 한계
클라이언트 접속마다 Process 혹은 Thread 를 생성하는 구조. 1만 클라이언트로부터 동시접속 요청이 들어온다면 CPU 와 메모리 사용이 증가하고 추가적인 Process/Tread 생성비용이 드는 등 대용량 요청에서 한계를 보. 또한, Apache 서버의 프로세스가 blocking 될 때 요청을 처리하지 못하고 처리가 완료될 때까지 대기상태에 있음. 이는 Keep Alive(접속대기) 로 해결이 가능하지만, 효율이 떨어짐.
Nginx 의 정리
Nginx 는 위에서 언급했듯이 Event-Driven 방식으로 동작. 즉, 프로그램 흐름이 이벤트에 의해 결정 됨. 한 개 또는 고정된 프로세스만 생성하고, 그 내부에서 비동기로 효율적인 방식으로 task 를 처리. Apache 와 달리 동시접속자 수가 많아져도 추가적인 생성비용이 들지 않음.
설치
node.js도 웹 서비스 구동이 가능하지만 보안요소와 여러 기능이 안정되고 검증된 NginX를 AWS에서 제공하는 EC2(컴퓨터 한대 빌림)안에 설치해서 사용. (내 컴퓨터에 서버를 24시간 켜 놓기도 힘들고, 고장 날 수도 있음.)
호스팅(Hosting)
서버 컴퓨터의 전체 또는 일정 공간을 이용할 수 있도록 임대해 주는 서비스
AWS 홈페이지 접속 -> 회원가입 -> Region(서비스할 지역과 가까운 지역(통신 속도 증대 위해) : 대한민국 ) -> EC2서비스 설정(운영체제만 설치된 빈 컴퓨터) ->
서버명은 web server
운영체제는 ubuntu 또는 CentOS
Ubuntu Server 20.04.LTS (HVM) 550 volumne Type
( 20버전 설치, '프리티어' 사용 시 무료 )
키 페어 설정. 원격 접속 시 키 페어 필요함. ( 로그인 시 패스워드 역할 )
aws-webserver .pem파일 (윈도우 쓰면 .ppk 내보내기 하고 불러다가 써야 함.)
키 페어 파일은 패스워드역할 잘 보관.
패스워드 선택 후
SSH는 원격 붙을 때 사용하는 통신 방법 (http 프로토콜 처럼 하나의 방식)
http는 80번 서비스 이용. SSH는 22번 서비스 오픈 하겠다는 말
이게 오픈이 되있어야 해 빌린 컴퓨터에 접근 가능. 그 다음에 NginX 설치하는 것은 웹 서비스 제공하겠다
방화벽 쪽에 HTTP 기본값이 막혀있음
허용하면 HTTP 트래픽 허용됨.
HTTPs는 사용안하지만 체크는 함.
인스턴스 시작
unbuntu20 nginX설치 검색
sudo apt update -> sudo apt upgrade -> sudo apt install nginx
public Ip 주소에 접근 해야 함
SSH가지고 어떻게 접근하는가?
mac aws ssh 접근
ssh -i pem경로 ubuntu@public ip4 주소 또는 ip4 주소
ssh -i ~/Desktop/aws-webserver.pem ubuntu@52.78.77.77
내 컴퓨터 Terminal이 아님.
서울 데이터 센터에 있는 컴퓨터에 원격 붙어서 사용하고 있는 것
그래픽 환경이 아님.
그럼 여기서 아까 본 명령어 하나 하나 입력 해서 실행함.
sudo apt update
sudo apt upgrade
sudo apt install nginx
nginx 화면까지 보이게 하는 게 목표
sudo systemctl enable nginx
public ip주소 입력
실행됨. nginx 서버가 가진 html파일 줌.
nginx 기본 경로가 etc에 있음.
nginx config 파일 수정 시
우리가 중요하게 볼 파일은
default파일이 /etc/nginx/sites-available과 연결이 되어있음.
vi default하면 뭔가 나옴
중요하게 볼게 var/www/html이게 html파일 모아놓은 기본 경로.
vi index.nginx-debian.html
서버는 Html파일 있음. 단순히 회사 소개 페이지 만들거면 Node.js가지고 만들 필요 없이
Nginx만 설치해서 회사소개 내용 꾸며 줌
Sudo vi index.nginx-debian.html ( 관리자 모드로 해야 수정 가능 )
nginx가 html 파일 준비 해놓고 준비한 파일을 클라이언트에게 제공.
이전 파일 다시 봄.
/etc/nginx/sites-available/default
index.html index.htm index.nginx-debian.html
이거는 server_name에 index.html -> index.htm -> index.nginx-debian.html
차례대로 보여줌.
ip 주소 입력했을 때 마지막 파일명만 보여줌. index.html만어떤 파일 먼저 보여줄지 결정하는 부분
index.html생성해봄
sudo vi index.html
다시 ip주소 호출 시
index.html 파일이 먼저 나옴.
mkdir board라는 폴더를 만듦.
board 폴더에 아무 파일도 없음.
그래서 ip주소/board 해도 아무것도 안 나옴.
sudo vi index.html
test 저장 시
var/www/html뒤로는 board부터는 이 url과 매칭 됨.
당연히 들어가짐. 시드니 컴퓨터가 제공하는 것. 어떤 디바이스에서 접근해도 사이트 접근 가능
그럼 간단히 NginX 설치 까지 진행 해봄. 만든 소스 코드 그냥 여기다 넣어주면 됨.
리액트로 소스코드 만들었어. 그럼 리액트 가지고 빌드 하는 과정이 있음.
빌드 한 폴더
여기다 넣으면 누가 가장 메인? index.html이 가장 메인. index.html 파일 여기다 메인 가지고 두고
여기 접근하면 만든 리액트 소스코드 index.html 받아와서 js 소스코드 받아와서 동작.
NginX에서 대표적으로 제공하는 다양한 기능이 있음
첫 번째. 설정을 안했지만 뭐가 뜨고 있는가 주의 요함
https가 아니어서
지금 우리는 http만 사용 중. 웬만한 웹 사이트는 Https 사용해야 크롬에서 이동도 잘되고 경고창도 안 뜸. 적용해야함.
그럼 이걸 알고 있어야 해. http 통신은 80번 사용. https는 443포트 번호 사용
그럼 우리는 어떻게 해야 하냐. 사용자가 https를 붙이지 않고 웹 사이트에 접근 하면
52.63.252.30에 접근했어. 그럼 이거는 지금 80 번 포트 가지고 접근
그럼 NginX에서 무슨 짓을 할 수 잇는가. 포트 포워딩 이라는 것을 할 수 있음.
개념은 맞음. 포트를 바꿔주는 거니까
NginX에서 80번 가지고 서비스가 들어오면
board파일 보여줘 가지고 설정할 수 있지만 80번으로 요청 들어오면 443페이지로 이동해줘 라고도 설정 가능
그래서 저희가 이 설정을 NginX에서 설정 가능.
저희는 지금 HttpS가 없어서 이동을 해도 이동이 안됨.
443이 없어서
둘 째. node.js 가지고 웹 서비스 개발 했다고 해봄
node.js에서 8000번 포트 가지고 구동 되고 있음
NginX에서 80번 포트가지고 접근을 하는데 80/board/list라고 요청을 보내면, 여기 있는 80번 포트를 8000가지고 바꿔서 board/list하고 요청을 보내줘
Node.js에 API가 board/list하고 구현이 되어잇으면 그럼
8000번 한테 요청을 보낼 수 있음.
그럼 또 무슨 짓을 할 수 있는가.
만약에 나중에 개발하실 때 Node.js에서 8000번 포트가지고 서비스가 구성이 되어있는데
여기에 만약에 express내에
/board/list
/board/write
/board/edit
이렇게 있는데 개발이 너무 되서 하나 하나 바꾸기는 그렇고
개발 다 해놓고 앞에 api 붙이고 싶음.
하나하나 바꾸면 버그가 발생할 수도 있음.
그럼 어떻게 할 수 있냐. 우리가 이걸 Proxy 설정이라고 함.
NginX 에서 사용자가 /api/board/list이렇게 요청을 하면
내가 NginX 가 알아서 8000 포트에 /board/list 요청을 보내게 해줄게 할 수 있음.
그러면 저희는 클라이언트에서 api 붙여서 요청 보내면
NginX가 api를 제거 하고 알아서 8000번 포트에 /board/list요청을 보내줌
이걸 저희가 프록시 설정이라고 함.
리눅스 명령어
sudo : 하나의 명령에 대해 일시적으로 root권한을 빌리는 것 ( root : 리눅스, macOS와 같은 유닉스 계열의 운영체제에서 모든 권한을 가지고 있는 최고 관리자가 사용하는 ID )
chmod : 파일 권한 변경
ls : 현재 위치에 있는 내용(디렉토리, 허가권, 소유권, 파일 등)을 확인
ls -l: 파일에 대한 정보를 길게 출력
vim 편집기 명령어
vi [파일명] : 파일 열기, 작성
unbuntu 명령어
apt : ubuntu계열에서 외부 기능 설치할 때 사용
정적 페이지(static pages)와 동적 페이지(dynamic pages)
우리가 보는 웹페이지는 위의 이미지처럼 웹 서버는 주소(url)를 가지고 통신 규칙(http)에 맞게 요청하면, 알맞은 내용(html)을 응답받음.
그러나 이처럼 단순한 클라이언트(웹 브라우저)와 웹 서버로는 정적(static)인 페이지밖에 처리하지 못한다는 한계를 가짐. 이러한 html의 태생적인 한계를 극복하기 위해 application을 활용한 것이 Web Application.
따라서 정적인 html의 한계를 극복하고 동적인 페이지를 제공하고자 하는 목적, 더 나아가 보안 강화와 장애 극복을 가능하게 만드는 것이 WAS
정적 페이지와 동적 페이지는 말 그대로 페이지가 바뀌느냐 바뀌지 않느냐의 차이
1) Static Pages
2) Dynamic Pages
Web Server와 WAS차이
1) Web Server
클라이언트로부터 HTTP 요청을 받아 HTML 문서나 각종 리소스(Resource)를 전달하는 컴퓨터
요청에 따라 아래의 두 가지 기능 중 적절하게 선택하여 수행.
기능 1
기능 2
Web Server에는 Apache Server와 NginX가 있는데 각각의 특성은 아래와 같음.
Apache Tomcat이라고 하는 이유
웹서버는 Apache, WAS는 Tomcat
2008년에 릴리즈된 Tomcat 5.5 부터 정적 컨텐츠 처리기능 추가
-> 순수 Apache를 사용하는것에 비해 성능 차이 없음
-> Tomcat이 Apache의 기능을 포함하므로 Apache Tomcat이라고함
2) Web Application Server, WAS
WAS는 웹 애플리케이션과 서버 환경을 만들어 동작시키는 기능을 제공하는 소프트웨어 미들웨어 프레임워크
위 이미지와 같이 WAS는 Web Server와 Web Container(JSP, Servlet)으로 이루어져 있음.
Web Server와의 차이점은 Web Container를 가진다는 점이며 WAS는 HTML 같은 정적인 페이지에서 처리할 수 없는 비즈니스 로직이나 DB 조회 같은 동적인 콘텐츠를 제공.
그런데 대규모 프로젝트를 보면 아래와 같이 WAS와 Web Server를 분리한 형태를 볼 수 있습니다. 분리를 하면 생기는 장점이 무엇일까요?
프록시(Proxy)
프록시의 사전적 의미는 '대리', '대신'. 보안상의 문제로 직접 통신을 주고받을 수 없는 두 PC 사이에서 통신을 할 때 직접 하지 않고 중간에서 대리로 중계를 하는 개념.
이렇게 중계 기능을 하는 것을 '프록시 서버'
Forward Proxy
클라이언트에서 서버로 리소스를 요청할 때 직접 요청하지 않고 프록시 서버를 거쳐서 요청함. 이 경우 서버에서 받는 IP는 클라이언트의 IP가 아닌 프록시 서버의 IP이기 때문에 서버는 클라이언트가 누구인지 알 수 없음. 따라서 서버에게 클라이언트가 누구인지 감춰주는 역할.
예를 들어 사용자가 google.com 에 연결하려고 하면 사용자 PC 가 직접 연결하는게 아니라 포워드 프록시 서버가 요청을 받아서 google.com 에 연결하여 그 결과를 클라이언트에 전달(forward).
포워드 프록시는 대개 캐싱 기능이 있으므로 자주 사용되는 컨텐츠라면 월등한 성능 향상을 가져올 수 있으며 정해진 사이트만 연결하게 설정하는 등 웹 사용 환경을 제한할수 있으므로 보안이 매우 중요한 기업 환경등에서 많이 사용.
Reverse Proxy
리버스 프록시는 포워드 프록시와 반대 개념. 애플리케이션 서버의 앞에 위치하며 클라이언트가 서버를 요청할 때 리버스 프록시를 호출하고 리버스 프록시가 서버로부터 응답을 전달받아 다시 클라이언트에게 전송하는 역할.
이 경우, 클라이언트는 애플리케이션 서버를 직접 호출하는 것이 아니라 서버를 통해 호출하기 때문에 리버스 프록시는 애플리케이션 서버를 감추는 역할을 하게 됨.
예를 들어 리버스 프락시로 웹 서버를 설정할 경우 사용자가 example.com 웹 서비스에 데이타를 요청하면 Reverse Proxy 는 이 요청을 받아서 내부 서버(보통 WAS 입니다)에서 데이터를 받은후에 이 데이터를 사용자에게 다시 전달하게 됨.
참고
https://kanoos-stu.tistory.com/entry/Nginx
https://dkswnkk.tistory.com/513
https://blog.slashuniverse.com/m/13