raspbian μ΄λ―Έμ§μμ μ΄ λ¬Έμ κ° μμ΅λλ€.
[2018-09-10 20:40:11 +0800] [21421] [CRITICAL] μμ
μ μκ° μ΄κ³Ό(pid:21699)
[2018-09-10 20:40:11 +0800] [21699] [ERROR] μμΌ μ€λ₯ μ²λ¦¬ μμ²μ
λλ€.
μμΆμ (κ°μ₯ μ΅κ·Ό νΈμΆ λ§μ§λ§):
νμΌ "/usr/lib/python3/dist-packages/gunicorn/workers/async.py", 62ν, νΈλ€
Six.reraise(*sys.exc_info())
νμΌ "/usr/lib/python3/dist-packages/gunicorn/six.py", 625ν, μ¬μμΉ
κ°μΉλ₯Ό λμ΄λ€
νμΌ "/usr/lib/python3/dist-packages/gunicorn/workers/async.py", 35ν, νΈλ€
listener_name = listener.getsockname()
OSError: [Errno 9] μλͺ»λ νμΌ μ€λͺ
μ
@leond08 ν°μΌ κ°μ¬ν©λλ€!
μ΄λ»κ² λ°μνλμ§ μ΄ν΄νκΈ° μν΄ μ‘°κΈ λ μ 보λ₯Ό μ 곡ν μ μμ΅λκΉ?
λλ gunicorn3 μ΅μ λ²μ μ μ¬μ©νκ³ μμ΅λλ€
λλ μ΄κ²μ μν΄ eventletκ³Ό geventλ₯Ό μ¬μ©νκ³ μμ΅λλ€.
λ΄ νλΌμ€ν¬ μμ© νλ‘κ·Έλ¨μ μ€ν μ€μ
λλ€ - Flask-SocketIO
μ¬μ©μκ° λ²νΌμ ν΄λ¦ν ν λ°±κ·ΈλΌμ΄λ μμ
μ μμν©λλ€.
λ΄ λ°±κ·ΈλΌμ΄λ μμ
κΈ°λ₯μ μ΄λ²€νΈλ₯Ό μμ νλ κ²μ
λλ€.
"μλ£" λ²νΌμ ν΄λ¦ν ν λ°±κ·ΈλΌμ΄λ μμ
μ΄ μ€μ§λμ΄μΌ ν©λλ€.
κ·Έλ° λ€μ λͺ¨λ μ¬μ©μμκ² λ°©μΆ λ©μμ§λ₯Ό 보λ
λλ€.
aiohttp + gunicornκ³Ό λμΌν λ¬Έμ κ° μμλλ° ctrl + cλ₯Ό ν λλ§λ€ λμΌν λ©μμ§λ₯Ό κ΄μ°°νμμμ€.
[INFO] μμΌμ λ«λ λμ μ€λ₯κ° λ°μνμ΅λλ€. [Errno 9] μλͺ»λ νμΌ μ€λͺ μ
λλ κ·Έκ²μ μ¬μμ°νμ§ μμ΅λλ€. κ·νμ μμ© νλ‘κ·Έλ¨μ΄ μμ λ¬Έμ λ₯Ό μΌμΌν€λ μΌλΆ fdλ₯Ό λ«κ³ μλ€κ³ μκ°ν©λλ€.
μ°λ¦¬λ λμΌν λ¬Έμ λ₯Ό κ²ͺκ³ μμ΅λλ€. μ μΌν λ¬Έμ λ λ컀 λΌμμ μ€νλλ 컨ν μ΄λ 8κ° μ€ 1κ°μμλ§ λ°μνλ€λ κ²μ λλ€.
μ°λ¦¬λ 9κ°μ 컨ν μ΄λ μ€ 1κ°μμ λμΌν λ¬Έμ λ₯Ό κ²½ννμ΅λλ€. docker λ° python3 λ° geventμ κ΄λ ¨λ κ² κ°μ΅λλ€.
gunicorn 20.0.4 + aiohttp 3.6.2
Gunicornμ΄ κ°λ° μλ²λ‘ μ€ν μ€μ λλ€.
gunicorn --reload app:make_app --bind localhost:5000 --worker-class aiohttp.GunicornWebWorker --workers 2 --access-logfile -
κ±°μ λͺ¨λ Ctrl+Cλ λ€μμΌλ‘ λλ©λλ€.
^C[2020-05-23 21:49:50 +0200] [38524] [INFO] Handling signal: int
Exception ignored when trying to write to the signal wakeup fd:
Exception ignored when trying to write to the signal wakeup fd:
Traceback (most recent call last):
File "/usr/lib/python3.8/asyncio/unix_events.py", line 42, in _sighandler_noop
Traceback (most recent call last):
File "/usr/lib/python3.8/asyncio/unix_events.py", line 42, in _sighandler_noop
def _sighandler_noop(signum, frame):
def _sighandler_noop(signum, frame):
OSError: [Errno 9] Bad file descriptor
OSError: [Errno 9] Bad file descriptor
[2020-05-23 21:49:50 +0200] [38526] [INFO] Worker exiting (pid: 38526)
[2020-05-23 21:49:50 +0200] [38528] [INFO] Worker exiting (pid: 38528)
[2020-05-23 21:49:50 +0200] [38524] [INFO] Shutting down: Master
μ ν리μΌμ΄μ μ΄ μμ²μ μ²λ¦¬νλμ§ μ¬λΆλ μ€μνμ§ μμ΅λλ€.
Sanic 20.3.0 μ¬μ©:
^C[2020-05-26 13:24:55 +0200] [27706] [INFO] Handling signal: int
[2020-05-26 13:24:55 +0200] [27769] [INFO] Stopping server: 27769, connections: 0
[2020-05-26 13:24:55 +0200] [27769] [INFO] Error while closing socket [Errno 9] Bad file descriptor
[2020-05-26 13:24:55 +0200] [27769] [INFO] Worker exiting (pid: 27769)
[2020-05-26 13:24:55 +0200] [27771] [INFO] Stopping server: 27771, connections: 0
[2020-05-26 13:24:55 +0200] [27771] [INFO] Error while closing socket [Errno 9] Bad file descriptor
[2020-05-26 13:24:55 +0200] [27771] [INFO] Worker exiting (pid: 27771)
[2020-05-26 13:24:55 +0200] [27706] [INFO] Shutting down: Master
λͺ¨λ Ctrl+Cμμ Gunicorn 20.0.4 + Uvicorn 0.11.5 μμ μ ν΄λμ€μ λμΌ
INFO: [12621] [gunicorn.error] Handling signal: int
INFO: [12635] [gunicorn.error] Error while closing socket [Errno 9] Bad file descriptor
INFO: [12634] [gunicorn.error] Error while closing socket [Errno 9] Bad file descriptor
INFO: [12635] [gunicorn.error] Worker exiting (pid: 12635)
INFO: [12634] [gunicorn.error] Worker exiting (pid: 12634)
INFO: [12621] [gunicorn.error] Shutting down: Master
μ μ© μκ° μμ΅λκΉ? λν μ΄λ€ λ²μ μ Pythonμ λν΄ μ΄μΌκΈ°νκ³ μμ΅λκΉ?
Ubuntu 20.04, virtualenvμμ μμ€ν μ 곡 Python 3.8.2
μμ μ ν리μΌμ΄μ : https://github.com/zgoda/newsloop-server/tree/d603a1c10c9e8be3d998f62ccc55dd73f4677115(aiohttp ν¬ν¨ ) λλ https://github.com/zgoda/newsloop-server/tree/b2a8a7f09fa98 λ΄ μ΄μ μ견μμ μ νν gunicorn νΈμΆ.
iohttpμ Sanic μ¬μ΄μ μΆλ ₯ μ°¨μ΄λ‘ μΈν΄ μμ μμ κ΄λ ¨λ λ¬Έμ κ° μλ€λ μμ¬μ΄ λλλ€.
λμΌν λ¬Έμ , Python 3.8.0
μ μ μ 19.12.2
κ·λμ½ 20.0.4
νΈμ§: μ΄κ²μ λ΄ Macμμ λ‘μ»¬λ‘ μ€νν λ λ°μνμ§λ§ Linux λ컀 λ΄μμ μ€νν λλ λ°μνμ§ μμ΅λλ€. λμμ΄ λ μ μμ΅λλ€.
μλ
νμΈμ,
μ΄ λ¬Έμ https://github.com/benoitc/gunicorn/issues/2064 λ κ°μ μ΄μ κ° μλ€κ³ μκ°ν©λλ€.
λ¬Έμ μ κ±°μ λμΌν μ€λ₯κ° μμ§λ§ gunicorn - 19.9.0μ μ¬μ©ν©λλ€.
μ λ μ΄κ²μ κ²½ννκ³ μμ΅λλ€. FastAPI + Python 3.8.5λ₯Ό μ¬μ©νλ μ΅μ Gunicorn λ° uvicorn μμ μ
uvicorn μ¬μ©μ μ€λ¨νμλ§μ(μ¦, λ΄ gunicorn ꡬμ±μμ μ΄ μ€μ μ κ±°):
worker_class = "uvicorn.workers.UvicornWorker"
μ€λ₯κ° μ¬λΌμ§λλ€.
μμμ μ€λͺ ν κ²μ²λΌ Ctrl+Cλ‘ Gunicornμ μ€μ§νκ±°λ PIDμ Graceful kill μ νΈλ₯Ό λ³΄λΌ λ λ°μν©λλ€.
[2020-09-12 11:56:37 +1000] [100390] [INFO] Starting gunicorn 20.0.4
[2020-09-12 11:56:37 +1000] [100390] [INFO] Listening at: http://0.0.0.0:6000 (100390)
[2020-09-12 11:56:37 +1000] [100390] [INFO] Using worker: uvicorn.workers.UvicornWorker
[2020-09-12 11:56:37 +1000] [100392] [INFO] Booting worker with pid: 100392
[2020-09-12 11:56:38 +1000] [100392] [INFO] Started server process [100392]
[2020-09-12 11:56:38 +1000] [100392] [INFO] Waiting for application startup.
[2020-09-12 11:56:38 +1000] [100392] [INFO] Application startup complete.
[2020-09-12 11:56:48 +1000] [100390] [INFO] Handling signal: term
[2020-09-12 11:56:48 +1000] [100392] [INFO] Shutting down
[2020-09-12 11:56:48 +1000] [100392] [INFO] Error while closing socket [Errno 9] Bad file descriptor
[2020-09-12 11:56:48 +1000] [100392] [INFO] Waiting for application shutdown.
[2020-09-12 11:56:48 +1000] [100392] [INFO] Application shutdown complete.
[2020-09-12 11:56:48 +1000] [100392] [INFO] Finished server process [100392]
[2020-09-12 11:56:48 +1000] [100392] [INFO] Worker exiting (pid: 100392)
[2020-09-12 11:56:48 +1000] [100390] [INFO] Shutting down: Master
λ¬Έμ μ μ νν 볡μ λ λ€μκ³Ό κ°μ΅λλ€.
[fots<strong i="6">@workstation</strong> testing]$ python3.8 -V
Python 3.8.5
[fots<strong i="7">@workstation</strong> testing]$ python3.8 -m venv ~/.virtualenv/testing
[fots<strong i="8">@workstation</strong> testing]$ source ~/.virtualenv/testing/bin/activate
(testing) [fots<strong i="9">@workstation</strong> testing]$ pip install fastapi gunicorn uvicorn
Collecting fastapi
Using cached fastapi-0.61.1-py3-none-any.whl (48 kB)
Collecting gunicorn
Using cached gunicorn-20.0.4-py2.py3-none-any.whl (77 kB)
Collecting uvicorn
Using cached uvicorn-0.11.8-py3-none-any.whl (43 kB)
Collecting pydantic<2.0.0,>=1.0.0
Using cached pydantic-1.6.1-cp38-cp38-manylinux2014_x86_64.whl (11.5 MB)
Collecting starlette==0.13.6
Using cached starlette-0.13.6-py3-none-any.whl (59 kB)
Requirement already satisfied: setuptools>=3.0 in /home/fots/.virtualenv/testing/lib/python3.8/site-packages (from gunicorn) (47.1.0)
Collecting h11<0.10,>=0.8
Using cached h11-0.9.0-py2.py3-none-any.whl (53 kB)
Collecting websockets==8.*
Using cached websockets-8.1-cp38-cp38-manylinux2010_x86_64.whl (78 kB)
Collecting httptools==0.1.*; sys_platform != "win32" and sys_platform != "cygwin" and platform_python_implementation != "PyPy"
Using cached httptools-0.1.1-cp38-cp38-manylinux1_x86_64.whl (227 kB)
Collecting uvloop>=0.14.0; sys_platform != "win32" and sys_platform != "cygwin" and platform_python_implementation != "PyPy"
Using cached uvloop-0.14.0-cp38-cp38-manylinux2010_x86_64.whl (4.7 MB)
Collecting click==7.*
Using cached click-7.1.2-py2.py3-none-any.whl (82 kB)
Installing collected packages: pydantic, starlette, fastapi, gunicorn, h11, websockets, httptools, uvloop, click, uvicorn
Successfully installed click-7.1.2 fastapi-0.61.1 gunicorn-20.0.4 h11-0.9.0 httptools-0.1.1 pydantic-1.6.1 starlette-0.13.6 uvicorn-0.11.8 uvloop-0.14.0 websockets-8.1
WARNING: You are using pip version 20.1.1; however, version 20.2.3 is available.
You should consider upgrading via the '/home/fots/.virtualenv/testing/bin/python3.8 -m pip install --upgrade pip' command.
(testing) [fots<strong i="10">@workstation</strong> testing]$ ls -l
total 4
-rw-rw-r-- 1 fots fots 117 Sep 12 12:13 main.py
(testing) [fots<strong i="11">@workstation</strong> testing]$ cat main.py
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def root():
return {"message": "Hello World"}
(testing) [fots<strong i="12">@workstation</strong> testing]$ gunicorn -k uvicorn.workers.UvicornWorker main:app
[2020-09-12 12:19:05 +1000] [105788] [INFO] Starting gunicorn 20.0.4
[2020-09-12 12:19:05 +1000] [105788] [INFO] Listening at: http://127.0.0.1:8000 (105788)
[2020-09-12 12:19:05 +1000] [105788] [INFO] Using worker: uvicorn.workers.UvicornWorker
[2020-09-12 12:19:05 +1000] [105790] [INFO] Booting worker with pid: 105790
[2020-09-12 12:19:05 +1000] [105790] [INFO] Started server process [105790]
[2020-09-12 12:19:05 +1000] [105790] [INFO] Waiting for application startup.
[2020-09-12 12:19:05 +1000] [105790] [INFO] Application startup complete.
^C[2020-09-12 12:19:06 +1000] [105788] [INFO] Handling signal: int
[2020-09-12 12:19:06 +1000] [105790] [INFO] Shutting down
[2020-09-12 12:19:06 +1000] [105790] [INFO] Error while closing socket [Errno 9] Bad file descriptor
[2020-09-12 12:19:06 +1000] [105790] [INFO] Waiting for application shutdown.
[2020-09-12 12:19:06 +1000] [105790] [INFO] Application shutdown complete.
[2020-09-12 12:19:06 +1000] [105790] [INFO] Finished server process [105790]
[2020-09-12 12:19:06 +1000] [105790] [INFO] Worker exiting (pid: 105790)
[2020-09-12 12:19:07 +1000] [105788] [INFO] Shutting down: Master
λ€μμ pip freeze
μΆλ ₯μ
λλ€.
click==7.1.2
fastapi==0.61.1
gunicorn==20.0.4
h11==0.9.0
httptools==0.1.1
pydantic==1.6.1
starlette==0.13.6
uvicorn==0.11.8
uvloop==0.14.0
websockets==8.1
μ΅μ μμ μ¬νμ λ°μλμ§ νμΈνκΈ° μν΄ GitHub(λ§μ€ν° λΈλμΉ)μμ uvicornκ³Ό gunicornμ μ€μΉνλ €κ³ μλνμ§λ§ λ¬Έμ κ° μ§μλμμ΅λλ€.
λμμ΄ λμκΈ°λ₯Ό λ°λλλ€
ν¬ν°μ€
gunicorn
λ° uvicorn
μ€μ μΌλ‘ μ΄ λ‘κ·Έ μ€λ₯λ₯Ό μ¬νν μ μμ΅λλ€. μ΄ μ€λ₯ λ©μμ§λ μ΄μ λ²μ 0.11.3
μλλΌ uvicorn==0.11.4
λ°μνκΈ° μμν©λλ€(OSx λ° Linux 컨ν
μ΄λ λͺ¨λμμ). μ΄λ λ³΄κ³ λ λ²μ μ΄ νμ 0.11.4
λ³΄λ€ ν° uvicornμ μ λ³΄κ³ μμ μΌμΉν©λλ€. λ§μ§λ§μ μ¦κ±°uvicorn
μ ν
μ€νΈ μ€μνΈλ₯Ό κ³μ ν΅κ³Όνλ©΄μ λ‘κ·Έ μ€λ₯κ° μ¬λΌμ§λλ€.gunicorn+uvicorn
μ€ν 맨 μμ starlette
λ° fastapi
λ₯Ό μ¬μ©ν©λλ€. - 12.X
λμ μ΅μ uvicorn λ²μ 0.11.4
; - ν λͺ
μ΄μμ uvicorn
μμ
μμ ν¨κ» gunicorn
μ€νμ¦κ±° . osxμ μ ν΄λμμ 첨λΆλ μ€ν¬λ¦½νΈ test.sh
(osxμμ ν
μ€νΈλ¨)λ₯Ό μ€νν©λλ€. Linux 컨ν
μ΄λμμ ν
μ€νΈνλ €λ©΄ μ€ν¬λ¦½νΈμ Dockerfileμ λͺ¨λ μ μ₯ν λ€μ Dockerfileμ ν€λλ₯Ό μ½μΌμμμ€. μ€ν¬λ¦½νΈ λ‘κ·Έλ 첨λΆν©λλ€.
@benoitc , uvicorn
μ μ΄ μ»€λ°μ λν΄ μ΄λ»κ² μκ°νμΈμ? λ²κ·Έκ° λ°μνλ κ² κ°λμ? λ¬Έμ λ gunicorn
μ uvicorn
μ¬μ΄μ μΈν°νμ΄μ€μ μλ κ² κ°μ΅λλ€. uvicorn
μμ μμμ μΈκΈν 컀λ°μμ λ³κ²½λ 2κ°μ μ½λ λΈλ‘ μμμ λν΄ μΈκΈν μ μμ΅λκΉ? μ΄λ κ² νλ©΄ λ€λ₯Έ κ²½μ°μλ μ΄λ° μΌμ΄ λ°μνλ μ΄μ λ₯Ό μ°Ύλ λ° λμμ΄ λ μ μμ΅λλ€. μ§κΈκΉμ§ μ΄κ²μ aiohttp
, gevent
, Flask-SocketIO
sanic
. νΈμλ₯Ό μν΄ μ€ν¬λ¦½νΈ λ‘κ·Έλ 첨λΆν©λλ€.
νμΌ _test.sh_
#!/bin/bash
python3 -m venv venv
source venv/bin/activate
pip install gunicorn==20.0.04 uvicorn==0.11.4
# create simple uvicorn app
printf "async def app(scope, receive, send):\n await send()\n" > example.py
# spin up gunicorn with 1 uvicorn worker, and then send TERM signal to gunicorn
gunicorn example:app -w 1 -k uvicorn.workers.UvicornWorker &
sleep 5 && pkill -f gunicorn
sleep 1
# you will see 1 log entry like this one:
# [XX] [YY] [INFO] Error while closing socket [Errno 9] Bad file descriptor
printf "\n\n[INFO] if you instead bump down uvicorn's version from 11.4 to 11.3 [Errno 9] goes away:\n\n"
pip install uvicorn==0.11.3
gunicorn example:app -w 1 -k uvicorn.workers.UvicornWorker &
sleep 5 && pkill -f gunicorn
νμΌ _λ컀νμΌ_
# run with:
# docker run -it $(docker build -q .)
FROM python:3.8
COPY test.sh .
RUN chmod +x /test.sh
CMD /test.sh
λλ λκ°μ λ¬Έμ κ°μμμ΅λλ€. μ¬κΈ° λ΄ κ²½μ°κ° μμ΅λλ€.
μμ½ : gunicornμ μ¬μ©νμ¬ Django dwebsocketμ λν ν μ€νΈ μμ© νλ‘κ·Έλ¨μ μ€μ νλ €κ³ ν©λλ€. websocket_clientλ₯Ό μ¬μ©νμ¬ κ²°κ³Όλ₯Ό ν μ€νΈνλ €κ³ ν λ websocketμ λ«μ ν μ΄ μ€λ₯κ° λ§€λ² λ°μν©λλ€.
νκ²½ :
λ컀 μ΄λ―Έμ§ : python:3.7
νμ΄μ¬ λ²μ : python3.7.6
gunicorn : λ²μ = 20.0.4, μμ
= gevent
Django λ²μ : Django==2.2
dwebsocket λ²μ : 0.5.12
μνΈ:
보기.py
from dwebsocket import accept_websocket
<strong i="16">@accept_websocket</strong>
def my_ws(request):
if request.is_websocket():
ws = request.websocket
while True:
msg = ws.wait(timeout=15)
if msg is None:
print('get None message')
break
else:
msg = b'echo :' + msg
ws.send(msg)
print('send ws seccess')
print('websocket close')
urls.py
from websocketInfo.views import my_ws
from django.conf.urls import url
urlpatterns = [
url(r'my_ws/$', my_ws, name='my_ws')
]
μΉ μμΌ_ν΄λΌμ΄μΈνΈ
from websocket import create_connection
ws = create_connection("ws://127.0.0.1:8080/my_ws/")
print("Sending 'Hello, World'...")
ws.send("Hello, World")
print("Receiving...")
result = ws.recv()
print(result)
ws.close()
print('ws close')
gunicorn μλ²λ₯Ό μ€ννλ commad
gunicorn MyWebsocket.wsgi -b 0.0.0.0:8000 -w 3 -k gevent
μ€λ₯ μΆλ ₯
send ws seccess
get None message
websocket close
[2021-01-13 02:43:56 +0000] [101] [ERROR] Socket error processing request.
Traceback (most recent call last):
File "/usr/local/lib/python3.7/site-packages/gunicorn/workers/base_async.py", line 65, in handle
util.reraise(*sys.exc_info())
File "/usr/local/lib/python3.7/site-packages/gunicorn/util.py", line 625, in reraise
raise value
File "/usr/local/lib/python3.7/site-packages/gunicorn/workers/base_async.py", line 55, in handle
self.handle_request(listener_name, req, client, addr)
File "/usr/local/lib/python3.7/site-packages/gunicorn/workers/ggevent.py", line 143, in handle_request
super().handle_request(listener_name, req, sock, addr)
File "/usr/local/lib/python3.7/site-packages/gunicorn/workers/base_async.py", line 128, in handle_request
util.reraise(*sys.exc_info())
File "/usr/local/lib/python3.7/site-packages/gunicorn/util.py", line 625, in reraise
raise value
File "/usr/local/lib/python3.7/site-packages/gunicorn/workers/base_async.py", line 114, in handle_request
resp.write(item)
File "/usr/local/lib/python3.7/site-packages/gunicorn/http/wsgi.py", line 326, in write
self.send_headers()
File "/usr/local/lib/python3.7/site-packages/gunicorn/http/wsgi.py", line 322, in send_headers
util.write(self.sock, util.to_bytestring(header_str, "latin-1"))
File "/usr/local/lib/python3.7/site-packages/gunicorn/util.py", line 286, in write
sock.sendall(data)
File "/usr/local/lib/python3.7/site-packages/gevent/_socket3.py", line 523, in sendall
return _socketcommon._sendall(self, data_memory, flags)
File "/usr/local/lib/python3.7/site-packages/gevent/_socketcommon.py", line 367, in _sendall
chunk_size = max(socket.getsockopt(SOL_SOCKET, SO_SNDBUF), 1024 * 1024)
File "/usr/local/lib/python3.7/site-packages/gevent/_socket3.py", line 156, in __getattr__
return getattr(self._sock, name)
File "/usr/local/lib/python3.7/site-packages/gevent/_socket3.py", line 66, in _dummy
raise OSError(EBADF, 'Bad file descriptor')
OSError: [Errno 9] Bad file descriptor
@ChrisXiaoShu κ²μν μ€ν μΆμ μ μ΄ νΉμ μμΌ κ°μ²΄κ° Python μμ€μμ λͺ
μμ μΌλ‘ λ« _dummy
λ₯Ό μ¬μ©νμ¬ μ΄μ 체μ μ λμΌν μμΈλ₯Ό μμ±ν¨). μ΄λ μ ν리μΌμ΄μ
μ€νμ μΌλΆκ° gunicornμ΄ μ²λ¦¬ν μ μλλ‘ μλ΅μ λ°ννκΈ° μ μ μμΌμ λ«κ³ μμμ μλ―Έν©λλ€. μ€λ₯κ° λ°μνλ μμ μμ gunicornμ μμ§ HTTP μλ΅ ν€λλ₯Ό 보λ΄μ§ μμμ΅λλ€.
μ΄ μ€λ₯κ° μ무 κ²λνμ§ μκ³ λ°μνλ€λ μ°¨μ΄μ κ³Ό ν¨κ» λ΄ κ²½μ°μλ λμΌν λ¬Έμ μ λλ€. λλ‘λ 5λΆ ν, λλ‘λ 2μκ° ν...
κ°μ₯ μ μ©ν λκΈ
gunicorn
λ°uvicorn
μ€μ μΌλ‘ μ΄ λ‘κ·Έ μ€λ₯λ₯Ό μ¬νν μ μμ΅λλ€. μ΄ μ€λ₯ λ©μμ§λ μ΄μ λ²μ 0.11.3
μλλΌuvicorn==0.11.4
λ°μνκΈ° μμν©λλ€(OSx λ° Linux 컨ν μ΄λ λͺ¨λμμ). μ΄λ λ³΄κ³ λ λ²μ μ΄ νμ0.11.4
λ³΄λ€ ν° uvicornμ μ λ³΄κ³ μμ μΌμΉν©λλ€. λ§μ§λ§μ μ¦κ±°uvicorn
μ ν μ€νΈ μ€μνΈλ₯Ό κ³μ ν΅κ³Όνλ©΄μ λ‘κ·Έ μ€λ₯κ° μ¬λΌμ§λλ€.gunicorn+uvicorn
μ€ν 맨 μμstarlette
λ°fastapi
λ₯Ό μ¬μ©ν©λλ€. -12.X
λμ μ΅μ uvicorn λ²μ 0.11.4
; - ν λͺ μ΄μμuvicorn
μμ μμ ν¨κ»gunicorn
μ€νμ¦κ±° . osxμ μ ν΄λμμ 첨λΆλ μ€ν¬λ¦½νΈ
test.sh
(osxμμ ν μ€νΈλ¨)λ₯Ό μ€νν©λλ€. Linux 컨ν μ΄λμμ ν μ€νΈνλ €λ©΄ μ€ν¬λ¦½νΈμ Dockerfileμ λͺ¨λ μ μ₯ν λ€μ Dockerfileμ ν€λλ₯Ό μ½μΌμμμ€. μ€ν¬λ¦½νΈ λ‘κ·Έλ 첨λΆν©λλ€.@benoitc ,
uvicorn
μ μ΄ μ»€λ°μ λν΄ μ΄λ»κ² μκ°νμΈμ? λ²κ·Έκ° λ°μνλ κ² κ°λμ? λ¬Έμ λgunicorn
μuvicorn
μ¬μ΄μ μΈν°νμ΄μ€μ μλ κ² κ°μ΅λλ€.uvicorn
μμ μμμ μΈκΈν 컀λ°μμ λ³κ²½λ 2κ°μ μ½λ λΈλ‘ μμμ λν΄ μΈκΈν μ μμ΅λκΉ? μ΄λ κ² νλ©΄ λ€λ₯Έ κ²½μ°μλ μ΄λ° μΌμ΄ λ°μνλ μ΄μ λ₯Ό μ°Ύλ λ° λμμ΄ λ μ μμ΅λλ€. μ§κΈκΉμ§ μ΄κ²μaiohttp
,gevent
,Flask-SocketIO
sanic
. νΈμλ₯Ό μν΄ μ€ν¬λ¦½νΈ λ‘κ·Έλ 첨λΆν©λλ€.log_test.log
νμΌ _test.sh_
νμΌ _λ컀νμΌ_