nginx는 웹 서버이고, gunicorn은 WAS(Web Application Server)에 속한다.
웹 서버는 단순히 정적 파일을 응답하는 존재이고, WAS는 동적인 처리를 수행하는 존재이다.
웹 서버를 별도로 운영하는 이유는 WAS의 부담을 줄여주기 위함이다.
이미지, html, css 등 웹 사이트 운영에 필요한 변하지 않는 파일들까지 WAS에서 처리하지 않고, 웹 서버가 처리함으로써, WAS의 부담을 줄여준다.
빠른 속도
동시 요청이 많아도 메모리 사용량이 현저히 적다.
리버스 프록시(Reverse proxy)로 사용 가능
리버스 프록시란 인터넷과 백엔드 사이에 있는 서버를 가리킴.
여러 WAS가 존재하면 클라이언트 요청을 분산시키는 역할을 수행 -> 로드 밸런싱
캐싱 가능 (WAS까지 요청하지 않아도 클라이언트 요청에 빠르게 응답)
민감한 WAS 정보(기기 id, MAC 주소 등)를 숨기는 보안 역할 수행
SSL 지원
HTTPS의 인증서 제공
웹 페이지 접근 인증
로그인 정보(관리자, 사용자)를 WAS에서 하지 않고 nginx에서도 가능
압축
gzip을 사용하여 클라이언트가 보낸 텍스트 파일을 압축
비동기 처리
Event loop 기반으로 상당히 많은 트래픽을 동시에 처리 가능
gunicorn은 WSGI의 일종이다.
WSGI(Web Server Gateway Interface)는 CGI(Common Gateway Interface)의 일종으로 공통적인 형태(HTTP 형식)로 주고 받기 위해 만든 규약이다.
WSGI는 파이썬 앱이 웹 서버와 효율적으로 통신하기 위해 만들어진 인터페이스로써, gunicorn이나 uWSGI 등은 nginx로 들어오는 HTTP 요청을 파이썬이 이해할 수 있게 바꿔준다.
기본 flask 서버는 개발용이고, 배포용으로 적합하지 않다고 한다.
flask를 단독으로 실행하면 단일 프로세스가 생성되고 한개의 프로세스가 여러 Request 요청을 처리하게 된다.
즉, Request 요청이 많아지면 서버에 병목이 생기게 된다.
gunicorn과 같은 WSGI는 여러 개의 쓰레드를 생성하여 요청을 병렬로 처리해주기 때문에 기본 flask 서버를 사용할 때보다 성능이 뛰어나다.
uWSGI 또한 python에서 사용하는 대표적인 WSGI이지만, gunicorn이 더 가볍고 성능이 좋다고 한다.
결론은 gunicorn 또는 nginx 둘 중 하나만 써도 상관없다.
import os
import binascii
random_number = os.urandom(24)
random_hex = binascii.hexlify(random_number)
print(random_hex)
sudo apt-get install nginx gunicorn
# app.py
from flask import Flask
app = Flask(__name__)
@app.route("/")
def index():
return "hello world"
if __name__ == "__main__":
app.run()
app:app
은 (MODULE_NAME):(VARIABLE_NAME)
을 의미한다.app.py
파일명을 의미하고, 뒤쪽 app은 Flask app의 변수명이다.gunicorn3 --bind 0.0.0.0:8000 app:app &
gunicorn3 --bind unix:/home/somnode/flaskapp/gunicorn.sock app:app &
# /etc/systemd/system/flaskapp.service
[Unit]
Description=gunicorn daemon
After=network.target
[Service]
User=root
Group=root
WorkingDirectory=/home/somnode/flaskapp
ExecStart=/usr/bin/gunicorn3 \
--workers 5 \
--bind unix:/home/somnode/flaskapp/gunicorn.sock \
--access-logfile /home/somnode/flaskapp/access.log \
--error-logfile /home/somnode/flaskapp/error.log \
app:app &
[Install]
WantedBy=multi-user.target
flaskapp
은 아까 리눅스 서비스 생성 시 파일명이다.
sudo systemctl daemon-reload
sudo systemctl enable flaskapp
sudo systemctl start flaskapp
sudo systemctl status flaskapp
flaskapp.com
, www.flaskapp.com
)# /etc/nginx/conf.d/flaskapp.conf
server {
listen 80;
listen [::]:80;
server_name flaskapp.com www.flaskapp.com;
location / {
proxy_pass http://unix:/home/somnode/flaskapp/gunicorn.sock;
}
}
# /etc/nginx/conf.d/flaskapp.conf
server {
listen 5000;
listen [::]:5000;
server_name _;
location / {
proxy_pass http://unix:/home/somnode/flaskapp/gunicorn.sock;
}
}
sudo systemctl restart nginx flaskapp
/etc/nginx/sites-enabled/default
에서 listen 부분의 80을 8080 등 다른 번호로 수정하면 된다./
디렉터리)부터 권한이 맞는지 확인한다.namei -m /home/somnode/flaskapp/gunicorn.sock
drwx------
이렇게 group과 other에서 rx 권한이 없다면, 해당 경로를 아래와 같이 권한을 부여한다.chmod 755 /home/somnode/