昨天有个服务器出了点小问题,PHP FastCGI 进程无缘无故就死在那里了,造成 Nginx 不能和 FastCGI 通信,不能解析 PHP 页面,只能看到 Nginx 的 默认 HTML 页面。登录到服务器检查日志也没有找到原因,重启 FastCGI 后恢复正常。服务器上装了 monit,如果服务关闭的话会自动重启,但是这里 FastCGI 服务并没有关闭,只不过由于某种原因不能和 Nginx 通信,所以 monit 误认为 FastCGI 运行正常没有执行重启 FastCGI 的命令。

今天写了一个 Python 脚本用来后台监测 nginx 的日志,如果在日志里发现 111: Connection refused 或者 104: Connection reset by peer 等错误就 kill 掉所有 php-cgi 进程后重启服务。程序有几个地方需要说明:

1、如果不先 kill 直接运行 /etc/init.d/php-cgi restart 重启服务有时候不管用,因为这时候 php-cgi 只是驻留在内存里的死进程而而已不能执行任何命令,所以需要 kill 全部 php-cgi 进程后再启动;

2、读 nginx 的 log 文件的时候要小心,log 文件通常很大,如果用 python 的普通读文件函数会把整个文件读出来后再处理,速度很慢,也会占用大量内存,所以最好用 tail 截取文件,我们只需要分析最后部分(也是最近)的记录即可;

3、程序通过 /var/run/php_cgi.pid 来判断 PHP FastCGI 是否正在运行,通过 /var/log/nginx/error.log 来判断 Nginx/FastCGI 是否工作正常,每600秒检查一次,如果工作不正常 sleep 2秒后重启 php-cgi;

4、本程序可扩展到重启其他服务,比如通过 /var/run/lighttpd.pid 来判断 lighttpd 是否需要重启;

5、程序中 daemonize 函数来自 Python Cookbook(O’Reilly ) 一书。

程序使用

拷贝下面代码做一定修改以后保存为 checkphpcgi,增加文件可执行权限后用 root 运行程序:

# chmod +x checkphpcgi

# ./checkphpcgi

usage: ./checkphpcgi start|stop|restart

# ./checkphpcgi start

如果想要停止程序:

# ./checkphpcgi stop

程序代码

#!/usr/bin/python

# Monitoring PHP/FastCGI processes, restart FastCGI if they:

# 1. crashed or

# 2. simply cannot communicate with Nginx

#

# written by http://www.vpsee.com

import sys, os, time

from signal import SIGTERM

pidfile = '/var/run/checkphpcgi.pid'

phpcgi_pidfile = '/var/run/php_cgi.pid'

phpcgi_command = '/etc/init.d/php_cgi restart'

nginx_logfile = '/var/log/nginx/error.log'

kill_phpcgi = 'killall -9 php-cgi'

def main():

argc = len(sys.argv)

if argc != 2:

print "usage: ./checkphpcgi start|stop|restart"

sys.exit(0)

action = sys.argv[1]

if action == 'start':

start()

elif action == 'stop':

stop()

elif action == 'restart':

stop()

start()

def start():

daemonize()

while True:

try:

f = file(phpcgi_pidfile, 'r')

pid = int(f.read().strip())

f.close()

except IOError:

pid = None

if not pid:

os.system(phpcgi_command)

elif pid > 0:

log = '/usr/bin/tail ' + nginx_logfile + ' > /tmp/nginx.log'

os.system(log)

f = file('/tmp/nginx.log')

text = f.read()

if text.find("111: Connection refused") or text.find("104: Connection reset by peer"):

os.system(kill_phpcgi)

time.sleep(2)

os.system(phpcgi_command)

f.close

os.remove('/tmp/nginx.log')

time.sleep(600)

def stop():

try:

f = file(pidfile, 'r')

pid = int(f.read().strip())

f.close()

except IOError:

pid = None

return

try:

os.kill(pid, SIGTERM)

os.remove(pidfile)

except OSError, err:

sys.stderr.write("not found checkphpcgi\n")

def daemonize(stdin = '/dev/null', stdout = 'dev/null', stderr='/dev/null'):

try:

pid = os.fork()

if pid > 0:

sys.exit(0)

except OSError, e:

sys.stderr.write("fork failed\n")

sys.exit(1)

os.chdir("/")

os.umask(0)

os.setsid()

try:

pid = os.fork()

if pid > 0:

sys.exit(0)

except OSError, e:

sys.stderr.write("fork failed\n")

sys.exit(1)

sys.stdout.flush()

sys.stderr.flush()

si = file(stdin, 'r')

so = file(stdout, 'a+')

se = file(stderr, 'a+', 0)

os.dup2(si.fileno(), sys.stdin.fileno())

os.dup2(so.fileno(), sys.stdout.fileno())

os.dup2(se.fileno(), sys.stderr.fileno())

f = open(pidfile, "w")

f.write("%d" % os.getpid())

f.close()

if __name__=="__main__":

main()

php-cgi 重启,自动监测和重启 FastCGI 服务相关推荐

  1. 服务器知识:终端连接Linux服务器、重启服务器、重启服务

    在开发过程中,维护服务器的时候,遇到死机的时候,通过电脑终端连接到服务器,重启服务器:在服务器上面部署的服务,有些时候会卡死,也需要重启服务.不管是Mac电脑还是Windows电脑,终端连接Linux ...

  2. python 重启程序_python重启程序

    广告关闭 腾讯云11.11云上盛惠 ,精选热门产品助力上云,云服务器首年88元起,买的越多返的越多,最高返5000元! # 重启程序 def restart_program():print(重启... ...

  3. 服务器系统日志关机重启,服务器关机重启日志

    服务器关机重启日志 内容精选 换一换 云监控服务为用户提供一个针对弹性云服务器.带宽等资源的立体化监控平台.使您全面了解云上的资源使用情况.业务的运行状况,并及时收到异常告警做出反应,保证业务顺畅运行 ...

  4. linux 如何重启oracle,Linux重启oracle数据库的三大技巧

    Linux系统下网站出现问题的时候,可通过重启oracle数据库进行处理,而重启oracle数据库的方法有好多种,可登陆数据库进行操作,也可在终端操作,具体的随小编一起来了解下吧. 网站的服务中断了, ...

  5. ubuntu 重启命令,ubuntu 重启网卡方法 修改DNS 不生效处理

     ubuntu 重启命令,ubuntu 重启网卡方法 ubuntu 重启命令 重启命令: 1.reboot 2.shutdown -r now 立刻重启(root用户使用) 3.shutdown  ...

  6. 重启php软重启_重启PHP命令

    Ubuntu重启关机命令使用 如果你想保持当前用户的登录而且使用root用户执行命令 可以输入:su root,输入密码 可以运行,shutdown 命令 重启命令: 1.reboot 2.shutd ...

  7. 共享服务器不能远程重启,彻底解决服务器重启失败或重启缓慢无法远程的问题...

    服务器在日常管理中,由于某种原因导致运行缓慢,或者是服务器在安装了某些软件后,需要执行重启来完成安装.重启服务器也是服务器日常维护中,所占比例最大的,但是,由于独立服务器不像VPS或云服务器一样,提供 ...

  8. 软重启、硬重启、重启、重置概念介绍

    转自:微点阅读  https://www.weidianyuedu.com 如果你使用的是Windows电脑,甚至是手机,我相信你已经听说过所有这些术语.虽然它们听起来很相似,但是它们之间还是有区别的 ...

  9. iphone快捷指令一键重启_一键重启捷径怎么设置 一键重启捷径设置教程

    一键重启捷径怎么设置?相信很多小伙伴都还不是很清楚吧,下面小编就为大家带来一键重启捷径设置教程.感兴趣的小伙伴们随小编一起来看看吧,希望对大家能有所帮助. 那么一键重启捷径怎么制作呢?接下来看看IT数 ...

最新文章

  1. DataGridView使用技巧十一:DataGridView用户输入时,单元格输入值的设定
  2. zbb20170824 oracle expdp/impdp 导入导出数据
  3. 广东白云机场俯视图,猜猜像什么
  4. 三十五、深入Java中的泛型(下篇)
  5. android studio 如何导入工程文件,Android studio如何导入已有的eclipse工程
  6. python 抓网卡数据包_Python选择网卡发包及接收数据包
  7. Python之Pandas库
  8. 【Python学习笔记】Coursera之PY4E学习笔记——String
  9. 如何编写一个抢购bot_如何编写一个SkyWalking插件
  10. 初识 Node.js
  11. 【Altium Designer2018设计简单的PCB文件实例】
  12. vue下载文件流图片
  13. Lync 2010升级到Lync 2013POC计划-过程!
  14. 用php制作抖音视频去水印小程序?
  15. Web Science笔记 Emotion, Event detection
  16. nginx: [emerg] could not build server_names_hash
  17. 什么是power bi
  18. python数据分析设置教程视频_炼数成金女讲师Python数据分析实战应用视频教程
  19. vue3 + vite + ts 设置 @ 路径别名
  20. 快乐共享(By Robinvane Suen)

热门文章

  1. LeetCode简单题之找到所有数组中消失的数字
  2. 深度学习编译与优化Deep Learning Compiler and Optimizer
  3. 目标检测coco数据集点滴介绍
  4. Android App的启动过程
  5. Cocos生命周期回调
  6. [JAVAEE] Thymeleaf 基本语法: 迭代循环
  7. SCOI2009 最长距离
  8. 大话设计模式笔记(七)の原型模式
  9. 使用docker Hub
  10. offsetof使用小结