python web开发之gunicorn 和 uWSGI 对比和配置
uWSGI是使用C写的, worker进程的启动都是使用C语言系统接口来实现的, 在worker进程处理循环中, 解析了http请求后,使用python的C接口生成environ对象, 再把这个对象作为参数,塞到暴露出来的WSGI application函数中调用,而这一切都是在C程序中进行,只是在处理请求的时候交给python虚拟机调用application,完全使用C语言实现的好处是性能会好一
关于uWSGI的定义,在上一篇文章中写了,链接:WSGI/uwsgi/uWSGI详解
python开发常见的容器就只有的uWSGI和Gunicorn,本文介绍两者的区别和配置
1. 共同点
在架构上,nginx负责动态的转发和静态文件的直接访问,gunicorn和uwsgi作为网关服务用来解析http请求,后面的flask只是个application而已,没有server的服务特征。
Gunicorn 和 uWSGI,Nginx都是基于perfork模型的WSGI服务器。(perfork是一种服务端编程模型,简单的说perfok就是master进程启动注册一堆信号处理函数, 使用master进程来监控worker进程状态, 避免了我们使用supervisor来监控进程, 还支持多种信号来控制worker的数量, 使得CPU能充分得到利用, 多个worker进程监听同一端口, 可以配置reuse_port参数在worker进程间负载均衡。)
Gunicorn与uWSGI都支持reuse_port选项, 在使用时可以通过压测来评估一下reuse_port是否能提升性能.
一般我们会在Gunicorn/uWSGI前面再加一层Nginx, 这样做的原因有一下几点:(nginx是通过多个进程轮流持锁的方式来避免epoll accept唤醒问题)
- 做负载均衡
- 静态文件服务器
- 更安全
- 高并发
2. 使用场景
gunicorn是长连接的,uwsgi要启用 –http-keepalive 模式才是长连接请求。
Gunicorn是使用Python实现的WSGI服务器, 直接提供了http服务, 并且在woker上提供了多种选择, gevent, eventlet这些都支持, 在多worker最大化里用CPU的同时, 还可以使用协程来提供并发支撑, 对于网络IO密集的服务比较有利.
在针对长连接的服务时, 最好开启reuse_port, 避免worker进程负载不均。
uWSGI是使用C写的, worker进程的启动都是使用C语言系统接口来实现的, 在worker进程处理循环中, 解析了http请求后,使用python的C接口生成environ对象, 再把这个对象作为参数,塞到暴露出来的WSGI application函数中调用,而这一切都是在C程序中进行,只是在处理请求的时候交给python虚拟机调用application,完全使用C语言实现的好处是性能会好一些。
一般在uWSGI服务器前面使用Nginx作为负载均衡,如果使用http协议,请求在转发到uWSGI前已经在Nginx这里解析了一遍,转发到uWSGI又会重新解析一遍。uWSGI为了追求性能,设计了uwsgi协议,在Nginx解析完以后直接把解析好的结果通过uwsgi协议转发到uWSGI服务器,uWSGI拿到请求按格式生成environ对象,不需要重复解析请求。如果用Nginx配合uWSGI,最好使用uwsgi协议来转发请求。
除了是一个WSGI服务器,uWSGI还是一个开发框架,它提供了缓存、队列、rpc等等功能。一般也只是把uWSGI当作WSGI服务器来用。
3.gunicorn 配置
启动方式:
gunicorn -w 3 -b 127.0.0.1:5000 app:app -k gevent
对于高并发的场景下,如果支持unix domain socket 模式,最少可以省略tcp的计算校验,这样性能有不少的提升。gunicorn wsgi相比uwsgi的协议相比,可以使传输的协议层更加的紧凑。
如果是在项目里使用,配置较为齐全的,请参考上一篇链接python之gunicorn的配置
4.uWSGI 配置
启动方式:
/usr/local/bin/uwsgi --gevent 500 --gevent-monkey-patch --http 127.0.0.1:5000 --callable app --wsgi-file app.py --http-keepalive --master
uwsgi会启动两组端口port, 一个是5000 ,一个是5300x , 端口5000是我们已知的,这个端口用来直接对外接收请求的,他在构建完一个请求协议包之后,会connect 到 5300x 端口, 平白的多消耗了一些网络io。这种模式是 rep req模型,我能想到的优点是,他避免了因为listen fd事件的到来把其他进程唤醒的问题。 也就是说,只有5000对外,5300x是真正的worker。 端口5000根据一定的算法来选择worker。 5000 和 5300x的数据交互方式是 可压缩可序列化的tcp报文,有兴趣的可以抓包看看。
如果是在项目里使用,配置较为齐全的,请参考: 链接
参考链接:
更多推荐
所有评论(0)