Gunicorn与uWSGI

perfork

perfork是一种服务端编程模型, Nginx, Gunicorn, uWSGI都是这种模型的实现,
简单的说perfok就是master进程启动注册一堆信号处理函数, 创建listen socket fd, fork出多个worker子进程,
子进程执行accept循环处理请求(这里简化模型, 当然也可以用select, epoll多路复用),
master进程只负责监控worker进程状态, 通过pipeline通信来控制worker进程.

perfork模型使用master进程来监控worker进程状态, 避免了我们使用supervisor来监控进程,
还支持多种信号来控制worker的数量, 使得CPU能充分得到利用, 多个worker进程监听同一端口,
可以配置reuse_port参数在worker进程间负载均衡.

Gunicorn与uWSGI都是基于perfork模型的WSGI服务器, 下面我们就来聊聊他们的区别。

Gunicorn

Gunicorn是使用Python实现的WSGI服务器, 直接提供了http服务, 并且在woker上提供了多种选择, gevent,
eventlet这些都支持, 在多worker最大化里用CPU的同时, 还可以使用协程来提供并发支撑, 对于网络IO密集的服务比较有利.

同时Gunicorn也很容易就改造成一个TCP的服务, 比如doge重写worker类, 在针对长连接的服务时, 最好开启reuse_port, 避免worker进程负载不均。

uWSGI

不同于Gunicorn, uWSGI是使用C写的, 它的socket fd创建, worker进程的启动都是使用C语言系统接口来实现的,
在worker进程处理循环中, 解析了http请求后, 使用python的C接口生成environ对象,
再把这个对象作为参数塞到暴露出来的WSGI application函数中调用. 而这一切都是在C程序中进行,
只是在处理请求的时候交给python虚拟机调用application. 完全使用C语言实现的好处是性能会好一些.

除了支持http协议, uWSGI还实现了uwsgi协议, 一般我们会在uWSGI服务器前面使用Nginx作为负载均衡,
如果使用http协议, 请求在转发到uWSGI前已经在Nginx这里解析了一遍, 转发到uWSGI又会重新解析一遍. uWSGI为了追求性能,
设计了uwsgi协议, 在Nginx解析完以后直接把解析好的结果通过uwsgi协议转发到uWSGI服务器,
uWSGI拿到请求按格式生成environ对象, 不需要重复解析请求. 如果用Nginx配合uWSGI, 最好使用uwsgi协议来转发请求.

除了是一个WSGI服务器, uWSGI还是一个开发框架, 它提供了缓存, 队列, rpc等等功能,
在github找找就会发现有人用它的缓存写了一个Django cache backend, 用它的队列实现异步任务这些东西,
但是用了这些东西技术栈也就跟uWSGI绑定在一起, 所以一般也只是把uWSGI当作WSGI服务器来用。

Nginx

使用多个进程监听同一端口就绕不开惊群这个话题, fork子进程, 子进程共享listen socket fd,
多个子进程同时accept阻塞, 在请求到达时内核会唤醒所有accept的进程, 然而只有一个进程能accept成功,
其它进程accept失败再次阻塞, 影响系统性能, 这就是惊群. Linux 2.6内核更新以后多个进程accept只有一个进程会被唤醒,
但是如果使用epoll还是会产生惊群现象.

Nginx为了解决epoll惊群问题, 使用进程间互斥锁, 只有拿到锁的进程才能把listen fd加入到epoll中, 在accept完成后再释放锁.

但是在高并发情况下, 获取锁的开销也会影响性能, 一般会建议把锁配置关掉. 直到Nginx 1.9.1更新支持了socket的SO_REUSEPORT选项, 惊群问题才算解决, listen socket fd不再是在master进程中创建, 而是每个worker进程创建一个通过SO_REUSEPORT 选项来复用端口, 内核会自行选择一个fd来唤醒, 并且有负载均衡算法.

Gunicorn与uWSGI都支持reuse_port选项, 在使用时可以通过压测来评估一下reuse_port是否能提升性能.

一般我们会在Gunicorn/uWSGI前面再加一层Nginx, 这样做的原因有一下几点:

  1. 做负载均衡
  2. 静态文件服务器
  3. 更安全
  4. 扛并发

Gunicorn与uWSGI的更多相关文章

  1. fcgi vs. gunicorn vs. uWSGI

    fcgi vs. gunicorn vs. uWSGI - Peterbe.comhttps://www.peterbe.com/plog/fcgi-vs-gunicorn-vs-uwsgi uWSG ...

  2. 部署 Flask 应用时,为什么会需要 gunicorn 或 uWSGI?

    Flask自带的wsgi性能低下 只适合你开发调试的时候用, 线上你必须用Gunicorn+Nginx才能获得更强的性能,和更高的安全性

  3. flask Gunicorn和uwsgi并发对比(转载)

    转载 结果 吞吐量(要求/秒) 响应时间(毫秒) 失误 吞吐量的标准偏差(要求/秒) 尽管uWSGI的性能在高负载下确实有些不稳定,但它看起来像Python应用服务器.uWSGI不仅速度快得离谱,而且 ...

  4. 深入理解uwsgi和gunicorn网络模型

    前言: 去年10月份建了一个python技术群,到现在为止人数已经涨到700人了.最一开始我经常在群里回应大家的问题,不管是简单还是困难的,我都会根据自己的经验来交流. 让人新奇的是一些初学者关注最多 ...

  5. nginx+gunicorn/uwsgi+python web 的前世今生

    我们在部署 flask.django 等 python web 框架时,网上最多的教程就是 nginx+gunicorn/uwsgi 的部署方式,那为什么要这么部署呢,本文就来系统地解释这个问题. 必 ...

  6. Flask + Gunicorn + Nginx 部署

    最近很多朋友都在问我关于 Flask 部署的问题,说实在的我很乐意看到和回答这样的问题,至少证明了越来越多人开始用 Flask 了. 之前我曾发表过一篇在 Ubuntu 上用 uwsgi + ngin ...

  7. django在nginx uwsgi和tornado异步方案在项目中的体验

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://rfyiamcool.blog.51cto.com/1030776/1397495 ...

  8. Python生产环境部署(fastcgi,uwsgi)

    Python部署web开发程序的几种方法 fastcgi ,通过flup模块来支持,在nginx里对应的配置指令是 fastcgi_pass http,nginx使用proxy_pass转发,这个要求 ...

  9. WSGI及gunicorn指北(一)

    作为一个Python Web 开发工程师,pyg0每天都喜滋滋的写着基于各种web框架的业务代码. 突然有一天,技术老大过来跟pyg0说,嘿,我们要新上线一个服务,你来帮我部署一下吧.不用太复杂.用g ...

随机推荐

  1. idea中@Data标签getset不起作用

    spring cloud中使用@Data标签,不用手动添加get set方法,但是如果项目中其他类中使用getset方法,如果报错,原因是idea中没有添加Lombok插件,添加上插件便可以解决.截图 ...

  2. JavaSSM框架面试

    一.Spring面试题 1.Spring 在ssm中起什么作用? Spring:轻量级框架 作用:Bean工厂,用来管理Bean的生命周期和框架集成. 两大核心: 1.IOC/DI(控制反转/依赖注入 ...

  3. CSS怎么在项目里引入自定义字体(@font-face)

    前言: 以前我一直用内置的默认字体给文字设置字体,直到一天UI妹纸给了我下面的字体    当时我是蒙蔽的,这个字体的效果如下 默认字体并无该字体,直接设置是没有效果的,这时就需要用到自定义字体了 下面 ...

  4. [Swift]LeetCode852. 山脉数组的峰顶索引 | Peak Index in a Mountain Array

    Let's call an array A a mountain if the following properties hold: A.length >= 3 There exists som ...

  5. python 抓取糗事百科糗图

    1 首先看下要抓取的页面 这是糗事百科里面的糗图页面,每一页里面有很多的图片,我们要做的就是把这些图片抓取下来. 2 分析网页源代码 发现源代码里面的每张图是这样储存的,所以决定使用正则匹配出图片的u ...

  6. Vue中实现一个无限加载列表

    参考 https://www.jianshu.com/p/0a3aebd63a14 一个需要判断的地方就是加载中再次触发滚动的时候,不要获取数据. <!DOCTYPE html> < ...

  7. ASP.NET Core 2.1 Web API + Identity Server 4 + Angular 6 + Angular Material 实战小项目视频

    视频简介 ASP.NET Core Web API + Angular 6的教学视频 我是后端开发人员, 前端的Angular部分讲的比较差一些, 可以直接看代码!!!! 这是一个小项目的实战视频, ...

  8. Eclipse debug Source not found

    点击打开链接最近开始慢慢转向idea开发了,但是因为旧项目是在eclipse里面.就没有在idea导入,所以旧项目就用eclipse,新项目就用idea.然而最近几天eclipse似乎不干了,每次de ...

  9. .NET Core实战项目之CMS 第九章 设计篇-白话架构设计

    前面两篇文章给大家介绍了我们实战的CMS系统的数据库设计,源码也已经上传到服务器上了.今天我们就好聊聊架构设计,在开始之前先给大家分享一下这几天我一直在听的<从零开始学架构>里面关于架构设 ...

  10. jenkins修改数据存放路径

    如果是用tomcat做容器的话,则在./bin/catalina.sh文件添加以下语句即可:export JENKINS_HOME="存放路径(需存在)" 例如: