これは、なにをしたくて書いたもの?
前に、uWSGIについてエントリを書きました。
今回は、同じくWSGIサーバーであるGunicornを試してみたいと思います。
Gunicorn - Python WSGI HTTP Server for UNIX
Gunicorn
Gunicornは、UNIX向けのPython WSGI HTTPサーバーです。
Gunicorn - WSGI server — Gunicorn 19.9.0 documentation
名前から想像できるかもしれませんが、RubyのUnicornから移植された、Preforkワーカーモデルのサーバーです。
いろいろなWebフレームワークと互換性があり、シンプルな実装のためリソース消費も少ないのが特徴だそうです。
確かに、uWSGIと比べるとドキュメントの量もぐっと少なくなります。
Python 2.6以上、Python 3.2以上に対応しているようです。
今回は、uWSGIで作成したソースコードを使って、Gunicorn上で動かすお題でやってみようと思います。
環境
今回の環境は、こちら。
$ python3 -V Python 3.6.7
Gunicornをインストールする
まずは、Gunicornをインストールします。
Installation — Gunicorn 19.9.0 documentation
とりあえず、仮想環境を作成して
$ python3 -m venv venv $ . venv/bin/activate
Gunicornをインストール。
$ pip3 install gunicorn
バージョン。
$ pip3 freeze gunicorn==19.9.0
uWSGIの時に作った、簡単なWSGIアプリケーション。
simple-wsgi-app.py
def application(env, start_response): start_response('200 OK', [('Content-Type', 'text/plain')]) return [b'Hello WSGI!!']
こちらを、Gunicornで動かしてみます。
Running Gunicorn — Gunicorn 19.9.0 documentation
以下のような指定になるようです。
$ gunicorn simple-wsgi-app:application
構文的には以下で、「APP_MODULE」は「$(MODULE_NAME):$(VARIABLE_NAME)」で表現されます。
$ gunicorn [OPTIONS] APP_MODULE
「MODULE_NAME」がファイル名(.py除く)で、「VARIABLE_NAME」がWSGIで呼び出し可能なポイントの名前ですね。
デフォルトで8000ポートでリッスンしますが、ポート(バインドアドレス)を指定する場合は以下のようになります。
$ gunicorn -b :8000 simple-wsgi-app:application
設定項目は、こちら。
Settings — Gunicorn 19.9.0 documentation
確認。
$ curl -i localhost:8000 HTTP/1.1 200 OK Server: gunicorn/19.9.0 Date: Sat, 13 Apr 2019 16:13:23 GMT Connection: close Transfer-Encoding: chunked Content-Type: text/plain Hello WSGI!!
ここで、uWSGIの時と同じように、Gunicornが利用するプロセス数、スレッド数を増やしてみましょう。
まず、デフォルトの状態だと以下のようになっています。
$ ps aux -L | grep gunicorn | grep -v grep xxxxx 5473 5473 0.1 1 0.1 69352 22468 pts/4 S+ 01:13 0:00 /path/to/venv/bin/gunicorn simple-wsgi-app:application xxxxx 5477 5477 0.0 1 0.1 78064 19868 pts/4 S+ 01:13 0:00 /path/to/venv/bin/python3 /path/to/venv/bin/gunicorn simple-wsgi-app:application
デフォルトで、ワーカー数(プロセス数)が1、スレッド数が1だからです。
起動時の表示は、こんな感じでした。
[2019-04-14 01:13:10 +0900] [5473] [INFO] Using worker: sync [2019-04-14 01:13:10 +0900] [5477] [INFO] Booting worker with pid: 5477
ワーカー数を4、スレッド数を2にしてみましょう。
$ gunicorn --workers 4 --threads 2 simple-wsgi-app:application
起動時の表示が、このようになります。
[2019-04-14 01:17:07 +0900] [5647] [INFO] Using worker: threads [2019-04-14 01:17:07 +0900] [5650] [INFO] Booting worker with pid: 5650 [2019-04-14 01:17:07 +0900] [5651] [INFO] Booting worker with pid: 5651 [2019-04-14 01:17:07 +0900] [5652] [INFO] Booting worker with pid: 5652 [2019-04-14 01:17:07 +0900] [5653] [INFO] Booting worker with pid: 5653
この時点だと、プロセス数が増えただけですね。
$ ps aux -L | grep gunicorn | grep -v grep xxxxx 5647 5647 0.1 1 0.1 74956 24004 pts/4 S+ 01:17 0:00 /path/to/venv/bin/python3 /path/to/venv/bin/gunicorn --workers 4 --threads 2 simple-wsgi-app:application xxxxx 5650 5650 0.0 1 0.1 83544 21180 pts/4 S+ 01:17 0:00 /path/to/venv/bin/python3 /path/to/venv/bin/gunicorn --workers 4 --threads 2 simple-wsgi-app:application xxxxx 5651 5651 0.0 1 0.1 83548 21052 pts/4 S+ 01:17 0:00 /path/to/venv/bin/python3 /path/to/venv/bin/gunicorn --workers 4 --threads 2 simple-wsgi-app:application xxxxx 5652 5652 0.0 1 0.1 83548 21052 pts/4 S+ 01:17 0:00 /path/to/venv/bin/python3 /path/to/venv/bin/gunicorn --workers 4 --threads 2 simple-wsgi-app:application xxxxx 5653 5653 0.0 1 0.1 83552 21052 pts/4 S+ 01:17 0:00 /path/to/venv/bin/python3 /path/to/venv/bin/gunicorn --workers 4 --threads 2 simple-wsgi-app:application
スレッドが増えることは、どうやったら確認できるんでしょうね。負荷をかけたらいいのかな?
Djangoで作ったアプリケーションをGunicornで動かしてみる。
続いては、Djangoで作ったアプリケーションを動かしてみます。
Djangoで作ったアプリケーションのデプロイ方法は、ドキュメントに記載があります。
アプリケーションは、uWSGIのエントリで作成したものを使用します。
$ pip3 install Django $ pip3 freeze Django==2.2 ... $ django-admin startproject mysite $ cd mysite $ django-admin startapp myapp $ cd mysite
URL設定とViewのコードだけ、再度記載しておきます。
myapp/urls.py
from django.urls import path from . import views urlpatterns = [ path('', views.index, name = 'index'), ]
myapp/views.py
from django.shortcuts import render from django.http import HttpResponse # Create your views here. def index(request): return HttpResponse('Hello Django!!')
プロジェクトディレクトリ配下にwsgi.pyがあるので、以下のように指定します。
$ gunicorn mysite.wsgi
この場合、ディレクトリのセパレーターが「.」に…?
これで、Djangoアプリケーションが起動します。
確認。
$ curl -i localhost:8000/myapp/ HTTP/1.1 200 OK Server: gunicorn/19.9.0 Date: Sat, 13 Apr 2019 16:24:42 GMT Connection: close Content-Type: text/html; charset=utf-8 X-Frame-Options: SAMEORIGIN Content-Length: 14 Hello Django!!
動きましたね。とりあえず、uWSGIと同じところまでは確認できましたよ、と。