uwsgi, wsgi協議的一個很好的實現,源碼在這里:https://github.com/unbit/uwsgi
c語言編寫,有興趣可以研究下。
上DEMO:
wsgi_server.py
def application(env, start_response): start_response('200 OK', [('Content-Type', 'text/html')]) return 'hello world'
應用:
使用uwsgi部署以上應用:
uwsgi --http 0.0.0.0:9090 -p 4 -l 100 -M -R 100000 -z30 -L --wsgi-file wsgi_server.py --max-apps 65535 --stats 127.0.0.1:1717 --post-buffering 100M --cpu-affinity --buffer-size 65535 --daemonize /tmp/uwsgi --pidfile /tmp/uwsgi.pid --memory-report --threads 4
然后瀏覽器訪問: http://localhost:9090/ 即可。
優勢:
提高並發訪問支持(-p 進程數, --threads 線程數)
提高服務運行穩定性(--daemonize)
安裝
pip install uwsgi
pip install uwsgitop
uwsgi--uwsgi服務器
uwsgitop--uwsgi服務器性能查看工具,用法:
配合以上例子
uwsgitop 127.0.0.1:1717
參數詳細說明
官方文檔:http://uwsgi-docs.readthedocs.io/en/latest/Options.html
不錯的中文文檔:http://www.cnblogs.com/zhouej/archive/2012/03/25/2379646.html
挑幾個重點:
--wsgi-file , 指定wsgi入口文件
-p , workers個數,也是進程數, 按照慣例可默認設為核數,但是不是最優配置需要通過 uwsgitop來查看(個人覺得uwsgitop沒啥用)。
--threads , 線程數, 每個進程的線程數,進程的任務用線程的模式完成。由於用c編寫,因此不用擔心GIL的問題, 但linux上不存在線程,線程本質來講是偽進程(且存在上下文切換成本),因此不建議使用。
(用了后,再用uwsgitop監控時,可通過鍵盤的“A”鍵查看線程的資源占用情況)
--listen (-l), 內核監聽(listen)網絡隊列的長度,受文件操作系統最大的網絡連接數(net.core.somaxconn) 的限制, 長度越大意味着在高並發的環境下,丟失請求越少。
--cpu-affinity, cpu友好,即進程在運行時不切換核(切換意味着時間成本)
--stats, 監控程序的url,只有設置了這個參數以后才能用 uwsgitop 1717來觀看監控
--memory-report, 開啟內存占用報告(uwsgitop中可以看到)
--master(-M), 啟動主進程,方便管理所有進程, 可以配合--pidfie 使用。方便停止(uwsgi --stop /tmp/uwsgi.pid)/重啟uwsgi ( uwsgi --reload /tmp/uwsgi.pid)
--daemonize, 增加守護進程,使web服務更加穩定。參數為日志文件的路徑。
--disable-loggin, 不記錄請求信息的日志。只記錄錯誤以及uWSGI內部消息到日志中。
其他略,可以自己逐一嘗試。
用途
flask必需搭配使用咯。
django建議使用,默認支持,有默認的wsgi.py文件生成。
1. flask
uwsgi -s /tmp/uwsgi.sock --manage-script-name --mount /=xxx_project:app --http 0.0.0.0:9091
xxx_project換為具體的項目文件頂層文件夾。
2. django
django官方介紹。
即
uwsgi --chdir=/path/to/project/site_app --module=site_app.wsgi:application --env DJANGO_SETTINGS_MODULE=site_app.settings
uwsgi官方介紹:http://uwsgi-docs.readthedocs.io/en/latest/tutorials/Django_and_nginx.html#test-your-django-project。
即
uwsgi --http :8000 --module web_app.wsgi
相對來說后者簡單粗暴。
進一步的並發提升
+nginx,
為啥呢?看這里:http://www.oschina.net/translate/serving-python-web-applications?lang=eng
即:
I was pretty proud when we got API response times down to 40ms on average. When I say API I’m only talking about the time it takes from it hitting the Python server, to the server returning it’s response to the proxy.
Unfortunately, it quickly became apparent that there were capacity issues when we started getting more traffic for larger spikes. We’d hit bumpy response times that were no longer consistent, but we still had about 30% memory and 60% cpu to spare on the web nodes.
即:實測發現,uwsgi似乎不能充分的利用cpu和內存來達到無上限的並發。有一定瓶頸,並且到達瓶頸后,cpu和內存還剩下很多!
那為了充分利用資源不妨多開幾個uwsgi服務咯。
老外實測發現: 與其讓一個uwsgi服務跑10個進程,不如開10個uwsgi服務,然后用nginx做負載均衡!
After quite a few tweaks, what we eventually settled on was managing a larger amount of uwsgi processes, and letting nginx load balance them (vs letting uwsgi itself load balance).
What this means, is that instead of doing uwsgi –processes=10, we ran 10 separate uwsgi processes.
The result was a beautiful, consistent 20ms average response time.
當然這個有待驗證。
簡單說,就是uwsgi本身的負載均衡沒有nginx牛逼。所以閹割掉不用。
因此uwsgi退化成了wsgi服務器。
nginx 咋配置,略。
轉載請注明來自:http://www.cnblogs.com/Tommy-Yu/p/5647730.html,謝謝!