本人之前在linux上写的一段PHP代码(逻辑是用PHP实现对数据库中日志文件的转移,运行是shell脚本运行),为什么挂掉后(不能正常转移数据库中的数据),进程却还在,根本就看不出来他挂掉。具体的PHP代码如下:
/**
* 测试
*/
class PaizuTableHandler extends ScriptBase
{
public static $mysql = null;
const LOG_PAIZU_TABLE = 'log_user_paiju';
public function logic()
{
if(empty(self::$mysql)){
self::$mysql = $this->mysql('logs');
}
set_time_limit(0);
while (true)
{
$date = date("Y-m-d");
$dataTime = strtotime($date);
$timestampStart = $dataTime - 3600*24; //昨天
$timestampEnd = mktime(0,0,0,date("m"),1,date("Y"));//本月月初 例如:2017-07-01 00:00:00
$timestampEnd_lastmoth = mktime(0, 0 , 0,date("m")-1,1,date("Y"));//上月月初 例如:2017-06-01 00:00:00
if($timestampStart < $timestampEnd){
sleep(60);
continue;
}
$table = self::LOG_PAIZU_TABLE.'_'.date("Ym");//本月的表
$lastMothTable = self::LOG_PAIZU_TABLE.'_'.date("Ym",mktime(0, 0 , 0,date("m")-1,1,date("Y")));//上个月的表
$hasTable = self::$mysql->tableExists($table); //判断是否有本月的表
$hasTableLast = self::$mysql->tableExists($lastMothTable); //判断是否有上个月的表
$createFlag = $hasTable ? true : false; //本月的表是否存在
$createFlagLast = $hasTableLast ? true : false; //上个月的表是否存在
if( empty( $createFlag ) ){
//创建表
$createSql = "CREATE TABLE {$table} LIKE log_user_paiju";
$createFlag = self::$mysql->query($createSql);
}
if( $createFlag ){
//查询本月当天应清空数据有没有清空
$sql = "select * from log_user_paiju where UNIX_TIMESTAMP(`time`) between {$timestampEnd} and {$timestampStart} order by `time` desc limit 100";
$result = self::$mysql->query($sql);
$rs = self::$mysql -> fetch_row($result);
if( !$result ){
break;
exit(0);
}
$date = date("Y-m-d");
$current_time = strtotime($date); //当前时间戳
$current_time2 = mktime(0,0,0,date("m"),6,date("Y")); //月初第6天
$last_rs = array(); //添加于2017.10.25
if($current_time == $current_time2 && !empty( $createFlagLast ) && empty($rs)){
//本月第6天把 上个月的数据全部放到上个月的表中(要放最少2天前)
$last_sql = "select * from log_user_paiju where UNIX_TIMESTAMP(`time`) between {$timestampEnd_lastmoth} and {$timestampEnd} order by `time` desc limit 100";
$last_sql1 = "INSERT INTO {$lastMothTable}(uid,paiju_score,paizu_score,`time`,paizu_id,seq,room_id,server_id,creator,`status`,mahjongType) SELECT uid,paiju_score,paizu_score,`time`,paizu_id,seq,room_id,server_id,creator,`status`,mahjongType FROM log_user_paiju where UNIX_TIMESTAMP(`time`) between {$timestampEnd_lastmoth} and {$timestampEnd} order by `time` desc limit 100";
$last_sql2 = "delete from log_user_paiju where UNIX_TIMESTAMP(`time`) between {$timestampEnd_lastmoth} and {$timestampEnd} order by `time` desc limit 100";
$result1 = self::$mysql->query($last_sql);
$last_rs = self::$mysql -> fetch_row($result1);
if($last_rs){
if($r = self::$mysql->query($last_sql1)){
self::$mysql->query($last_sql2);
}
}
}
$sql1 = "INSERT INTO {$table}(uid,paiju_score,paizu_score,`time`,paizu_id,seq,room_id,server_id,creator,`status`,mahjongType) SELECT uid,paiju_score,paizu_score,`time`,paizu_id,seq,room_id,server_id,creator,`status`,mahjongType FROM log_user_paiju where UNIX_TIMESTAMP(`time`) between {$timestampEnd} and {$timestampStart} order by `time` desc limit 100";
$sql2 = "delete from log_user_paiju where UNIX_TIMESTAMP(`time`) between {$timestampEnd} and {$timestampStart} order by `time` desc limit 100";
if(empty($rs) && empty($last_rs)){
sleep(60);
}
if($rs){
if($r1=self::$mysql->query($sql1)){
!self::$mysql->query($sql2);
}
}
}
usleep(3000);
}
}
}
====================================分割线================================
shell脚本如下:
#!/bin/sh
# scripts daemon, add to /etc/crontab
# */1 * * * * root PATH/script.sh --daemon
# run on root
if [ "$(uname -s|grep -F 'CYGWIN')" = "" ] && [ $UID -ne 0 ]; then
echo "superuser privileges are required to run this script."
exit 1
fi
# settings
PHP_CLI="/usr/bin/php -c /etc/php.ini"
SCRIPTS="PaizuTableHandler"
# paths
BASE_PATH=$(cd $(dirname $0) && pwd)
BASE_SCRIPT="$BASE_PATH/script.php"
LOGS_PATH="$BASE_PATH/data/logs/bash.log"
USAGE="Usage: $(basename $0) [-d|-a|-k SCRIPT]\n\
-d, --daemon\t\tthe daemon mode, runing checking\n\
-a, --killall\t\tkill the all scripts\n\
-k, --kill SCRIPT\tkill the SCRIPT\n\
-h, --help\t\tthis help text"
function get_pid()
{
echo $(ps -ef|grep -F "$1"|grep -v "grep"|awk '{print $2}')
}
function kill_script()
{
PID=$(get_pid "$1")
if [ "$PID" = "" ]; then
echo "$1 not found"
else
kill -9 $PID
echo "$1 has been killed, pid: $PID"
fi
}
case $1 in
-k|--kill)
if [ "$2" = "" ]; then
echo -e $USAGE
exit 0
fi
kill_script "$BASE_SCRIPT request/$2"
;;
-a|--killall)
for SCRIPT in $SCRIPTS; do
kill_script "$BASE_SCRIPT request/$SCRIPT"
done
;;
-d|--daemon)
for SCRIPT in $SCRIPTS; do
SCRIPT="$BASE_SCRIPT request/$SCRIPT"
PID=$(get_pid "$SCRIPT")
if [ "$PID" = "" ]; then
eval "$PHP_CLI $SCRIPT >/dev/null 2>&1 &"
PID=$(get_pid "$SCRIPT")
echo "[$(date +%Y-%m-%d\ %H:%M:%S)] $SCRIPT has been down, restarted: $PID" >> $LOGS_PATH
fi
done
;;
*)
echo -e $USAGE
;;
esac
crontab 一分钟执行一次
shell
,shell
case 倒数第一个,然后你把标准输出标准错误重定向了/dev/null
,话说,挂掉后(不能正常转移数据库中的数据)的处理逻辑在哪里呢?PHP抛异常不算挂掉哈,你的shell会继续唤起的