在尝试了 docker 和 supervisor 之后,感觉我目前的使用场景下 supervisor 更加便捷,之前的 nginx 和 uwsgi 都是通过 daemon 的方式挂在后台,然后加一个挂在 crond 上的脚本来当看门狗,觉得这样还是不太规范,于是将这两个服务都搬到 supervisor 上了,不过和其他大部分的任务不同,这两个都自带了 daemon ,所以需要一些修改,在此记录
一般情况下,supervisor 用如下九行都足够了,其中第 4 和第 9 行不是必须的,在前文 基于Centos7+Flask+Nginx+uWSGI+Python3的服务器网页搭建教程 中,直接开启uwsgi的代码中有 -d /root/uwsgi.log 一个参数,其中 -d 表示 daemon ,在用 supervisor 时不能添加此参数,去除后 log 在 stdout_logfile 中输出,路径可以自行修改
/etc/supervisord.d/uwsgi.ini
1 [program:uwsgi_supervisor] 2 stdout_logfile=/root/flask/log/uwsgi_supervisor.out.log 3 stderr_logfile=/root/flask/log/uwsgi_supervisor.out.err 4 directory=/usr/local/bin 5 command=/usr/local/bin/uwsgi --ini /root/uwsgi.ini 6 user=root 7 autostart=true 8 autorestart=true 9 redirect_stderr=true
同理,nginx也需要关闭daemon,方法为添加参数 -g 'daemon off;'
/etc/supervisord.d/nginx.ini
1 [program:nginx_supervisor] 2 stdout_logfile=/root/flask/log/nginx_supervisor.out.log 3 stderr_logfile=/root/flask/log/nginx_supervisor.out.err 4 directory=/usr/local/nginx/sbin 5 command=/usr/local/nginx/sbin/nginx -g 'daemon off;' -c /usr/local/nginx/conf/nginx.conf 6 user=root 7 autostart=true 8 autorestart=true 9 redirect_stderr=true
文件名可以自行更改,保证路径正确即可,在新增两个文件后,如果已经开启了nginx和uwsgi,需要关闭,否则会提示端口已经占用
killall -9 uwsgi
killall -9 nginx
然后更新supervisor,就可以在web管理器上看到了
supervisorctl update
如果出现了fatal error,分析下日志一般都能找到问题所在
而在daemon方式部署uwsgi中,滚动日志是比较麻烦的,因为如果直接修改log文件会导致uwsgi不再写入log,因此需要触发重新写入,而笔者是用python对所有日志进行自动整理,因此做了个小的取巧,即关闭uwsgi,重命名和归档之后重新打开uwsgi,实际上几乎感知不到,但是这终归不是很好的解决办法,而用supervisor托管之后就不存在这个问题了,因为supervisor的日志是可以直接用logrotate滚动的,直接创建任务文件
/etc/logrotate.d/uwsgi
/root/flask/log/uwsgi_supervisor.out.log { daily copytruncate rotate 60 dateext missingok notifempty nocompress postrotate endscript }
注意文件中的路径需要和上面的路径匹配,这是一个很简单的logrotate模板,解释如下,如需更多命令可以自行查找
daily 每日触发 copytruncate 复制后清空原文件而不是新建文件,对应的是create命令 rotate 60 保留60份日志,即两个月日志,如果不添加这一行,历史日志就没了 dateext 使用日期作为扩展名 missingok 忽略错误,如文件不存在 notifempty 忽略空文件 nocompress 不需要压缩 postrotate endscript 这两个命令之间可以添加一段脚本,在执行完滚动日志之后执行,比如重启服务或移动日志
至此,可以用 logrotate -v /etc/logrotate.d/uwsgi 命令尝试手动执行一次,当然,你会发现,有输出,但没有任何反应(
问题在于,文件路径不在 /var/log 下,selinux阻止了操作,于是方法1,将log改到 /var/log 下,笔者没试过是否可以做到,方法2,增加log文件标识,笔者也没有试过,方法可以自行查找,方法3, -f 啦,没有什么事情是强制执行不能解决的啦,修改文件
/etc/cron.daily/logrotate
#!/bin/sh /usr/sbin/logrotate -f -s /var/lib/logrotate/logrotate.status /etc/logrotate.conf EXITVALUE=$? if [ $EXITVALUE != 0 ]; then /usr/bin/logger -t logrotate "ALERT exited abnormally with [$EXITVALUE]" fi exit 0
新增强制执行,就不存在任何障碍了,当然,觉得这样不太好的话可以用 crontab -e 新增上述手动执行的带 -f 的命令,定期“手动”执行即可,此外,cron.daily中的命令带了 -s ,意为使用status文件来记录上次的滚动情况
感谢
运维工作笔记 https://www.cnblogs.com/he-ding/p/10270268.html