django celery的分佈式異步之路(二) 高併發

當你跑通了前面一個demo,博客地址:http://www.cnblogs.com/kangoroo/p/7299920.html,那麼你的分佈式異步之旅已經起步了。html

性能和穩定性是web服務的核心評價指標。下面咱們來講,怎麼樣部署服務,實現web服務的高併發和高可用。python

咱們將經過一些工具和部署,提高web服務的性能。nginx

 

這篇文章咱們先講高併發web

部署方式:nginx+gunicorn+wsgi算法

 

一、django和python的缺陷分析django

django做爲一個python實現的web服務器,它的性能實際上是沒有多大保證的。這是由於python的線程是不能共享機器資源的(由於萬惡的GIL),線程們只是經過頻繁切換控制權,來分享一個core上的時間片,讓你看起來是併發在跑,可是其實同一個時間只有一個線程在跑。那python是否是在自欺欺人?不是的。看你程序的類型:編程

1)IO密集型api

IO密集型程序的耗時基本都在打開文件/打開句柄進行讀寫,也就是消耗在IO上。這種類型的程序,當線程阻塞在IO上時,交出線程控制權,給其餘線程運行,當IO完成後再得到控制權繼續跑,這樣的話,能夠在IO的時候跑其餘的線程,實際上是能夠提升代碼運行效率的。緩存

2)計算密集型服務器

你的程序基本就沒有IO,而是在跑一個算法。那麼對不起,這種類型的程序,你經過python多線程編程沒法提高效率,甚至會再頻繁切換線程控制權時,損失效率。

3)協線程greenlet

python的這種類型的線程(咱們姑且叫他線程),只在IO阻塞的狀況下進行線程控制權的切換。而gevent就是協線程的一個實現。

 

二、gunicorn部署

 1)安裝gunicorn,並安裝協線程的支持

$ pip install gunicorn
$ pip install greenlet  # Required for both
$ pip install eventlet  # For eventlet workers
$ pip install gevent    # For gevent workers

2)改造你的django工程,讓他變成一個wsgi應用

在工程的settings.py中INSTALLED_APPS中加入gunicorn

INSTALLED_APPS = (
   ...'djcelery',
    'kombu.transport.django',
    'gunicorn',
)

而後你就能夠這樣啓動了

nohup gunicorn --worker-class=gevent dmonitor.wsgi:application -b 0.0.0.0:8009 -w 4 &

打印以下,你使用了gevent的異步方式綁定本機8009端口啓動了4個進程(實際上是5個,後面再說)

[2017-08-28 17:05:16 +0000] [24913] [INFO] Starting gunicorn 19.7.1
[2017-08-28 17:05:16 +0000] [24913] [INFO] Listening at: http://0.0.0.0:8009 (24913)
[2017-08-28 17:05:16 +0000] [24913] [INFO] Using worker: gevent
[2017-08-28 17:05:16 +0000] [24939] [INFO] Booting worker with pid: 24939
[2017-08-28 17:05:16 +0000] [24940] [INFO] Booting worker with pid: 24940
[2017-08-28 17:05:16 +0000] [24941] [INFO] Booting worker with pid: 24941
[2017-08-28 17:05:16 +0000] [24942] [INFO] Booting worker with pid: 24942

先簡單說明一下:

--worker-class:指定了異步方式,使用的是gevent方式實現的異步,也就是每一個worker(進程)中線程以前切換使用的是協線程切換。

dmonitor.wsgi:application:dmonitor是django工程的名稱,你的django工程中要有wsgi.py文件。

-b:你的進程服務綁定哪一個ip和端口

-w:啓動幾個worker

其實這樣你就部署完了!

 

介紹一下gunicorn

1)主從結構

gunicorn實際上是個pre-fork的主從結構:一個master進程管理着多個worker進程,以前咱們起了4個進程,可是實際上有5個就是由於有一個是master進程。

master進程不對外提供api,只是進行集羣的管理,核心就是探活,一旦發現有worker進程掛掉了,那麼master會把它拉起來。

2)worker數量的選擇

官方給出的公式是worker_num = (2 $num_cores) 1,num_cores是機器核數。

官方又說了,通常配置的數量是4-12個,就可以支持上萬QPS。固然前提是你的web服務能處理的過來。

3)配置說明

懶得翻譯了,請看這裏

 

四、nginx部署

在說nginx部署以前,先說一些廢話。

可能你們有個疑問,gunicorn和nginx有啥區別?或者說我使用了gunicorn已經啓動了多個實例,而且進行了負載均衡,我爲何要須要nginx呢?

通常來講是須要nginx的,緣由有這幾點:

1)你的服務有沒有靜態文件?

2)你需不須要作灰度,需不須要攔截功能等等等?

3)你能保證你的服務能抗的住高峯壓力?

nginx的強大能讓你擁有上述的能力。固然nginx做爲一個已經在無數生產環境中驗證過的web容器,仍是很省心的。

回到這個系列,咱們是想解決高併發異步場景,那麼對高併發使用nginx有什麼好處呢?

nginx能夠作爲一個緩衝器,nginx在接收完request以後,纔開始轉發,若是nginx後面的服務疲於相應,nginx就會緩存request,等待空閒來到再進行轉發。這樣提升了系統的彈性。

部署nginx其實並無什麼區別,由於經過gunicorn啓動的服務對外也只有一個ip:port

注意:咱們這裏是把靜態文件直接經過nginx進行轉發的,而不是經過web服務的模板引擎。這充分利用了nginx的高性能。

nginx配置文件

upstream dmonitor {
        server 10.93.84.53:8009;
}
server {
        listen   8080;

        server_name 10.93.84.53;
        access_log  /var/log/nginx/dmonitor.log;

        location / {
                proxy_pass http://dmonitor;
                proxy_set_header Host $host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }

        location /static/ {
                #靜態文件目錄
                root /home/.../static; 
        }            

熱加載配置文件你只須要執行以下命令

./nginx -s reload
相關文章
相關標籤/搜索