一看就懂系列之 如何实现与控制php常驻进程
版权声明:本文为博主原创文章,未经博主允许不得转载。
目录(?)[+]
前言
关于如何实现与控制php常驻进程,不管是google还是baidu上进行搜索,都没有感觉看起来赏心悦目的解答,于是决定自己动手总结下。
有同学会问了,整这个干甚?简单的说就是,可以让一个php脚本一直处于运行的状态。从而实现将项目中某些耗时操作异步化,进队列后由php脚本取出再执行。
有同学又会问了,直接在服务器直接命令“php test.php &”,不就可以实现了?那么这样做的话有三点还需要考虑:1.如何保证此进程的稳定性(挂了怎么办)2.如果想开10个进程,手动去执行10回好像不怎么友好。3.关闭的话需要手动杀死进程?
有同学又会问了,这个不是在crontab加一个定时任务从而一直去执行不就好了,而且保证了稳定性。准确地说这也是可以的,但是有三点需要考虑:1.每回新增队列都要加一回crontab真的好吗。2.还是开10的进程问题(同上)。3.那要是关闭的话还要去备注crontab任务?
所以本文所设计的方案主要解决以下几个问题:
1.如果实现php的常驻?(不依赖第三方php扩展)
2.如何保证进程的稳定性(谁来守护的问题)?
3.如何方便的管理php进程的关闭与重启?
4.如何方便的管理php进程的并发数?
5.如何进行对php进程的监控?
正文
demo文件描述
cron_demo
1.cron_watchdog.sh:用于添加以及调起php进程
2.cron_watchdogd.sh:用于监控cron_watchdog.sh,保证其一直在运行
3.cron_zombie_alert.sh:用于进程文件的扫描监控,与错误通知。
privdata/cron_demo
cron_count.ini:用于控制php进程的并发数
cron_switch.ini:用于控制php进程的开关
cron_status/ :用于存在标记php进程的pid,以供cron_zombie_alert.sh扫描
cron_kill.log:用于记录cron_zombie_alert.sh扫描到并且kill的僵尸进程。
由于是一看就懂系列,故具体文件解析会附带上详细的解读。
cron_watchdog.sh的实现与解读
代码实现
#!/bin/bash
#该脚本需在bash版本>=4中执行
#输出当前地址
CRON_DIR=$(cd $(dirname "$0"); pwd)
#执行进程监控脚本的命令
zombie_alert_cmd="/bin/sh $CRON_DIR/cron_zombie_alert.sh& > /dev/null"
#获取php进程并发数配置
CRON_COUNT_INI=/www/privdata/cron_demo/config/cron_count.ini
echo $CRON_COUNT_INI#此类写法需要bash版本>4的支持。(如果mac默认3.x,所以不支持)
declare -A deamon_map#key 为cron_count里的key value为命令脚本地址
deamon_map["test"]="$CRON_DIR/test.php"while true; do#循环执行deamon_map里的命令for deamon_count_key in "${!deamon_map[@]}" ; doecho $deamon_count_key#计算出配置文件里面php进程的并发数SUM=`grep "^$deamon_count_key *=" "$CRON_COUNT_INI" | awk '{print $3}'`#若在cron_count.ini中不存在,则默认赋值队列并发数1if ! (echo $SUM | egrep -q '^[0-9]+$'); thenSUM=1 fiphp_script="${deamon_map["$deamon_count_key"]}"#计算当前运行中的php进程数目proc=`/bin/ps xaww | grep -v " grep" | grep "$php_script" |wc -l`current_count=$proc#若小于进程的配置数,则进行调起if [ $current_count -lt "$SUM" ];thenneed_to_open_count=`expr $SUM - $current_count`while [ $need_to_open_count -gt 0 ]dophp "$php_script" &(( need_to_open_count-- ))donefidone#php进程的监控与消息通知eval "$zombie_alert_cmd"sleep 1
done
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
shell关键点解读
1.ps xaww:
a 显示终端上地所有进程,包括其他用户地进程
x 显示没有控制终端地进程
ww 避免详细参数被截断;
2.${!arr[@]} 用于返回数组array的所有下标
3.deamon_map[“test”]=”$CRON_DIR/test.php”
用于添加cron任务,test为脚本在cron_count.ini里面的标号(这里设置为php脚本文件名),test.php为所需要执行的php脚本。
解决问题
1.进程添加问题,只需在此处添加一行配置即可。
2.进程并发管理问题,只需在cron_count.ini配置即可。
cron_watchdogd.sh的实现与解读
代码实现
#!/bin/sh
CRON_DIR=$(cd $(dirname "$0"); pwd)
cmd="/bin/sh $CRON_DIR/cron_watchdog.sh& > /dev/null"
#检测cron_watchdog.sh是否在执行
proc=`/bin/ps xaww | grep -v " grep" | grep -- "cron_watchdog.sh"`
#根据返回结果进行判断脚本是否执行
if test -z "$proc"
then#若不执行,那么就调起命令执行eval "$cmd"
fi
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
此外需要在/etc/crontab中添加以下命令,以保证此脚本定时都会去检测一回。
*/1 * * * * root sh /www/cron_demo/cron_watchdogd.sh > /dev/null 2>&1
- 1
- 2
shell关键点解读
1.grep -v:逆向输出. 打印不匹配模式的行
2.test –z 字符串:测试字符串的长度是否为零
3.eval
此命令会执行两回后续的语句,在这里,第一回先翻译"$cmd"成"/bin/sh $CRON_DIR/cron_watchdog.sh& > /dev/null",第二回在进行执行这个命令
解决问题
1.cron_watchdog.sh脚本的监控,保证其不死掉
cron_zombie_alert.sh的实现与解读
代码实现
#!/bin/sh
PID_LOG=/www/privdata/cron_demo/cron_status/
KILL_LOG=/www/privdata/cron_demo/log/cron_kill.log
#用于检测30分钟未进行更新的进程文件。
Minute=30#PID_LOG
cd "$PID_LOG"
if [ "$?" == 0 ];then#若进程文件30分钟没进行更新则认为已经僵死,需要kill并报警for pid in `find ./ -mmin +"$Minute"| grep -v /$ | awk -F '/' '{print $2}'`doif [ "$pid" != '' ];thenNOW=`date +%Y-%m-%d_%H:%M`HOSTNAME=`hostname`nl=''PROCESS=`ps p$pid fuh`if [ "$PROCESS" != '' ];thenPSTACK=`pstack $pid`#将pid进程信息输出到tmp.out文件,若2秒之后还在运行再kill此进程TMP=`timeout 2 strace -p $pid -o tmp.out`STRACE=`cat tmp.out`rm tmp.outfi#组织报警消息message="$NOW $HOSTNAME zombie process id $pid $nl$PROCESS$nl$PSTACK$nl$STRACE--"echo "$message">>"$KILL_LOG"#kill "$pid"cd "$PID_LOG"#同时删除进程文件rm -r "$pid"#进行邮件或者其他的形式将message的内容同步出去fidone
fi
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
shell关键点解读
1.timeout:
timeout [选项] 数字[后缀] 命令 [参数]...
或:timeout [选项]
运行指定命令,如果在指定时间后仍在运行则杀死该进程。
后缀"s"代表秒(默认值),"m"代表分,"h"代表小时,"d"代表天。
2.strace:
-f :除了跟踪当前进程外,还跟踪其子进程。
-o file :将输出信息写到文件file中,而不是显示到标准错误输出(stderr)。
-p pid :绑定到一个由pid对应的正在运行的进程。此参数常用来调试后台进程。
解决问题
1.cron_status底下进程文件的管理。
2.处理php进程僵死的情况。发出相应报警信息。
简单的例子
用于测试的php脚本片段。主要实现功能:每隔10秒输出数字到tset_cron.log日志。
<?php
define('ROOT_PATH', dirname(__FILE__));
//一些初始化操作,常量定义以及公共函数的引入
include(ROOT_PATH . '/cron_init.php');
$log_file = LOG_DIR . '/test_cron.log';//获取进程pid
$pid_status_log = CRON_STATUS_DIR . '/' . getmypid();
$i = 0;
while (true) {// 将其放入cron_status中以供检测file_put_contents($pid_status_log, 1);//从cron_switch.ini中来判断此进程是否开启,这个函数后面会单独解析$cron_flag = cron_switch(TEST_CRON_KEY);//若关闭则删掉进程文件if (!$cron_flag) {unlink($pid_status_log);exit();}// 可从队列中取出数据进行处理// 这里作为例子,以记录一个日志好了$msg = $i ."\n";file_put_contents($log_file, $msg, FILE_APPEND);sleep(10);$i++;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
cron_switch函数
function cron_switch($task = 'all') {//解析cron_switch.ini文件$cron_switch = parse_ini_file(CRON_SWITCH_FILE);if ($task == 'all') {return $cron_switch;} else {$task = str_replace(KEY_PREFIX, '', $task);$current_cron_switch = $cron_switch [$task];//第二个判断用于重启进程之用。只要将cron_switch的数字设置大一点则认为重启,设置为0代表关闭,1代表开启。if($GLOBALS['current_cron_switch'] && $GLOBALS['current_cron_switch']<$current_cron_switch){//若小于当前配置文件$current_cron_switch = 0;}if($current_cron_switch){//全局标记当前的cron_switch值,用于当作重启的标志$GLOBALS['current_cron_switch'] = $current_cron_switch;}return $current_cron_switch;}}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
开始运行啦
加好定时任务后发现:
日志每隔10s输出一个数字了。此时将此php进程kill掉,马上发现,有重现开始跑了。
此时:
现在试试进程数设置为2(cron_count.ini设置“test = 2”),会发现以上命令后,进程数会变为2个。(这里不截图了,因为很晚了)
代码demo
cron_demo
demo地址:https://github.com/supcbs/cron_demo
来源:http://blog.csdn.net/u011957758/article/details/52519748
一看就懂系列之 如何实现与控制php常驻进程相关推荐
- 如何管理php常驻进程,一看就懂系列之 如何实现与控制php常驻进程-Go语言中文社区...
前言 关于如何实现与控制php常驻进程,不管是google还是baidu上进行搜索,都没有感觉看起来赏心悦目的解答,于是决定自己动手总结下. 有同学会问了,整这个干甚?简单的说就是,可以让一个php脚 ...
- php 设计模式系列,一看就懂系列之 php设计模式(一)-Go语言中文社区
前言 一提到设计模式,很多人都是敬而远之,一方面由于设计模式有一点忽悠太理论的感觉,另一方面也会觉得设计模式有点难懂不知道该在什么场景下使用.一看就懂系列之php设计模式,主要解决两个问题: 1.用最 ...
- 一看就懂系列之Golang的pprof
前言 这是一篇给网友的文章,正好最近在研究分析golang的性能,我觉得是时候来一个了断了. 正文 1.一句话简介 Golang自带的一款开箱即用的性能监控和分析工具. (全篇看的过程中没必要特意记忆 ...
- C++----字符集详解(一看就懂系列)
关注微信公众号"二进制小站"~~获取更多分析~~(文末二维码~~) 写的太好,不敢更改:https://blog.csdn.net/qq_28098067/article/deta ...
- 一看就懂系列:java8流的扁平化/什么是扁平化流(图解)
<java8实战>这本书上,关于刘的扁平化的讲解,个人觉得有点费解.我也是读完,回味了好多遍才理解. 其实我觉得作者的图解不太直观,接下来,我会重新画一张图,方便大家理解. 什么是扁平化流 ...
- single-shot detection(SSD)目标检测算法详解——(一看就懂系列!!!)
SSD是One-stage系列的优秀算法之一 one-stage的意思是挑选候选框和预测候选框两步是同时完成的,R-CNN家族都是two-stage. SSD有什么创新点? (1)基于Faster-R ...
- 什么叫做装箱和拆箱?一看就懂系列
有很多同学对与装箱和拆箱还是有点搞不太明白. 首先讲一下概念: 1.装箱指的是把值类型转化为引用类型 2.拆箱当然指的就是把引用类型转化为值类型 估计很多同学可能还分不清哪些是属于引用类型和值类型,这 ...
- Python一看就懂系列(三)
专栏: python轻奢入门系列 作者: 豆破苍琼 [字符串] 字符串介绍 字符串格式 被单引号或者双引号括起来的数据就是字符串. 字符串输出 """ 字符串输出 &qu ...
- Python一看就懂系列(四)
专栏: python轻奢入门系列 作者: 豆破苍琼 [函数] 基本知识 定义 函数可以理解为创建一个具有某种用途的工具.使用def关键字来实现. 调用 def introduce():name = i ...
最新文章
- vs2008 ActiveX控件测试容器的生成以及调试ActiveX控件
- ssh 别名登录小技巧
- Freemarker介绍
- 【本站原创】台大林轩田《机器学习基石》系列课程教材的习题解答和实现
- sql2000数据类型对应的数值_Qlikview---数据类型
- ios开发 将json格式数据上传服务器
- mysql怎么找出树形的根节点,Oracle 层级语句 树形结构 显示根节点 不显示根节点...
- 基于ASP.NETAJAX的WebPart开发与部署-转
- Element UI踩坑记 —— el-table中 formatter 的属性居然失效了
- 安卓开发要学多久_开发微信小程序需要多久?流程有哪些?
- 整除光棍 — C语言【模拟手算除法(附过程图解)】
- 不是吧,还有人不会做国庆头像小程序(可开通流量主,赚零花钱)
- 向量个数,向量维数,向量空间维数
- 如何系统地学习网络安全
- Sdkman运行时INTERNET NOT REACHABLE问题和解决
- uniapp——操作成功返回首页
- 【测试用例练习】二、手机app测试点
- 微信小程序——给用户发送通知
- OutputStream的flush()方法
- Python ABC(抽象基类)
热门文章
- python内置函数表_python学习系列--python内置函数(一)
- MongoDB配置参数说明
- Eclipse Memory Analyzer以及内存泄露的原因
- 【python-numpy】工具包中np.random.choice()的用法详解及其参考
- 3DSlicer相关资料汇总
- Qt学习笔记之数据库
- ImportError: No module named _tkinter, please install the python-tk package ubuntu运行tkinter错误
- 甲骨文中国公司如何如何打赢这场裁员翻身仗?
- JAVA-抽象类/类继承
- Vsftpd文件传输服务(本地用户访问)