95992828九五至尊2

python编程境遇的几个坑,Python进度管理工具

一月 20th, 2019  |  882828九五至尊手机版

这一周处理了多少个从前一向出现一直从未面对面的坑,总括一下。

add by zhj: 下边是在ubuntu上的一对运用经验

sqlalchemy连接池

我写了一个简短的内网dns管理种类,用到flasksqlalchemy。主要就是经过web页面和api对dns记录举行增删改查,所有那一个操作都写入数据库,每趟变更后暴发一个celery职分来异步的双重生成dns的计划文件。

看起来一个简约的问题,不过在celery中读取数据库的时候现身了问题,每一天早晨都会报错Mysql has gone away,我重启服务复苏正常,第二天上午又会现出一样的问题,不过在flask的路由下调用的兼具数据库操作没有出现其他问题。咨询DBA,DBA说数据库是常规的,所以毫无疑问是本人的程序处理有题目了。我在网上种种材料查询,最后找到结果。

flask_sqlalchemy默许使用数据库连接池来对理数据库连接举办复用以压缩建立连接的付出,他默许会对连接池中的每个连接隔2钟头检查一遍是不是可用,借使不可用就销毁掉,创立新的连天放到连接池中,我们使用db.session的时候就要求从连接池中获得一个接连,使用完后调用db.session.close来将连接放回到连接池(close并不是关门连接,关闭连接的操作由连接池来保管)。可是自己在路由函数中一直没有利用过db.session.close,也一贯没有出现过问题,是因为flask_sqlachemy会自动在呼吁上下文停止时自动将连接放回连接池,这样放回连接池的连天就会每隔两钟头接受一次检查。不过在celery中查询的时候问题就会油可是生,celery中并从未请求上下文,所有查询完以后并不会将连接放回连接池,也就是说celery中向来选用同一个老是,向来没有放回过连接池,也就不曾会被检查三番五回的灵光,所以延续断开的时候举办询问,导致报错。

连日为何会断开呢?原来mysql会把闲置不用当先8时辰的连续主动关掉,而dns变更大多是大白天上班的时候改变,早晨为主不会变动,那样超过8钟头过后mysql的总是已经被断开了,而celery中行使的接连依旧前一天早晨重启得到的连接,肯定失效了,拿去询问数据失利,抛出非常。

因此我后来在celery中老是查询截至后都会调用db.session.close,那样会将屡次三番放回连接池,下次查询会重新从连接池中收获新的连年,那么些接二连三各种八个时辰会被检查,因而再也从没出现过这么些问题。

 

supervisord 与 celery

882828九五至尊手机版,这几个题目出现在发表连串中,也是让自家胸闷了漫漫的一个题材,这一周终于得到解决。大家的昭示系列应用celery异步的执行ansible脚本来进行表露的,每一次发布几乎须要1.5到5分钟不等的年月。大家采纳supervisord来治本web端和celery端的启动,每一遍修改完代码之后上线重启发表系统之后就会并发众多揭橥职分卡死不再继续执行,每一回都亟需手动把卡死的昭示职分kill掉,然后重发,上周终于找到问题源于了。

众所周知celery有一个warm shutdown的机制,就是给celery master发送一个
SIG_TERM信号,celery
master就会布告其管理的workers截止接受新的天职,然后等待手头的天职完结,等到所有workers均做到职责后,master会kill掉所有workers,然后截至运行。大家的宣布连串需求的就是以此效果,可是我一贯深感supervisord甘休celery的时候并不曾运用warm
shutdown的章程,因为每一遍都会又有的celery
worker进程未被终止,而且永远不会落成运行,那个celery
worker中推行的揭发任务就会卡死不动,那一个场景叫我百思不得其解。

于是乎我去查supervisord的文档,发现她停止进程的时候确实默许就发送SIG_TERM信号,而且自己也远非那方面的配备,表达应该是行使了warm shutdown的,看celery
worker打印出来的日记也确实是有warm
shutdown,可是为何会并发如此诡异的事情啊?我再看supervisord的文档,发现种种由superivsord托管的次序都有一个布局项stopwaitsecs,表示supervisord对这些程序发出SIG_TERM信号(用来杀死该程序)到她收受SIG_CHLD信号(标志着这几个顺序真的被杀掉)之间他乐于等待的光阴,假若当先这几个小时,supervisord会再次向该程序发出SIG_KILL信号,这一个信号是肯定会杀死其管理的先后的。也就是说,supervisord会先对celery的master举办warm
shutdown的操作,完了之后等待stopwaitsecs秒之后会大开杀戒,直接干掉celery
master。而以此stopwaitsecs默认为10s,对于我们一个等分揭橥时间为3分钟左右的披露义务的话肯定等不到warm
shutdown真正到位,supervisord就会惨酷的干掉celery
master。而这么强行的干掉celery master之后,celery
worker貌似也出现了越发,再不干活了,因为他是格外器重master的,而且她干完活之后还需求想master发送ack确认音信的,故此导致那个workers中的发表职责卡死。

当我把stopwaitsecs调整至10分钟之后,再没有出现过类似问题,
因为这几个时候,supervisord对celery master进行warm shutdown
操作之后会等待最多10分钟才会残忍的干掉celery
master,而我辈的通告义务最长不会当先7分钟,因而10秒钟以内warm
shutdown一定会成功,supervisord一定见面临SIG_CHILD信号。


总而言之,以后要么要致密看文档啊。

1. 简介

supervisor有三个零件:supervisord和supervisorctl,组成了client/server结构。

supervisord负责读入配置文件,然后supervisord监管的应用程序以supervisord子进度的艺术启动,supervisord会自动将应用程序的进度转为守护进度,

这么就算你退出shell也没影响。注意,即使一个历程已经是看护进度了,那用supervisord监控时,会出错。

supervisorctl则负责和supervisord举办联系,获取运行中的进度消息,包涵pid,uptime等音讯。supervisorctl既可以经过命令行参数举行支配,又可以

一贯进去一个蓄意的shell,通过这些shell管控进程组。那样,既可以让有些同学纯正把握进程景况,又能避免松开shell权限,一举多得。

 

2. 装置和布局

官网: http://www.supervisord.org/

建议用sudo pip install supervisor来安装,不要用apt-get安装

安装后,用echo_supervisord_conf > ~/supervisord.conf生成配置文件

 

3. 开行和倒闭

启动supervisor: supervisord -c /etc/supervisor/supervisor.conf   #
假设不点名安顿文件,那自动加载/etc/supervisord.conf

一般会安排成开机自启动,所以需要一个init脚本,参见Running supervisord automatically
on
startup
,下载对应你的操作系统的启动脚本就足以了,

只是,里面的情节可能须要修改,比如supervisord和supervisorctl的门径,pid和log的门路与您supervisord.conf中的pid和log路径要一律

关闭supervisor: sudo kill <supervisord进程id>          #
kill默然会发送SIGTERM信号,supervisord收到该信号会,会关闭所有子进度,最终关闭自己,那几个历程可能须要几秒钟

 

4. 配备文件

详见的陈设参见http://www.cnblogs.com/ajianbeyourself/p/5534737.html

supervisord要求监控的经过无法是守护进度。比如要监督nginx,那您要在nginx配置文件nginx.conf中,设置daemon
off

supervisor的布局项有许多,下边是店铺dev环境上的celery_beat应用程序的配备项

[program:celery_beat]
command=python manage.py celery beat --loglevel=info --settings=configs.dev
directory=/home/zhj/work/hera/   ; 执行command前,先跳转到directory
autorestart=true          ; 当进程关闭后,重启,当然,对于用supervisorctl stop xx关闭的进程,不会重启
redirect_stderr=true      ; 重定向程序的标准错误到标准输出 (default false)
startsecs=10              ; 启动后坚持运行多长时间被认为是启动成功了, (def. 1)
stopwaitsecs=30           ; 最长结束等待时间,超过这个时间还没收到子进程的SIGCHLD信号,那就用SIGKILL强制结束子进程 (default 10)
stdout_logfile=/var/log/celery/celery_beat.log
stdout_logfile_maxbytes=50MB
autostart=true            ; 当supervisor启动后,也随之启动

5. supervisorctl命令

相似只有启动supervisor时,用到supervisord命令,其实境况下,用supervisorctl就足以了。

用上面的一声令下进入supervisor shell,
sudo最好增加,不然有可能报错

推行supervisorctl时,配置文件的探寻路径如下

 

  1. $CWD/supervisord.conf
  2. $CWD/etc/supervisord.conf
  3. /etc/supervisord.conf

 

zhj@pc:~$ supervisorctl -c /etc/supervisor/supervisord.conf 
celery_beat                      STOPPED   Not started
celeryworker_celery:0            STOPPED   Not started
celeryworker_celery:1            STOPPED   Not started
celeryworker_email               STOPPED   Not started
supervisor> help

default commands (type help <topic>):
=====================================
add    exit      open  reload  restart   start   tail   
avail  fg        pid   remove  shutdown  status  update 
clear  maintail  quit  reread  signal    stop    version

supervisor> help start
start <name>        Start a process
start <gname>:*        Start all processes in a group
start <name> <name>    Start multiple processes or groups
start all        Start all processes
supervisor> 

上边是supervisorctl命令行下的授命:

status  #查阅supervisord监控的有着进度的情形

celery status  #翻看celery进程的景况

stop xxx   #终止某一个进度(xxx),xxx为[program:theprogramname]里计划的值

start xxx  #启航某个进度

restart xxx  #重启某个进度

stop groupworker  #重启所

stop
all  #为止任何进度,注:start、有属于名为groupworker这一个分组的长河(start,restart同理)restart、stop都不会载入最新的配备文件

reload
  #重启supervisor

update  #基于新型的布置文件,启动新安插或有改动的进程,配置没有改变的进度不会受影响而重启。 当配置文件修改后,要实践那条命令。

                               #彰显用stop甘休掉的经过,尽管配置文件设置了autorestart=true,用reload或者update都不会自行重启。

用supervisor监控celery和celery
beat,配置参数见celery官方文档提供的链接,

http://docs.celeryproject.org/en/latest/tutorials/daemonizing.html#supervisord

 

6. supervisor的log

  在[program:xxx]中,若是设置了numprocs > 1,
这每个进程会利用单独的一个log文件,大家来分析下边的布署。

stdout和stderr文件都是/var/log/celery/celeryworker_celery.log

supervisor会启动八个celeryworker_celery进度(名称分别是celeryworker_celery:0和celeryworker_celery:1),并在启动时创造celeryworker_celery.log

还有celeryworker_celery.log.1 ~
celeryworker_celery.log.5那5个轮转log文件。那三个经过会独家写差其他log文件,不会写到同一个文本,

这是supervisor保证的。celeryworker_celery.log只会被内部一个历程使用,另一个进程会动用celeryworker_celery.log.xx。当celeryworker_celery.log

达到stdout_logfile_maxbytes时,它会被关闭,仁同一视命名为celeryworker_celery.log.1,如若发现celeryworker_celery.log.1已经存在,那就把那

个已存在的celeryworker_celery.log.1重命名为celeryworker_celery.log.2,依次类推。你可以想象有八个水缸并排,在率先个水缸的顶部有一个注水

口,满了后来,将水缸向右推一个岗位,即推到第三个水缸的义务,然后在率先个水缸的义务增添一个新水缸,而最左边的非常水缸被挤出行列。一个注水

口就一定于一个经过,当numprocs>1,即多少个进度时,就是在numprocs个水缸上边各有一个进水口。在

http://supervisord.org/configuration.html\#program-x-section-settings的配置项\`stdout\_logfile\`中提到It
is not possible for two processes

to share a single log file (stdout_logfile) when rotation
(stdout_logfile_maxbytes) is enabled. This will result in the file
being corrupted. 

即当设置了log rotate时,supervisor可以确保每个进程使用差距的log文件

[program:celeryworker_celery]
command=python manage.py celery worker -l info -Q celery -c 1 --settings=configs.local_default
directory=/home/workspace/gikoo/
redirect_stderr=true                     ; 将stderr重定向到stdout
startsecs=10
stopwaitsecs=30
stdout_logfile=/var/log/celery/celeryworker_celery.log
stdout_logfile_maxbytes=3KB
autostart=false
autorestart=false
numprocs=2
process_name=%(process_num)d
stdout_logfile_backups=5

7. 相会的有的题目

不知是如何原因,用supervisor监控celery
worker时,有时会并发僵尸进度,每个celery worker都是一个进度池,

每个进程池有一个main process和一组worker
process,每个main process都是supervisor的子进度。但运用中

发觉,有时会油但是生一些celery进度的父进度是1号经过,当前卫未检查这一个经过是main
process仍然worker process,

猜猜是worker
process的可能性相比大,原因有可能是supervisor关闭celery时,main
process在未曾等待worker 

process关闭的场地下就倒闭了,那样worker
process就没了父进程,1号经过就成了他们的父进度。由于任务的拿走

都是main
process与broker之间进行的,这样的话,这么些1号经过下的worker
process由于不可能与broker通信,所以

也就不会再实施职务了(那块东西待商量)。

 

原文:http://chenxiaoyu.org/2011/05/31/python-supervisor.html

日常会境遇要写一些看护进度,简单做法放入后台:

shell> nohup python xxx.py & 

奇迹那样做仍能接受,如果一堆那样的啊?

本来还有一个题材,就是各个服务,对应的一声令下或者路径都不太相同,比如Apache、MySQL或者其余活动编译的工具。

假定能够统一保管那个应用,是不是很哈皮?

按照规矩现谷歌一把,不失所望找到一个神奇的利器。supervisor!

supervisor地址:http://supervisord.org,官方标语就是:一个经过管理工具。

安装:

sudo pip install supervisor

设置好之后,有八个可执行文件和一个布置文件(平台差别,可能路径不均等):

/usr/bin/supervisord             --  supervisor服务守护进程 

/usr/bin/supervisorctl           --  supervisor服务控制程序,比如:status/start/stop/restart/update等

/etc/supervisor/supervisord.conf  --  配置文件,定义服务名称以及接口等等 

上面来一个示范,用web.py写一个hello的顺序:

import web
urls = (     '/(.*)','hello' ) 
app = web.application(urls, globals())
class hello:     
    def GET(self, name):         
        return 'hello: ' + name 

if __name__ == '__main__':     
    app.run() 

本条时候可以直接开行那一个程序了,上面来布局supervisor,出席管理。修改supervisord.conf,加入如下一些:

[program:hello]
command=python /home/smallfish/hello.py
autorstart=true
stdout_logfile=/home/smallfish/hello.log

地点的趣味应该很简单懂,program后边跟服务的称号,command是先后的举办路径,autorstart是意味着应用程序随supervisor的开行而启动,stdout_logfile是捕获标准输出。

到这边,基本搞定了,上边就是启动管制:

shell> sudo /etc/init.d/supervisor start   -- 启动supervisor服务 
shell> sudo supervisorctl status hello     -- 获取hello服务的状态,因为是autorstart,这里已经启动了 
hello  RUNNING    pid 1159, uptime :20:32 
shell> sudo supervisorctl stop hello       -- 停止hello服务 
hello: stopped 
shell> sudo supervisorctl stop hello       -- 再次停止hello,会有错误信息 hello: ERROR (not running) 
shell> sudo supervisorctl start hello      -- 启动hello服务 hello: started 

OK,基本的操作就是相近这几个了,仔细看supervisord.conf文件里会发现有一段[unix_http_server]的配备,默许是9001端口,可以输入用户名和密码,主要用以Basic
Auth认证用的。

填写一下,然后重启supervisor服务,打开浏览器输入:http://localhost:9001,如图:

882828九五至尊手机版 1

sudo supervisorctl shutdown  #
关闭supervisord,会同时关闭supervisord监控的兼具进度

 

相关文章

Your Comments

近期评论

    功能


    网站地图xml地图