gunicorn支持不同的worker类型,同步或者异步,异步的话包括基于gevent、基于eventlet、基于Aiohttp(python版本需要大于3.3),也有多线程的版本。下面是gunicorn当前版本(19.6.0)支持的Worker类型:
  • sync
  • eventlet - Requires eventlet >= 0.9.7
  • gevent - Requires gevent >= 0.13
  • tornado - Requires tornado >= 0.2
  • gthread - Python 2 requires the futures package to be installed
  • gaiohttp - Requires Python 3.4 and aiohttp >= 0.21.5
本文主要对同步模型进行分析。同步模型实现(gunicorn.workers.sync.SyncWorker)继承自gunicorn.workers.base.Worker,绝大多数方法都是定义在基类,包括
init_signal
    注册信号处理函数
 
handle_xxx:
    各个信号具体的处理函数
 
notify:
    通知父进程自己还活着
 
run:
    需要子类实现的接口,用于处理具体的请求。
 
init_process:
    提供给Arbiter的接口,调用inti_signal和run方法
 
 
SyncWorker实现了run方法,对HTTP请求进程处理
def run(self):
if len(self.sockets) > 1:
self.run_for_multiple(timeout) # 使用select
else:
self.run_for_one(timeout) # 如果只有一个监听socket,那么阻塞accept就行了
  run方法根据监听的端口数量进行区分,如果只在一个端口监听,那么调用accept; 如果是多个端口,那么用select轮训再accept。不管哪种方式,新的连接请求到达后 都调用handle_request函数处理,源代码如下:
  

    def handle_request(self, listener, req, client, addr):
environ = {}
resp = None
try:
self.cfg.pre_request(self, req)
request_start = datetime.now()
resp, environ = wsgi.create(req, client, addr,
listener.getsockname(), self.cfg)
# Force the connection closed until someone shows
# a buffering proxy that supports Keep-Alive to
# the backend.
resp.force_close()
self.nr += 1
if self.nr >= self.max_requests:
self.log.info("Autorestarting worker after current request.")
self.alive = False
respiter = self.wsgi(environ, resp.start_response)
try:
if isinstance(respiter, environ['wsgi.file_wrapper']):
resp.write_file(respiter)
else:
for item in respiter:
resp.write(item)
resp.close()
request_time = datetime.now() - request_start
self.log.access(resp, req, environ, request_time)

  其中,调用到App的是下面这行代码

   respiter = self.wsgi(environ, resp.start_response)
 
  前面提到worker通过notify来向master进程做心跳,具体的代码在WorkerTmp.py。原理很简单:
    (1)首先通过tempfile.mkstemp创建一个临时文件
    (2)worker进程在每次轮训的时候修改该临时文件的属性
    

    def notify(self):
try:
self.spinner = (self.spinner + 1) % 2
os.fchmod(self._tmp.fileno(), self.spinner)
except AttributeError:
# python < 2.6
self._tmp.truncate(0)
os.write(self._tmp.fileno(), b"X")
    (3)master进程检查临时文件最新一次修改时间是否超过阈值
    

    def last_update(self):
return os.fstat(self._tmp.fileno()).st_ctime
references:

gunicorn syncworker 源码解析的更多相关文章

  1. gunicorn Arbiter 源码解析

    如前文所述,Arbiter是gunicorn master进程的核心.Arbiter主要负责管理worker进程,包括启动.监控.杀掉Worker进程:同时,Arbiter在某些信号发生的时候还可以热 ...

  2. 【原】Android热更新开源项目Tinker源码解析系列之三:so热更新

    本系列将从以下三个方面对Tinker进行源码解析: Android热更新开源项目Tinker源码解析系列之一:Dex热更新 Android热更新开源项目Tinker源码解析系列之二:资源文件热更新 A ...

  3. 【原】Android热更新开源项目Tinker源码解析系列之一:Dex热更新

    [原]Android热更新开源项目Tinker源码解析系列之一:Dex热更新 Tinker是微信的第一个开源项目,主要用于安卓应用bug的热修复和功能的迭代. Tinker github地址:http ...

  4. 【原】Android热更新开源项目Tinker源码解析系列之二:资源文件热更新

    上一篇文章介绍了Dex文件的热更新流程,本文将会分析Tinker中对资源文件的热更新流程. 同Dex,资源文件的热更新同样包括三个部分:资源补丁生成,资源补丁合成及资源补丁加载. 本系列将从以下三个方 ...

  5. 多线程爬坑之路-Thread和Runable源码解析之基本方法的运用实例

    前面的文章:多线程爬坑之路-学习多线程需要来了解哪些东西?(concurrent并发包的数据结构和线程池,Locks锁,Atomic原子类) 多线程爬坑之路-Thread和Runable源码解析 前面 ...

  6. jQuery2.x源码解析(缓存篇)

    jQuery2.x源码解析(构建篇) jQuery2.x源码解析(设计篇) jQuery2.x源码解析(回调篇) jQuery2.x源码解析(缓存篇) 缓存是jQuery中的又一核心设计,jQuery ...

  7. Spring IoC源码解析——Bean的创建和初始化

    Spring介绍 Spring(http://spring.io/)是一个轻量级的Java 开发框架,同时也是轻量级的IoC和AOP的容器框架,主要是针对JavaBean的生命周期进行管理的轻量级容器 ...

  8. jQuery2.x源码解析(构建篇)

    jQuery2.x源码解析(构建篇) jQuery2.x源码解析(设计篇) jQuery2.x源码解析(回调篇) jQuery2.x源码解析(缓存篇) 笔者阅读了园友艾伦 Aaron的系列博客< ...

  9. jQuery2.x源码解析(设计篇)

    jQuery2.x源码解析(构建篇) jQuery2.x源码解析(设计篇) jQuery2.x源码解析(回调篇) jQuery2.x源码解析(缓存篇) 这一篇笔者主要以设计的角度探索jQuery的源代 ...

随机推荐

  1. ADO.NET中SqlCommand对数据库操作

    我们要不断地进行数据库的读写,那么ExecuteNonQuery(),ExecuteReader()与ExecuteScalar()就是我们在对数据库进行操作时要用到的,下面我来依次认识一下:     ...

  2. tornado+WSGI+Apache

    1.原理 2.安装mod_wsgi http://pan.baidu.com/s/1sjsccWH configure的时候会找对应的python脚本,默认是/usr/bin/python 生成mod ...

  3. Python之numpy模块array简短学习

    1.简介 Python的lists是非常的灵活以及易于使用.但是在处理科学计算相关大数量的时候,有点显得捉襟见肘了. Numpy提供一个强大的N维数组对象(ndarray),包含一些列同类型的元素,这 ...

  4. SDRAM操作(FPGA实现)

    对SDRAM基本概念的介绍以及芯片手册说明,请参考上一篇文章SDRAM操作说明. 1. 说明 如图所示为状态机的简化图示,过程大概可以描述为:SDRAM(IS42S16320D)上电初始化完成后,进入 ...

  5. boot之mybatis

    特别注意,此种方法和starter不兼容,我用了两个方式混蛋,发现跑不起来! spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driv ...

  6. Hibernate从零开始的反向工程

    首先  创建一个web项目 导入jar包 Bulid Path 先现在hibernate的插件   help-->eclipse marketplace-->输入tool  点instal ...

  7. Python 面向对象(三) 魔术方法

    __getitem__ 在对实例或对象使用索引访问时调用,self[key]__dir__ 收集当前模块的信息,包括继承自其它基类(包括object类)的属性和方法 __new 定义如何创建实例__i ...

  8. 一位有着工匠精神的博主写的关于IEnumerable接口的详细解析

    在此,推荐一位有着工匠精神的博主写的一篇关于IEnumerable接口的深入解析的文章:http://www.cnblogs.com/zhaopei/p/5769782.html#autoid-0-0 ...

  9. 4. 跟踪标记 (Trace Flag) 610 对索引组织表(IOT)最小化日志

    跟踪标记:610 功能: 用批量导入操作(Bulk Import Operations)加载数据时,对于索引组织表(即有聚集索引的表) 最小化日志: 上图为simple/bulk-logged恢复模式 ...

  10. js的学习(window对象的使用)

    open方法: //语法:var winObj = window.open([url][,name][,options]);  //参数:url:准备在新窗口中显示那个文件.url可以为空字符串,表示 ...