gunicorn不停服重启更新服务

news2024/11/17 5:46:08

简介

Gunicorn是基于unix系统,被广泛应用的高性能的Python WSGI HTTP Server。用来解析HTTP请求的网关服务。
它通常是在进行反向代理(如nginx),或者进行负载均衡(如 AWS ELB)和一个web 应用(比如 Django 或者 Flask)之间。
它的运行模型基于pre-fork worker 模型,即就是支持eventlet,也支持greenlet。
目前,gunicorn只能运行在Linux环境中,不支持windows平台。

信号

gunicorn是通过信号处理来达到对进程管理的目的,先看一下他接收的几种信号

  • QUIT: 快速关闭
  • TERM: 优雅的关闭。等待worker完成当前请求直到达到超时时间
  • HUP: 重新加载配置,使用新的配置启动新的工作进程,并优雅地关闭较老的工作进程。
  • TTIN: 增加一个进程
  • TTOU: 减少一个进程
  • USR1: 重新打开日志文件
  • USR2: 在线升级gunicorn
  • WINCH: 优雅地关闭守护进程(后台运行的进程)

HUP

文档中的意思使用HUP可以达到重启的效果,测试的日志是这样的

[2021-01-21 17:25:14 +0800] [20388] [INFO] Handling signal: hup
[2021-01-21 17:25:14 +0800] [20388] [INFO] Hang up: Master
[2021-01-21 17:25:14 +0800] [29249] [INFO] Booting worker with pid: 29249
[2021-01-21 17:25:14 +0800] [29248] [INFO] Booting worker with pid: 29248
[2021-01-21 17:25:14 +0800] [29250] [INFO] Booting worker with pid: 29250
[2021-01-21 17:25:14 +0800] [28643] [INFO] Shutting down
[2021-01-21 17:25:14 +0800] [28643] [INFO] Error while closing socket [Errno 9] Bad file descriptor
[2021-01-21 17:25:14 +0800] [28640] [INFO] Shutting down
[2021-01-21 17:25:14 +0800] [28640] [INFO] Error while closing socket [Errno 9] Bad file descriptor
[2021-01-21 17:25:14 +0800] [28642] [INFO] Shutting down
[2021-01-21 17:25:14 +0800] [28642] [INFO] Error while closing socket [Errno 9] Bad file descriptor
[2021-01-21 17:25:14 +0800] [28643] [INFO] Finished server process [28643]
[2021-01-21 17:25:14 +0800] [28643] [INFO] Worker exiting (pid: 28643)
[2021-01-21 17:25:14 +0800] [28640] [INFO] Finished server process [28640]
[2021-01-21 17:25:14 +0800] [28640] [INFO] Worker exiting (pid: 28640)
[2021-01-21 17:25:14 +0800] [28642] [INFO] Finished server process [28642]
[2021-01-21 17:25:14 +0800] [28642] [INFO] Worker exiting (pid: 28642)
[2021-01-21 17:25:15 +0800] [29248] [INFO] Started server process [29248]
[2021-01-21 17:25:15 +0800] [29248] [INFO] Waiting for application startup.
[2021-01-21 17:25:15 +0800] [29248] [INFO] ASGI 'lifespan' protocol appears unsupported.
[2021-01-21 17:25:15 +0800] [29248] [INFO] Application startup complete.
[2021-01-21 17:25:15 +0800] [29249] [INFO] Started server process [29249]
[2021-01-21 17:25:15 +0800] [29249] [INFO] Waiting for application startup.
[2021-01-21 17:25:15 +0800] [29249] [INFO] ASGI 'lifespan' protocol appears unsupported.
[2021-01-21 17:25:15 +0800] [29249] [INFO] Application startup complete.

通过日志可以看到他是先停止了旧进程然后再启动了新的进程,但是从gunicorn源码中看是先启动了进程然后通过进程数和配置的进程数对比来kill掉老的进程:

# 简化后的处理HUP方法
# spawn new workers
for _ in range(self.cfg.workers):
	self.spawn_worker()  # 这里启动了进程

# manage workers
self.manage_workers()  # 这里根据进程启动的时候给的一个age值来kill掉老的进程

# manage_workers方法
def manage_workers(self):
  """\
        Maintain the number of workers by spawning or killing
        as required.
        """
  if len(self.WORKERS) < self.num_workers:
    self.spawn_workers()

    workers = self.WORKERS.items()
    workers = sorted(workers, key=lambda w: w[1].age)
    while len(workers) > self.num_workers:
      (pid, _) = workers.pop(0)
      self.kill_worker(pid, signal.SIGTERM)

      active_worker_count = len(workers)
      if self._last_logged_active_worker_count != active_worker_count:
        self._last_logged_active_worker_count = active_worker_count
        self.log.debug("{0} workers".format(active_worker_count),
                       extra={"metric": "gunicorn.workers",
                              "value": active_worker_count,
                              "mtype": "gauge"})

实操

  • 获取Gunicorn进程树:
pstree -ap|grep gunicorn

结果如下:

  |   |-gunicorn,29863 /usr/local/bin/gunicorn -c gun.tests.conf app:app
  |   |   |-gunicorn,29867 /usr/local/bin/gunicorn -c gun.tests.conf app:app
  |   |   |   `-{gunicorn},31724
  |   |   |-gunicorn,29868 /usr/local/bin/gunicorn -c gun.tests.conf app:app
  |   |   |   `-{gunicorn},30979
  |   |   |-gunicorn,29869 /usr/local/bin/gunicorn -c gun.tests.conf app:app
  |   |   |   `-{gunicorn},30953
  |   |   |-gunicorn,29870 /usr/local/bin/gunicorn -c gun.tests.conf app:app
  |   |   |   `-{gunicorn},30532
  |   |   |-gunicorn,29872 /usr/local/bin/gunicorn -c gun.tests.conf app:app
  |   |   |   `-{gunicorn},30951
  |   |   |-gunicorn,29875 /usr/local/bin/gunicorn -c gun.tests.conf app:app
  |   |   |   `-{gunicorn},30533
  |   |   |-gunicorn,29876 /usr/local/bin/gunicorn -c gun.tests.conf app:app
  |   |   |   `-{gunicorn},30714
  |   |   |-gunicorn,29877 /usr/local/bin/gunicorn -c gun.tests.conf app:app
  |   |   |   `-{gunicorn},30952
  |   |   `-gunicorn,29878 /usr/local/bin/gunicorn -c gun.tests.conf app:app
  |   |       `-{gunicorn},30510

  • 重启Gunicorn任务
kill -HUP 29863 

补充其他内容

安装

pip install gunicorn

配置与启动

Gunicorn可以以三种方式读取配置信息。

  • 从framework定义的配置信息中读取,目前只对 Paster 框架有效。本方式较少用到。
  • 在命令行中定义,命令行中定义的配置信息将会覆盖框架中定义的相同的参数名的值
  • 将所有的参数信息,放到一个python文件中,只要是在命令行中可以定义的参数中,在配置文件中都可以定义。

命令行配置参数

命令行有哪些参数可以通过gunicorn -h 查到
在这里插入图片描述
实例:

gunicorn -D -t 300 -w 2 -b 0.0.0.0:8787 flaskr:create_app()

下面是flaskr下 init.py 的内容

import os

from flask import Flask
from flask_cors import CORS

def create_app(test_config=None):
    # create and configure the app
    app = Flask(__name__, instance_relative_config=True)
    CORS(app, supports_credentials=True)
    app.config.from_mapping(
        SECRET_KEY='dev',
        DATABASE=os.path.join(app.instance_path, 'flaskr.sqlite'),
    )

    if test_config is None:
        # load the instance config, if it exists, when not testing
        app.config.from_pyfile('config.py', silent=True)
    else:
        # load the test config if passed in
        app.config.from_mapping(test_config)

    # ensure the instance folder exists
    try:
        os.makedirs(app.instance_path)
    except OSError:
        pass

    # a simple page that says hello
    from . import api, db
    db.init_app(app)
    app.register_blueprint(api.bp)
    return app

python文件配置参数

命令行中定义的参数,都可以放在配置文件(config_gunicorn.py)中。

#config_gunicorn.py
#import multiprocessing

bind = "0.0.0.0:8787"#gunicorn监控的接口
#workers = multiprocessing.cpu_count() * 2 + 1
workers = 2#进程数
#threads = 1 #每个进程开启的线程数
timeout = 300

backlog = 2048
worker_class = "eventlet"# 工作模式协程,详看https://ox0spy.github.io/post/web-test/gunicorn-worker-class/
worker_connections = 1000
daemon = True
pidfile = 'log/gunicorn.pid'#gunicorn进程id,kill掉该文件的id,gunicorn就停止
#loglevel = 'debug'
accesslog = 'log/access.log'
errorlog = 'log/gunicorn.log'

gunicorn --config=config_gunicorn.py flaskr:create_app()

命令行参数和文件配置还可以混合使用,此时命令行中定义的配置信息将会被优先采用。

gunicorn --config=config_gunicorn.py --worker-class=gevent flaskr:create_app()

服务重启、退出

获取Gunicorn进程树(用下面的命令获取gunicorn的Master PID)

#方法1
pstree -ap|grep gunicorn
#方法2
ps -ef|grep gunicorn 

重启Gunicorn进程

HUP(终端断线)信号发出之后,worker进程会进行被杀掉,并启动新的进程,保证源代码的修改会反映进来。master进程不会变

kill -HUP master_pid

优雅停止Gunicorn进程

kill -9 master_pid

自动化管理:supervisor

gunicorn无法重启,关闭进程麻烦,因此还需要一个程序(如supervisor)来管理gunicorn,以达到自动化.而supervisor是一个专门用来管理进程的工具,还可以管理系统的工具进程,甚至可设置web页面管理相关进程;

下面的命令是将gunicorn配置在supervisor之下的情况。仅做参考。

# 重新加载配置
sudo supervisorctl reload
# 重启动
sudo supervisorctl restart all(你想重启的单个应用名字也可以)
# 查看状态
sudo supervisorctl status 

安装
pip install supervisor

supervisor设置配置文件(supervisor.conf)还可以将脚本打印信息输出到指定文件内,设置内存上限可自动清理等等;

配置文件

创建配置文件的默认路径

sudo mkdir /etc/supervisor
sudo mkdir /etc/conf.d
创建配置文件
cat /etc/supervisor/conf.d/wsgi.ini
[program:wsgi]   ;program:名称
;启动命令,当然你可以直接 python run.py,此处使用gunicorn启动
command=gunicorn pygun.conf wsgi:app --log-level=debug --preload
;工作目录(脚本启动目录的全路径)
directory=/data/test 
startsecs=0
stopwaitsecs=0
autostart=true          ;supervisord守护程序启动时自动启动tornado
autorestart=true        ;supervisord守护程序重启时自动重启tornado
redirect_stderr=true   ;将stderr重定向到stdout
;日志标准输出路径,同时脚本print打印信息也会在改文件显示
stdout_logfile=./stdout.log
stderr_logfile=./error.log


;守护进程,可在 web 上访问
[inet_http_server]     ; inet (TCP) server disabled by default
port=127.0.0.1:9001    ; (ip_address:port specifier, *:port for all iface)
username=wialsh        ; (default is no username (open server))
password=wialsh        ; (default is no password (open server))

;supervisord日志配置
[supervisord]
logfile=/tmp/supervisord.log ; main log file; default $CWD/supervisord.log
logfile_maxbytes=50MB        ; max main logfile bytes b4 rotation; default 50MB
logfile_backups=1

若无特别需求,只需修改启动命令(command)、部分文件(directory、stdout_logfile、stderr_logfile、logfile)路径和守护进程(inet_http_server),其他参数默认即可;

启动

完成配置后,执行如下脚本启动(supervisord -c 启动指定路径的配置):

supervisord -c /etc/supervisor/conf.d/wsgi.ini

在完成配置后,查看监控日志,以检查启动是否成功,可执行如下操作

less error.log  #gunicorn的errorlog路径
less /tmp/supervisord.log  #supervisor的logfile路径

查看状态(如无错误情况,可查看状态)

supervisorctl -c /etc/supervisor/conf.d/wsgi.ini status
wsgi                         RUNNING   pid 274203, uptime 0:17:35

重启服务

supervisorctl -c /etc/supervisor/conf.d/wsgi.ini reload
Restarted supervisord

关闭服务

supervisorctl -c /etc/supervisor/conf.d/wsgi.ini shutdown
Shut down

参考

官方文档
Gunicorn简介、安装、配置、启动
gunicorn不停服重启
优化 Gunicorn 配置
supervisor + gunicorn + flask 入门
详解gunicorn的功能及使用方法
supervisor配置详解

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/682459.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

AI + 算力 = “最强龙头”?

随着人工智能技术的飞速发展&#xff0c;“AI算力”的结合应用已成为科技行业的热点话题&#xff0c;甚至诞生出“AI算力最强龙头“的网络热门等式。该组合不仅可以提高计算效率&#xff0c;还可以为各行各业带来更强大的数据处理和分析能力&#xff0c;从而推动创新和增长。 …

Java项目-SpringBoot+Vue 的学生就业管理信息系统

&#x1f495;&#x1f495;作者&#xff1a;程序员徐师兄 个人简介&#xff1a;7 年大厂程序员经历&#xff0c;擅长Java、微信小程序、Python、Android等&#xff0c;大家有这一块的问题可以一起交流&#xff01; 各类成品java毕设 。javaweb&#xff0c;ssh&#xff0c;ssm&…

小航助学2023年6月GESP_C++三级试卷(含题库答题软件账号)

需要在线模拟训练的题库账号请点击 小航助学编程在线模拟试卷系统&#xff08;含题库答题软件账号&#xff09;_程序猿下山的博客-CSDN博客 单选题2.0分 删除编辑附件图文 答案:D 第1题高级语言编写的程序需要经过以下&#xff08; &#xff09;操作&#xff0c;可以生成在…

geo-tool 解析百度经纬出错 {‘status‘: 240, ‘message‘: ‘APP 服务被禁用‘}

geo-tool 解析百度经纬出错 {status: 240, message: APP 服务被禁用} 引子一、查错二、排错三、测试通过参考 作者&#xff1a;高玉涵 时间&#xff1a;2023.6.25 环境&#xff1a;Windows 10 专业版 22H2&#xff0c;Python 3.10.4 第三方包&#xff1a;geo-tool 1.1.2 引…

【模拟CMOS集成电路】HSPICE入门仿真分析实例

【模拟CMOS集成电路】HSPICE入门仿真分析实例 一、采用HSPICE的MOS器件仿真二、INV倒相器HSPICE仿真附录程序源码&#xff08;一&#xff09;程序源码&#xff08;二&#xff09; 一、采用HSPICE的MOS器件仿真 一、采用HSPICE的MOS器件仿真, 并回答以下问题。   1&#xff0…

Visual Studio 2019使用详解

VS2019&#xff08;Visual Studio 2019&#xff09;是由微软开发的集成开发环境&#xff08;IDE&#xff09;&#xff0c;用于开发各种应用程序&#xff0c;包括桌面应用程序、Web应用程序、移动应用程序等。 对工具的熟悉程度有助于提升开发效率&#xff0c;磨刀不误砍柴功&am…

solr快速上手:整合spring-data-solr实现客户端操作(十)

0. 引言 前一章介绍了官方的solr客户端SolrJ&#xff0c;但是solrJ的使用相对来说并不方便&#xff0c;仍然需要做一些负责的客户端操作以及语句的书写&#xff0c;有没有更加方便的ORM框架呢&#xff0c;这就提到了spring-data-solr了 1. 简介 首先如果你还不知道spring-da…

面试题:深拷贝和浅拷贝(+内存图)

深拷贝和浅拷贝主要是针对对象的属性是对象&#xff08;引用类型&#xff09; 一、基本类型和引用类型的区别 1&#xff09;、基本类型&#xff1a;就是值类型&#xff0c;即在变量所对应的内存区域存储的是值。 2&#xff09;、引用类型&#xff1a;就是地址类型。 何为地…

Kubeadm 部署k8s实现并且演示滚动不停服务更新

1. 环境准备 在开始之前&#xff0c;部署Kubernetes集群机器需要满足以下几个条件&#xff1a; 一台或多台机器&#xff0c;操作系统 CentOS7.x-86_x64&#xff1b;硬件配置&#xff1a;2GB或更多RAM&#xff0c;2个CPU或更多CPU&#xff0c;硬盘30GB或更多&#xff1b;集群中…

【Activiti】原理

一、核心类 RepositoryService&#xff1a;部署管理流程资源&#xff0c;如bpmn文件、附件等等&#xff1b;RuntimeService&#xff1a;操作运行时的流程&#xff1b;TaskService&#xff1a;流程中任务的信息&#xff1b;HistoryService&#xff1a;流程的历史信息&#xff1…

ZYNQ——按键和LED关联实验

ZYNQ 7020黑金开发板的PL端有四个LED&#xff0c;如下图所示。 PL端也有四个KEY&#xff0c;如下图所示。 本文将把这四个按键和四个LED一一对应起来&#xff0c;在按键按下或松开时&#xff0c;对应的LED产生亮或灭的信号。 在原理图中找到PL端的LED和KEY如下图所示。 通过…

成为python爬虫工程师需要哪些知识?

爬虫&#xff08;Web crawler&#xff09;是一种自动化程序&#xff0c;用于从互联网上抓取、解析和提取网页数据。它模拟浏览器行为&#xff0c;通过发送HTTP请求获取网页内容&#xff0c;并通过解析网页源代码或DOM结构&#xff0c;提取所需的信息。以python爬虫为例&#xf…

优思学院|作业标准和标准化作业有何区别?傻傻搞不清?

作业标准和标准作业是两个在生产和制造环境中具有重要意义的概念。尽管它们看似相似&#xff0c;但实际上它们在定义、目的和实施方法上存在显著差异。本文将探讨作业标准和标准作业的区别&#xff0c;以及它们在工作场所中的作用和重要性。 1. 引言 在制造领域中&#xff0c…

JDBC小记——SQL注入及预编译操作对象、批处理

目录 SQL注入 预编译操作对象 自定义JDBC工具类 1.创建配置文件 2.配置 3.在工具类中使用配置文件 批处理 注意事项 SQL注入 SQL注入是黑客对数据库进行攻击的常用手段之一&#xff0c;他们拼接一些恶意的sql语句&#xff0c;来获取他们想要的数据。 例&#xff1a; s…

Bpmn.js流程建模结合业务整合工作流(一)

bmpn.js是什么? 先上图 初步认识bpmn.js 相关文档直接上链接 全网最详bpmn.js教材-基础篇 - 掘金bpmn.js是一个BPMN2.0渲染工具包和web建模器, 使得画流程图的功能在前端来完成. 因为公司业务的需要因而要在项目中使用到bpmn.js,但是由于bpmn.js的开发者是国外友人, 因此国…

【2023年中总结】是的,我从一家世界前百强企业毕业了,进入了一家只有20人的小企业。。。

我的2023-上 &#x1f550; 一、引言&#x1f55c; 二、新年&#x1f559; 三、措手不及&#x1f565; 四、抉择&#x1f55a; 五、适应&#x1f389;测试驱动开发&#x1f389;角色的转变&#x1f389;工作环境和生活环境的转变&#x1f389;工作态度 &#x1f566; 六、挑战&…

【裸机开发】定时器中断(EPIT)

EPIT 是周期性中断定时器&#xff0c;会定期调用指定的中断服务函数&#xff0c;其实可以看做是一种IRQ的外设中断&#xff0c;对应的中断ID是88&#xff08;5632&#xff09;或者 89&#xff08;5732&#xff09;。 目录 一、定时器计数流程 二、寄存器解析 1、EPIT1_CR 2…

骨传导耳机、运动耳机推荐:南卡OE开放式TWS耳机值得买吗?南卡OE测评

目前&#xff0c;如果说到骨传导耳机、蓝牙耳机想必大家都很熟悉&#xff0c;那你了解TWS耳机么&#xff1f; 如果说iPhone“重新定义”了智能手机&#xff0c;那么AirPods就重新定义了耳机——它“断”了耳机与手机/播放器间的连线&#xff0c;还将左右耳彼此间的连线彻底摒弃…

SimpleDateFormat显示24小时和12小时时间格式

public static void main(String[] args) throws Exception {MainTest1 mainTest1 new MainTest1();mainTest1.dateFormat();} yyyy-MM-dd HH:mm:ss格式显示的时间为:2017-06-12 18:01:06 yyyy-MM-dd hh:mm:ss格式显示的时间为:2017-06-12 06:01:06

二章:VMvare虚拟机的安装+VMvare安装winServer2008

目录 一、Vmware软件安装 二、Vmware软件注册 三、Vmware配置虚拟机-1 四、Vmware配置虚拟机-2 五、Vmware配置虚拟机-3 六、Vmware安装windows server 2008 一、Vmware软件安装 第一步 双击安装程序&#xff0c;点击下一步。 第二、三步 勾选接受许可&#xff0c;点击下一步。…