http&server

02. flask + gunicorn + docker 조합

식피두 2020. 7. 29. 11:14

파이썬을 이용해서 웹 애플리케이션 서버를 작성할 때,

flask 만큼 쉬운게 없다고 생각한다.

 

회사에서도 간단한 WAS를 작성할 때 flask를 사용하고 있다.

 

flask 관련해서 기억하고 싶은 것들 몇 가지를 정리해본다.

 

Flask 와 Gunicorn, 그리고 Docker 같이 쓰기

플라스크는 내부적으로 Blocking 작업이 있을 경우,

 

A가 API 작업에 요청을 보내고

B가 동일 API에 요청을 해도, A가 다 처리 될 때 까지 기다린다.

 

따라서 flask 앱 내부에서 IO(request, file) 작업을 할 때 주의 해야한다.

 

플라스크 앱은 기본적으로 synchronous 하다.

 

하지만,  이 부분에서 gunicorn을 통해 여러 워커를 띄워 

워커 개수 만큼의 요청을 동시에 처리하게 할 수 있다.

 

https://gunicorn.org/

 

Gunicorn - Python WSGI HTTP Server for UNIX

Deployment Gunicorn is a WSGI HTTP server. It is best to use Gunicorn behind an HTTP proxy server. We strongly advise you to use nginx. Here's an example to help you get started with using nginx: server { listen 80; server_name example.org; access_log /var

gunicorn.org

gunicorn으로 띄운 플라스크 애플리케이션은 supervisor라는 것을 이용해서

node의 forever / pm2 처럼 프로세스 관리가 가능한데, 

 

나는 supervisor 말고,
docker 컨테이너로 foreground로 실행된 gunicorn을 감싸서 다루는 것을 더 선호한다. (restart 옵션을 추가해서)

 

그래도 혹시나 필요한 경우엔 이전에 정리해 두었던 것을 참고하자...

https://github.com/AI-Trolls/Web-related-topics

 

AI-Trolls/Web-related-topics

웹서버(nginx), WAS(flask), CGI 등 웹관련 정리. Contribute to AI-Trolls/Web-related-topics development by creating an account on GitHub.

github.com

 

gunicorn 실행 예시

gunicorn app:app -b 0.0.0.0:33333 \
	--log-level info \
	--access-logfile ./access.log \
	--error-logfile ./error.log
gunicorn app:app -b 0.0.0.0:24422 \
	--log-level debug \
       	-w 1 --daemon \
        --timeout 120 \
        --graceful-timeout 60
# Dockerfile with tensorflow cpu support on python3, opencv3.3
FROM python:3.7-slim-buster
MAINTAINER Jein Song <jeinsong200@gmail.com>

# The code below is all based off the repos made by https://github.com/janza/
ENV LC_ALL C.UTF-8
ENV LANG C.UTF-8

COPY extractor /root/extractor

RUN apt-get update

# Core linux dependencies. 
RUN apt-get install -y \
    build-essential \
    cmake \
    unzip

# Python dependencies
RUN pip3 --no-cache-dir install \
    ujson \
    numpy \
    python-dateutil \
    requests \
    flask \
    flask_cors \
    gunicorn

# logging path mount
# volume ["/root/extractor/logfile", "/root/extractor"]

# Gunicorn
WORKDIR /root/extractor
CMD ["gunicorn", "app:app", "-b", "0.0.0.0:23322", "--timeout", "300"] 

EXPOSE 23322

 

flask-gunicorn 활용 참고자료 (배포, 로깅, 백로그;큐)

https://medium.com/ymedialabs-innovation/deploy-flask-app-with-nginx-using-gunicorn-and-supervisor-d7a93aa07c18 

 

Deploy flask app with nginx using gunicorn and supervisor

In this blog, I will discuss how to set a Flask app up on an Ubuntu server.

medium.com

http://egloos.zum.com/mcchae/v/11149241

 

[Python] Flask RESTful API를 gunicorn WSGI 이용 및 supervisor 활용

지난번에 "Flask로 간단한 HTTPS REST API 제공 및 테스트"에 관한 블로깅을 한 적이 있습니다. 지난번에 만들어 보았던 Flask를 실제로 서비스에 활용하는 방법을 살펴봅니다. (Kickstarting Flask on Ubuntu - S

egloos.zum.com

https://medium.com/@trstringer/logging-flask-and-gunicorn-the-manageable-way-2e6f0b8beb2f

 

Logging, Flask, and Gunicorn … the Manageable Way

This blog post has permanently moved to https://trstringer.com/logging-flask-gunicorn-the-manageable-way/.

medium.com

https://docs.gunicorn.org/en/latest/faq.html

 

FAQ — Gunicorn 20.0.4 documentation

Does Gunicorn suffer from the thundering herd problem? The thundering herd problem occurs when many sleeping request handlers, which may be either threads or processes, wake up at the same time to handle a new request. Since only one handler will receive t

docs.gunicorn.org

https://docs.gunicorn.org/en/stable/settings.html#backlog

 

Settings — Gunicorn 20.0.4 documentation

post_fork def post_fork(server, worker): pass Called just after a worker has been forked. The callable needs to accept two instance variables for the Arbiter and new Worker. post_worker_init def post_worker_init(worker): pass Called just after a worker has

docs.gunicorn.org

https://stackoverflow.com/questions/45236384/reducing-flask-gunicorn-request-queue

 

Reducing Flask/Gunicorn request queue

I have a Flask/Gunicorn endpoint which takes a few seconds to return and gets hit pretty hard. Gunicorn seems to queue up a lot of requests and eventually process them all, but the requests which h...

stackoverflow.com