php虚拟主机下实现定时任务(仅供参考)
因为要做简单的中控 在实现心跳包的时候遇到了困难 正常的心跳包思路是这样的 举个例子 我写一个登陆签到脚本 当我登陆成功的时候 会把登陆成功这个状态传递给网络上的中控端 当我签到完成的时候会把签到成功的脚本状态传递给网络上的中控端 这样 我们在中控那边就可以清晰的看到当前脚本运行到哪个部分 如果脚本停止 以安卓按键为准会触发一个 OnScriptExit 事件 我们只需要在这个事件里面写上代码 当触发这个事件的时候 我们就给中控端发送下脚本状态为close 或者stop的状态信息 中控端就可以清楚脚本当前具体是处于什么状态 但是这个只是理想化状态 因为 有的时候脚本未必是正常关闭的 这样会导致 在中控端 因为迟迟收不到脚本的最新消息 当前脚本状态无法变化 看起来还在运行 但是实际上已经脚本崩溃导致问题,后来想到了心跳包 就是多开1个线程 间隔一会就向中控端发送信息 来让中控端知道 我这个脚本还在运行 如果超出一定时间内 中控端再也没接收到这个脚本的心跳包 那么中控端就会判定该脚本已经关闭
要解决的问题:从实际上来说 我们中控端有一个额外的操作 就是 间隔一定的时间 就搜索下数据库里面 所有的脚本记录 看看每个记录的最新记录时间和当前时间 相差多少 如果相差太多 就直接让这个记录对应的脚本状态设置了close或者stop 保证应对脚本异常关闭的情况 这也是这个文章的主要要解决的问题
思路:因为是虚拟主机 不是真正的主机 如果是真正的主机 那么可以考虑的办法相当的多 也无需像我这样费尽心机 比如可以用主机系统的计划任务来定时执行某些数据库操作 也可以用mysql的超级管理员的一些功能来实现定时任务 。百度了下 获得了一些基本思路 这些思路无非就是使用 ignore_user_abort(); //函数设置与客户机断开是否会终止脚本 set_time_limit(0); 实现一个无限死循环 在这个死循环里面 我们可以通过sleep进行适当的延迟间隔 来进行一定的操作 但是当我实际的来写代码的时候发现一些原来没有考虑过的问题
产生的新问题:
1.我们访问一次这个特殊页面就开启一个无限死循环(定时任务) 如果开启多个 那么对整个服务器的资源消耗是巨大的 非常影响网站的正常访问 所以我们必须要采取措施让这个无限死循环(定时任务)只能存在1个
2 我们需要有一个开关来控制这个无限循环 开启无限循环(定时任务)我们可以访问特殊页面开启 但是 关闭这个无限循环(定时任务) 我们也需要1个开关来控制 ----->用一个txt的内容来控制关闭
3.我们访问这个特殊页面后就开启了无限死循环(定时任务) 我们可以关闭这个特殊页面 但是这个无限死循环会一直执行下去 我们不清楚这个无限死循环(定时任务)都在干什么 都在忙什么 就算无限死循环(定时任务)出了问题 我们也不清楚 –-->专门做了一个简单的定时任务日志来监控 这个无限循环(定时任务)的运行情况
网页文件结构
browse_log.php 是日志文件 专门用来记录当天的定时任务的运行反馈
timed_task.php 是主文件 只要访问这个网页 就可以开启一个无限死循环(定时任务)
timed_task_18-08-22.log这个其实是真正的日志文件 browse_log.php是读取它的内容到网页上显示而已 但是 每一天都对应一个独立的log文件 log文件名字会变化 所以索性就显示到网页上
timed_task_config.txt 是无限循环(定时任务) 的配置文件 主要是用来关闭所有的无限循环(定时任务)和避免开启多个无限循环(定时任务)
用法:
开启无限循环(定时任务) :确保timed_task_config.txt 存在 并且内容为空 访问timed_task.php 等待页面反馈 如果页面进入卡住状态 则直接查看browse_log.php 看看日志里面是否记录启动成功
关闭无限循环(定时任务) :将timed_task_config.txt的内容改为close 然后等待一会 查看browse_log.php 看看日志里面是否记录关闭 记录了关闭才算关闭成功
日志查看:查看browse_log.php 有一点很关键注意看上下2个正常日志的时间间隔是否是符合你的要求 如果出现一些误差比较大的时间差 那么可以考虑是不是多开了无限循环 可以全部关闭重开下
主文件timed_task,php的代码
<?php
ignore_user_abort(); //函数设置与客户机断开是否会终止脚本的执行
set_time_limit(0); // 来设置一个脚本的执行时间为无限长
date_default_timezone_set('PRC'); // 切换到中国的时间
$interval=20;//间隔多久执行一次
$timed_task_config_path="timed_task_config.txt";//负责让这个无限循环停止的一个开关 其实是控制定时任务机制的一个配置文件 如果该文件不存在或者 里面的内容为close 那么定时任务不会执行 如果为open 则会开启一个无限循环来进行监控和执行定时任务
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>定时任务</title>
</head> <body> <?php
//问题1 如何控制这些无限循环让他们停止
//问题2 如何避免打开多个无限循环增加服务器的资源消耗
//问题3 无限循环的日志监控和避免无限增加的处理办法
//控制用txt
//php定时计划任务 //检测定时任务的配置文件 是否存在或者里面的内容 //strpos($str1,"open")
if(file_exists($timed_task_config_path))
{
//存在配置文件 开始检测里面的内容
$str1="";
$str1=trim(file_get_contents($timed_task_config_path));
if (is_numeric(strpos($str1,"open"))) {
////1.内容为open 表示当前已经有定时任务线程在运行了 就不再额外执行定时任务
send_timed_task_log("已经有一个定时任务进程存在 不能开启其他的进程");
exit("已经有一个定时任务进程存在 不能开启其他的进程");
} elseif (is_numeric(strpos($str1,"close"))) {
////2.内容为close表示要求定时任务关闭 更不用
send_timed_task_log("配置文件要求关闭所有定时任务进程");
exit("配置文件要求关闭所有定时任务进程");
} else {
////3.如果不是open 和close 那么就锁定该文件然后修改里面的内容为open 修改成功
$fp = fopen($timed_task_config_path, 'w+');
if(!is_writable($timed_task_config_path)){
send_timed_task_log("无法写入配置文件 请刷新重试");
exit("<p>无法写入配置文件 请刷新重试</p>");
}
flock($fp, LOCK_EX);
fwrite($fp, 'open');
sleep(1);
flock($fp, LOCK_UN);
fclose($fp); //////////如果再次读取下配置文件内容判断是否写入成功 成功则开始执行后面的无限循环 不成功提示并结束网页
$str1="";
$str1=trim(file_get_contents($timed_task_config_path));
// echo "<p>".$str1." </p>";
// echo "<p>".strpos($str1,"open")." </p>";
// exit();
if (is_numeric(strpos($str1,"open"))) {
///////////////修改成功 获取到了定时任务进程的权利
send_timed_task_log("启动成功 请关闭网页"); do{
$body="";
if (file_exists($timed_task_config_path)) {
$body = trim(file_get_contents($timed_task_config_path));
if (is_numeric(strpos($body,"close")))
{
send_timed_task_log("配置文件要求关闭所有的定时任务");
exit("<p>配置文件要求关闭所有的定时任务</p>");
}
} else {
send_timed_task_log("没有找到定时任务配置文件");
exit("<p>没有找到定时任务配置文件 进程结束</p>");
} //-----------------------定时操作开头------------------------------- send_timed_task_log("<常规检测:一切正常>"); //-----------------------定时操作结尾-------------------------------
sleep(rand($interval-2,$interval+2)); // 函数延迟代码执行若干秒 为了避免完全一样 随机下间隔避免一些问题 }while(true); }else{
send_timed_task_log("没有获取到定时任务进程的权限 请刷新重试");
exit("没有获取到定时任务进程的权限 请刷新重试");
}
}
}else{
send_timed_task_log("定时任务配置文件不存在 不执行该");
exit("<p>定时任务配置文件不存在 不执行该任务</p>");
} //用来发送定时任务日志的函数
function send_timed_task_log($str) { //接收从脚本传递来的日志信息 判断当前的日期 把这个日志信息存储到当前日期命名的日志文件里
if (trim($str)<>""){
$nowtimefilepath="timed_task_".date("y-m-d",time()).".log";
$send_str=date("y-m-d",time());
$send_str=date("Y-m-d H:i:s",time())."----".trim($str)."\r\n";
file_put_contents($nowtimefilepath,$send_str,FILE_APPEND);//���ģʽ ���Ǹ���
}else{ } }
?>
</body>
</html>
完整下载地址:
https://pan.baidu.com/s/1__xp1oSVdT2aDXj5BjxYHw
php虚拟主机下实现定时任务(仅供参考)的更多相关文章
- Blazor WebAssembly 船新项目下载量测试 , 仅供参考.
前言: 昨天 Blazor WebAssembly 3.2 正式发布了. 更新 VS2019后就能直接使用. 新建了两个PWA项目, 一个不用asp.net core (静态部署), 一个使用as ...
- python10作业思路及源码:类Fabric主机管理程序开发(仅供参考)
类Fabric主机管理程序开发 一,作业要求 1, 运行程序列出主机组或者主机列表(已完成) 2,选择指定主机或主机组(已完成) 3,选择主机或主机组传送文件(上传/下载)(已完成) 4,充分使用多线 ...
- Unity上一页下一页切换功能实现源码(仅供参考)
在做项目时我们有时需要实现切换上一页下一页图片,切换上一首下一首歌曲等等类似的功能.这里写了个简单的实现源码(仅供参考),要是有更好的方法欢迎提出来,共同进步~ 以切换上一页下一页图片为例: usin ...
- Ubuntu 12.04 分区方案(仅供参考)
Ubuntu 12.04 分区方案(仅供参考) 总空间大小:50G 目录 建议大小 实际大小 格式 描述 / 10G~20G 10G ext4 根目录 swap <2048M 1G swap ...
- 第二步 (仅供参考) sencha touch 使用cmd打包apk
最新版本的cmd可以直接将sencha touch项目打包成本地应用,不过还有很多不足,本文仅供参考 通过sencha app build native命令可以直接将项目打包成本地应用,不过在命令运行 ...
- 2019第十届蓝桥杯C++B组题解(赛后重写的,不确保答案正确性,仅供参考)
先说一下这次的感受吧,我们考场比较乱,开始比赛了,还有的电脑有故障,(向这些人发出同情),第一次认真参加比赛,真正比赛的时候感觉没有那么正式,很乱,各种小问题,(例如博主就没找到题目在哪里,找到后又不 ...
- 分享分享JavaScript100例-仅供参考
最近一直在做项目,分享下以前收集的Javascript100例,仅供参考. http://files.cnblogs.com/52net/JavaScript100例.zip
- 如何有效防止DEDE织梦系统被挂木马安全设置(仅供参考)
尊敬的客户,您好! 感谢广大客户对我司工作的信任和支持! 我司在最近的一个多月内陆续发现多起因 DedeCMS 安全漏洞造成网站被上传恶意脚本的事件,入侵者可利用恶意脚本对外发送大量 ...
- VSS的运用小内容(针对于vs2008版本)(小的问题都是,仅供参考--只针对于菜鸟级的)
自己开始接触vss 的时候有些小的习惯没有很好的养成,下面的有关VSS内容都是简单的迁入迁出的问题,(仅供参考) 1.文件的迁入迁出:(.txt..xlsx..doc) a:文件的覆盖问题: 对于文件 ...
随机推荐
- lamda表达式的两种写法
public class Test{ public synchronized void test1(){ System.out.println("test1 start........... ...
- eclipse 设置不弹出debug调试框
- 大二组队(NABCD)
(Need)需求 很多时候,外人都不了解我们的校园.为了宣传铁大.让更多人了解校园.走进铁大. (Approach)做法 我们有最基本的展示.对校园风貌有基本的讲解.有论坛供应大家讨论. (Benef ...
- IN中超过1000处理
后台 所有用到IN的方法,都要考虑超过1000的可能 if(cameraIds != null && cameraIds.length > 0){sql.append(" ...
- word doc转pdf
from win32com.client import constants, gencache # TODO pip install pywin32 -i http://mirrors.aliyun. ...
- APP开发工具如何选?
随着技术的发展,在当前开发一款APP已经非常的简单和快速.特别是近些年,利用HTML5技术将APP的开发门槛进一步降低.各种开发工具和框架层出不穷,令人眼花缭乱.这么多的工具摆在眼前应该如何进行选择呢 ...
- java中成员变量,局部变量,静态变量的辨析
转自百度:https://baijiahao.baidu.com/s?id=1625360816541592483&wfr=spider&for=pc 1.java中成员变量,局部变量 ...
- 用阿里fastJson解析Json字符串
一下总结来自工作代码: 1.第一种情况: 通过服务器端发送http请求获取的接送字符串. String jsonStr = HttpRequestUtil.sendGet(config.getAddr ...
- Scale9Sprite 的 setCapInsets中需要注意的地方
在设置 setCapInsets()方法的y参数的时候,不直接取cocosStudio中的y,而是取Scale9Sprite.height - cocosStudio中的y.
- How to make mail more effectively?
1.What does your reader need to know? 2.What does your reader know already? 3.Will your reader be ab ...