当你跑通了前面一个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 x $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