首页 存档 技术 查看内容

科普丨Python程序中不同的重启机制

2018-3-30 13:00 |来自: 互联网 370 0

摘要: 分析典型案例: Celery 分布式异步任务框架 Gunicorn Web容器 之所以挑这两个,不仅仅是应用广泛,而且两个的进程模型比较类似,都是Master、Worker的形式,在热重启上思路和做法又基本不同,比较有参考意义 知识 ...

分析典型案例:

  1. Celery 分布式异步任务框架

  2. Gunicorn Web容器

之所以挑这两个,不仅仅是应用广泛,而且两个的进程模型比较类似,都是Master、Worker的形式,在热重启上思路和做法又基本不同,比较有参考意义

知识点:

  • atexit

  • os.EⅩEcv

  • 模块共享变量

  • 信号处理

  • sleep原理:select

  • 文件描述符共享

这几个知识点不难,区别只在于Celery和Gunicorn的应用方式。如果脑海中有这样的知识点,这篇文章也就是开阔下视野而已。。。

Celery和Gunicorn都会在接收到HUP信号时,进行热重启操作

Celery的重启:关旧Worker,然后execv重新启动整个进程

Gunicorn的重启:建立新Worker,再关旧Worker,Master不动

下面具体的看下它们的操作和核心代码。

对于Celery:

def _reload_current_worker():
    platforms.close_open_fds([
        sys.__stdin__, sys.__stdout__, sys.__stderr__,
    ])
    os.EⅩEcv(sys.EⅩEcutable, [sys.EⅩEcutable]   sys.argv) 
 
  
def install_worker_restart_handler(worker, sig='SIGHUP'):
    def restart_worker_sig_handler(*args):
        """Signal handler restarting the current python program."""
        import atexit
        atexit.register(_reload_current_worker)        from celery.worker import state
        state.should_stop = EX_OK
    platforms.signals[sig] = restart_worker_sig_handler

HUP上挂的restart_worker_sig_handler 就做了两件事:

  1. 注册atexit函数

  2. 设置全局变量

考虑到这个执行顺序,应该就能明白Celery 是Master和Worker都退出了,崭新呈现。。

看过APUE的小伙伴,应该比较熟悉 atexit 了,这里也不多说。os.EⅩEcv还挺有意思,根据Python文档,这个函数会执行一个新的函数用于替换掉当前进程,在Unix里,新的进程直接把可执行程序读进进程,保留同样的PID。

在Python os标准库中,这是一整套基本一毛一样的函数,也许应该叫做函数族了:

  • os.execl(path,arg0,arg1,)

  • os.execle(path,arg0,arg1,,env)

  • os.execlp(file,arg0,arg1,)

  • os.execlpe(file,arg0,arg1,,env)

  • os.execv(path,args)

  • os.execve(path,args,env)

  • os.execvp(file,args)

  • os.execvpe(file,args,env)

以exec开头,后缀中的l和v两种,代表命令行参数是否是变长的(前者不可变),p代表是否使用PATH定位程序文件,e自然就是在新进程中是否使用ENV环境变量了

然后给worker的state.should_stop变量设置成False。。。模块共享变量这个是Python FAQ里提到的一种方便的跨模块消息传递的方式,运用了Python module的单例。我们都知道Python只有一个进程,所以单例的变量到处共享

而should_stop这个变量也是简单粗暴,worker在执行任务的循环中判断这个变量,即执行异步任务-

声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系 [邮箱地址] 删除

路过

雷人

握手

鲜花

鸡蛋

相关分类

返回顶部