官方參考文檔html
pip install uwsgi uwsgi --version # 查看 uwsgi 版本
新建一個測試文件 helloworld.py
前端
def application(env, start_response): start_response('200 OK', [('Content-Type', 'text/html')]) return [b'hello world',]
uwsgi --http :9090 --wsgi-file helloworld.py
uwsgi 默認是單進程單線程啓動的python
添加多進程使用 --processes 選項, 添加多線程使用 --threads 選項nginx
uwsgi --http :9090 --wsgi-file helloworld.py --master --processes 4 --threads 2 # 表示啓動 4 個進程,每一個進程 2 個線程;一個主進程,當進程掛掉後重新生成新的進程
監測是一個重要的任務。在生產環境中知道發生了什麼是相當重要的git
stats 子系統容許你以 json 格式導出 uwsgi 的內部統計信息web
uwsgi --http :9090 --wsgi-file helloworld.py --master --processes 4 --threads 2 --stats 127.0.0.1:9091 # 添加監測,經過 127.0.0.1:9091 訪問 json 格式的統計信息 # 把 stats 綁定到一個私有地址,不然全部人均可以訪問這個統計信息 uwsgitop 一個相似 top 的監控 uwsgi 的工具 pip install uwsgitop
uwsgi可使用 HTTP, FastCGI, SCGI, uwsgi 協議,其中性能最好的是 uwsgi,nginx 支持 uwsgi 協議,apache 在添加對應的模塊後也能夠支持 uwsgi 協議apache
一個常見的 nginx 配置以下:django
location / { include uwsgi_params; uwsgi_pass 127.0.0.1:3031; } # 使用 uwsgi 協議將每一個請求轉發到綁定 3031 端口的服務器
使用 uwsgi 協議啓動 uwsgi 服務器json
uwsgi --socket 127.0.0.1:3031 --wsgi-file helloworld.py --master --processes 4 --threads 2 -stats 127.0.0.1:9191
若是你的代理前端服務器使用的是 http 協議,你必須讓 uwsgi 也使用 http 協議flask
uwsgi --http-socket 127.0.0.1:3031 --wsgi-file helloworld.py --master --processes 4 --threads 2 --stats 127.0.0.1:9091 # --http 和 --http-socket 不同,--http 自帶一個代理
在使用腳原本啓動 uwsgi 以前,看是否可使用其餘進程管理程序來啓動 uwsgi,好比:
Upstart, Systemd supervisord, god, monit, circus
uwsgi 能夠很好的與以上的進程管理器集成,若是有大量的應用須要部署,建議使用 uWSGI Emperor
假設 django 項目路徑是: /home/foobar/myproject
uwsgi --socket 127.0.0.1:3031 --chdir /home/foobar/myproject/ --wsgi-file myproject/wsgi.py --master --processes 4 --theads 2 --stats 127.0.0.1:9191
--chdir 切換到 django 的項目路徑下,這是 django 正確加載模塊所必須的
以上這個很長的命令行命令能夠寫在一個 uwsgi 的 .ini 格式的配置文件中,好比 foo.ini
[uwsgi] socket = 127.0.0.1:3031 chdir = /home/foobar/myproject/ wsgi-file = myproject/wsgi.py processes = 4 threads = 2 stats = 127.0.0.1:9191
使用配置文件啓動
uwsgi foo.ini
若是使用的是舊版本的django(< 1.4),須要多加一下配置
uwsgi --socket 127.0.0.1:3031 --chdir /home/foobar/myproject/ --pythonpath .. --env DJANGO_SETTINGS_MODULE=myproject.settings --module "django.core.handlers.wsgi:WSGIHandler()" --processes 4 --threads 2 --stats 127.0.0.1:9191
[uwsgi] socket = 127.0.0.1:3031 chdir = /home/foobar/myproject/ pythonpath = .. env = DJANGO_SETTINGS_MODULE=myproject.settings module = django.core.handlers.wsgi:WSGIHandler() processes = 4 threads = 2 stats = 127.0.0.1:9191
舊版本的 django(< 1.4) 須要設置 env,module, pythonpath(容許獲取到 myproject.settings 模塊)
若是沒有使用多線程啓動 uwsgi,那麼在應用裏面生成的線程不會運行
可使用 --enable-threads 選項,enable-threads = true .ini文件配置項,在不使用多線程啓動 uwsgi 時支持應用內的多線程運行
uwsgi 支持 python 虛擬環境內查找 python 模塊,只須要添加配置項 virtualenv = <path>
安全性
不要使用 root 用戶運行 uwsgi,可使用 uid 和 gid 移除特權
[uwsgi] https = :9090,foobar.crt,fooar.key uid = foo gid = bar chdir = path_to_web2py module = wsgihandler master = true processes = 8
若是要使用特權端口(如 443),可使用共享 socket
[uwsgi] shared-socket = :443 https = 0, foobar.crt, foobar.key uid = foo gid = bar chdir = path_to_web2py module = wsgihandler master = true processes = 8
能夠性
請求阻塞問題,能夠設置一個 harakiri 定時器,在指定時間後銷燬被阻塞的 worker
[uwsgi] shared-socket = :443 https = =0,foobar.crt,foobar.key uid = foo gid = bar chdir = path_to_web2py module = wsgihandler master = true processes = 8 harakiri = 30
若是一個請求阻塞了 30 秒,那麼這個 worker 會被銷燬
能夠經過 stats 子系統實時查看每一個worker,thread 或者 async 工做狀況
uwsgi offloading 子系統在特定匹配模式或可使用純C線程時,能夠很快的釋放掉 worker,好比:從文件系統發送靜態文件,從網絡發送數據等
意思是:worker把請求中的特定操做(發送文件,發送數據等)分配給其餘的進程線程,從而使得 worker 能夠被儘快釋放,處理跟多的請求
添加 --offload-threads <n>
選項啓用,(建議每一個CPU啓用 1 個線程)
最好的方法是內置一個獨立於語言的特性的二進制文件,併爲每一個Python版本提供一個按需加載的插件
編譯時使用 PROFILE=nolang
make PROFILE=nolang
編譯python 插件
PYTHON=python3.4 ./uwsgi --build-plugin "plugins/python python34" PYTHON=python2.7 ./uwsgi --build-plugin "plugins/python python27" PYTHON=python2.6 ./uwsgi --build-plugin "plugins/python python26"
會獲得3個插件:python34_plugin.so, python27_plugin.so, python26_plugin.so
將這些複製到您想要的目錄中,默認狀況下,uWSGI在當前工做目錄中搜索插件。
如今能夠在 uwsgi 配置文件中使用這些插件,添加在最頂端
[uwsgi] plugins-dir = <path_to_your_plugin_directory> plugin = python26
2019-2-20 by achxku@163.com