首页 运维 安全 如何进行gunicorn Arbiter 源码解析

如何进行gunicorn Arbiter 源码解析

May 12, 2023 pm 04:28 PM
gunicorn arbiter

如前文所述,Arbiter是gunicorn master进程的核心。Arbiter主要负责管理worker进程,包括启动、监控、杀掉Worker进程;同时,Arbiter在某些信号发生的时候还可以热更新(reload)App应用,或者在线升级gunicorn。Arbiter的核心代码在一个文件里面,代码量也不大,源码在此:https://github.com/benoitc/gunicorn。

Arbiter主要有以下方法:

setup:

    处理配置项,最重要的是worker数量和worker工作模型

init_signal

    注册信号处理函数

handle_xxx:

    各个信号具体的处理函数

kill_worker,kill_workers:

    向worker进程发信号

spawn_worker, spawn_workers:

    fork出新的worker进程

murder_workers:

    杀掉一段时间内未响应的worker进程

manage_workers:

    根据配置文件的worker数量,以及当前active的worker数量,决定是要fork还是kill worker进程

reexec

    接收到信号SIGUSR2调用,在线升级gunicorn

reload:

    接收到信号SIGHUP调用,会根据新的配置新启动worker进程,并杀掉之前的worker进程

sleep

    在没有信号处理的时候,利用select的timeout进行sleep,可被唤醒

wakeup

    通过向管道写消息,唤醒进程

run

    主循环

  Arbiter真正被其他代码(Application)调用的函数只有__init__和run方法,在一句代码里:

    Arbiter(self).run()

  上面代码中的self即为Application实例,其中__init__调用setup进行配置项设置。下面是run方法伪代码


def run()
    self.init_signal()
    self.LISTENERS = create_sockets(self.cfg, self.log)
    self.manage_workers()    while True:        if no signal in SIG_QUEUE
            self.sleep()        else:
            handle_signal()
登录后复制


 关于fork子进程

  fork子进程的代码在 spawn_worker, 源码如下:

如何进行gunicorn Arbiter 源码解析 Arbiter.spawn_worker

  主要流程:

    (1)加载worker_class并实例化(默认为同步模型 SyncWorker)

    (2)父进程(master进程)fork之后return,之后的逻辑都在子进程中运行

    (3)调用worker.init_process 进入循环,新航道雅思培训的所有工作都在这个循环中

    (4)循环结束之后,调用sys.exit(0)

    (5)最后,在finally中,记录worker进程的退出

    

    下面是我自己写的一点代码,把主要的fork流程简化了一下


 1 # prefork.py 2 import sys 3 import socket 4 import select 5 import os 6 import time 7   8 def do_sub_process(): 9     pid = os.fork()10     if pid < 0:11         print &#39;fork error&#39;12         sys.exit(-1)13     elif pid > 0:14         print 'fork sub process %d'  % pid15         return16  17     # must be child process18     time.sleep(1)19     print 'sub process will exit', os.getpid(), os.getppid()20     sys.exit(0)21  22 def main():23     sub_num = 224     for i in range(sub_num):25         do_sub_process()26     time.sleep(10)27     print 'main process will exit', os.getpid()28  29 if __name__ == '__main__':30     main()
登录后复制


在测试环境下输出:

  fork sub process 9601

  fork sub process 9602

  sub process will exit 9601 9600

  sub process will exit 9602 9600

  main process will exit 9600

  需要注意的是第20行调用了sys.exit, 保证子进程的结束,否则会继续main函数中for循环,以及之后的逻辑。注释掉第19行重新运行,看输出就明白了。

关于kill子进程

  master进程要kill worker进程就很简单了,直接发信号,源码如下:


 1     def kill_worker(self, pid, sig): 2         """\ 3         Kill a worker 4  5         :attr pid: int, worker pid 6         :attr sig: `signal.SIG*` value 7          """ 8         try: 9             os.kill(pid, sig)10         except OSError as e:11             if e.errno == errno.ESRCH:12                 try:13                     worker = self.WORKERS.pop(pid)14                     worker.tmp.close()15                     self.cfg.worker_exit(self, worker)16                     return17                 except (KeyError, OSError):18                     return19             raise
登录后复制


关于sleep与wakeup

  我们再来看看Arbiter的sleep和wakeup。Arbiter在没有信号需要处理的时候会"sleep",当然,不是真正调用time.sleep,否则信号来了也不能第一时间处理。这里得实现比较巧妙,利用了管道和select的timeout。看代码就知道了


        def sleep(self):        """\
        Sleep until PIPE is readable or we timeout.
        A readable PIPE means a signal occurred.        """
            ready = select.select([self.PIPE[0]], [], [], 1.0) # self.PIPE = os.pipe()
            if not ready[0]: 
                return
            while os.read(self.PIPE[0], 1):                pass
登录后复制

  代码里面的注释写得非常清楚,要么PIPE可读立即返回,要么等待超时。管道可读是因为有信号发生。这里看看pipe函数

  •   os.pipe()

  • Create a pipe. Return a pair of file descriptors (r,w) usable for reading and writing, respectively.

  那我们看一下什么时候管道可读:肯定是往管道写入的东西,这就是wakeup函数的功能

        def wakeup(self):            """
            Wake up the arbiter by writing to the PIPE            """
            os.write(self.PIPE[1], b'.')
登录后复制

最后附上Arbiter的信号处理

退出,INT:快速关闭

TERM: 优雅关机。等待工作人员完成其当前请求,直到超时。

HUP:重新加载配置,用新配置启动新的工作进程,并优雅地关闭旧的工作进程。如果应用程序未预加载(使用--preload选项),Gunicorn也将加载新版本。

TTIN:将进程数增加一个

TTOU:将进程数减少一个

USR1:重新打开日志文件

USR2:在飞行中升级Gunicorn。应使用单独的术语信号终止旧进程。此信号也可用于使用预加载应用程序的新版本。

绞盘:当Gunicorn被守护时,优雅地关闭工作进程。

以上是如何进行gunicorn Arbiter 源码解析的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
4 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
4 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
4 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.聊天命令以及如何使用它们
4 周前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

一文弄懂 Gunicorn 与 Python GIL 一文弄懂 Gunicorn 与 Python GIL Apr 12, 2023 am 10:40 AM

什么是 Python GIL,它是如何工作的,以及它如何影响 gunicorn。生产环境我应该选择哪种 Gunicorn worker类型?Python 有一个全局锁 (GIL),它只允许一个线程运行(即解释字节码)。在我看来,如果你想优化你的 Python 服务,理解 Python 如何处理并发是必不可少的。Python 和 gunicorn 为您提供了处理并发的不同方法,并且由于没有涵盖所有用例的灵丹妙药,因此最好了解每个选项的选项、权衡和优势。Gunicorn worker类型Gunico

比较Flask应用部署的Gunicorn和uWSGI性能对比 比较Flask应用部署的Gunicorn和uWSGI性能对比 Jan 17, 2024 am 08:52 AM

Flask应用部署:GunicornvsuWSGI的比较引言:Flask作为一种轻量级的PythonWeb框架,受到了很多开发者的喜爱。在将Flask应用部署到生产环境时,选择适合的服务器网关接口(ServerGatewayInterface,简称SGI)是至关重要的决策。Gunicorn和uWSGI是两种常见的SGI服务器,本文将对它们进行详细的

深入了解Gunicorn的基本原理和功能 深入了解Gunicorn的基本原理和功能 Jan 03, 2024 am 08:41 AM

Gunicorn的基本概念和作用Gunicorn是一个用于在PythonWeb应用程序中运行WSGI服务器的工具。WSGI(Web服务器网关接口)是Python语言定义的一种规范,用于定义Web服务器与Web应用程序之间的通信接口。Gunicorn通过实现WSGI规范,使得PythonWeb应用程序可以被部署和运行在生产环境中。Gunicorn的作用是作

Flask应用的Gunicorn部署指南 Flask应用的Gunicorn部署指南 Jan 17, 2024 am 08:13 AM

如何使用Gunicorn部署Flask应用?Flask是一个轻量级的PythonWeb框架,被广泛应用于开发各种类型的Web应用。而Gunicorn(GreenUnicorn)是一个基于Python的HTTP服务器,用于运行WSGI(WebServerGatewayInterface)应用。本文将介绍如何使用Gunicorn部署Flask应用,并附

Gunicorn是什么 Gunicorn是什么 Nov 23, 2023 pm 03:07 PM

Gunicorn是一个用Python编写的WSGI(HTTP服务器) Web服务器网关接口规范,是一个轻量级、高效的服务器,专门用于运行Python web应用程序。其主要特点和功能包括:1、高性能,可以轻松地处理高并发请求;2、稳定可靠,可以提供持久的长时间运行,极大地减少了服务器崩溃的可能性;3、容错性,可以做到保持服务的稳定性;4、多种部署方式等等。

部署Gunicorn和Flask的无懈可击的组合 部署Gunicorn和Flask的无懈可击的组合 Jan 17, 2024 am 10:24 AM

Gunicorn和Flask:完美的部署组合,需要具体代码示例概述:对于开发者来说,选择适合的部署方式是非常重要的,尤其是对于Python的Web应用程序而言。在Python的Web框架中,Flask是非常流行的选择,而Gunicorn则是一种部署Python应用程序的服务器。本文将介绍Gunicorn和Flask的组合,并提供一些具体的代码示例,以帮助读者

CentOS安装Gunicorn及CentOS安装分区教程 CentOS安装Gunicorn及CentOS安装分区教程 Feb 10, 2024 pm 09:20 PM

LINUX是一个强大的操作系统,被广泛应用于服务器和开发环境,CentOS是基于RedHatEnterpriseLinux(RHEL)的一个开源操作系统,被广泛使用于服务器环境中,在CentOS上安装Gunicorn和进行分区可以提高服务器的性能和安全性,本文将详细介绍如何在CentOS上安装Gunicorn以及如何进行分区。CentOS安装GunicornGunicorn是一个Python的WSGIHTTP服务器,用于运行Python的Web应用程序,以下是在CentOS上安装Gunicorn

提升Flask应用性能的方法:使用Gunicorn 提升Flask应用性能的方法:使用Gunicorn Jan 17, 2024 am 10:42 AM

Gunicorn如何提高Flask应用的性能?随着互联网的快速发展,Web应用程序的性能对于用户体验和企业竞争力变得越来越重要。在处理高并发请求时,Flask框架默认的开发服务器往往无法满足需求。因此,我们需要使用Gunicorn(GreenUnicorn)来提高Flask应用的性能。Gunicorn是一个基于Python的HTTP服务器,它采用了预派生进

See all articles