gunicorn源码分析:Master-Worker模式
最近阅读了gunicron的源码。 gunicron的工作模式采用Master-Worker, 提前fork出配置文件中配置数量的worker进程(prefork),这些worker进程同事监听这master进程的一个socket. worker进程响应用户请求。master进程通过各种信号量管理者worker进程。整个实现非常的巧妙,很多细节值得学习。
我把代码回退到较早的一个版本的提交,主要想看清楚整个处理架构。
commit_id: ec301fd43d26207ff0dd9e06925882bc017dc866
文件结构
.
├── LICENSE
├── Manifest.in
├── README.rst
├── bin
│ ├── gunicorn #程序入口
│ └── gunicorn_django # django_app
├── examples
│ └── test.py # test app符合wsgi协议
├── gunicorn # 核心目录
│ ├── __init__.py
│ ├── arbiter.py # master进程启动文件
│ ├── http
│ │ ├── __init__.py
│ │ ├── iostream.py
│ │ ├── request.py # 处理http请求
│ │ ├── response.py # 处理http请求
│ ├── util.py
│ ├── worker.py # woker进程核心文件
└── setup.py
代码启动
1 | arbiter = gunicorn.Arbiter((opts.host, opts.port), opts.workers, app) |
构造Arbiter类,传入监听端口,worker数量,调用run方法启动。项目启动后能看到3个进程(设置worker数量为2)
1 | 501 75763 72171 0 Fri11PM ?? 0:00.58 /System/Library/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python /Users/wangjinlong/Documents/jinlong/code/github/gunicorn/bin/gunicorn --workers=2 examples/test:app |
可以看到两个75763
fork出两个子进程75764
和75765
. 75763
是master进程,
子进程为worker进程。
master类代码
类图
arbiter类图如下
构造函数
master类的构造方法如下:
1 | class Arbiter(object): |
self.init_signals()
初始化了所有的信号量以及对应操作, master靠信号量来管理worker进程,例如:增加一个worker进程,杀死一个woker进程等等,具体代码如下:
1 | def init_signals(self): |
self.PIPE
没搞清楚到底作用是什么?调试代码发现可能是为了在master进程中,有队PIPE写和读的操作。
self.listen
方法主要是构造了socket对象
重点看Arbiter类的run方法:
1 | def run(self): |
self.manage_workers
方法:
1 | def manage_workers(self): |
self.spawn_workers
方法就可以看到fork worker的操作
1 | def spawn_workers(self): |