返回顶部
首页 > 资讯 > 后端开发 > PHP编程 >实例解析PHP定时器的具体实现
  • 456
分享到

实例解析PHP定时器的具体实现

2024-04-02 19:04:59 456人浏览 安东尼
摘要

目录前言原因危险的做法正确的姿势CLI模式总结前言 常见的定时器有两种:一种周期性定时执行,例如每天的凌晨三点出报表;另一种在指定时间后执行(一次),例如会员登录系统五分钟后发放每日

前言

常见的定时器有两种:一种周期性定时执行,例如每天的凌晨三点出报表;另一种在指定时间后执行(一次),例如会员登录系统五分钟后发放每日登录奖励。两种情况对应shell中的cronat命令,与javascript中的setIntervalsetTimeout函数类似(严格来说setInterval是周期性执行,指定时间点执行需要自行处理)。

web开发PHP程序员对JavaScript中的两个定时器函数应该都还熟悉,回到php层面就有点傻眼:PHP中有sleep,但是没有(内置)定时器函数可用。sleep函数勉强可以做到,但会导致进程阻塞,期间不能做其他事(或无响应)。为什么PHP没能提供定时器(Timer)这个功能呢?

原因

个人认为,WEB开发中PHP不能使用定时器的本质原因是可控 常驻内存运行环境的缺失。两个要点:第一常驻内存,第二可控。CGI模式下,进程执行完脚本后直接退出,不能指望其到指定时间运行任务;PHP-FPM模式下,进程(绝大多数)常驻内存,但不可控。

不可控的意思是执行PHP的进程不受PHP代码影响,进程的入口点和退出时机由额外的程序控制。例如FPM模式下,PHP脚本中的exitdie函数只中断脚本的执行,不会对执行脚本的进程产生特别的影响(内存泄露除外)。PHP开发人员编写的脚本是进程的执行体,执行完毕后就从进程的执行上下文中卸载出去。这种情况下,执行PHP脚本的时机仍然由外部驱动,没有外部请求PHP代码就安详的躺在硬盘上,什么都不做,也就定时任务。

由于PHP主要面向web开发,PHP这种执行模式稳定可靠,开发效率快。比如省去资源释放这一步,就避免了开发中很多工作量和坑。想想某些第三方库代码中改时区、字符编码等还不还原,在常驻内存运行环境下几乎肯定会导致后续请求有问题。但在FPM模式下,这种坑无意中直接趟平,省去许多调试时间,为程序员保住发际线做出了不小的贡献。

问题已经了解,那么PHP中如何使用定时器执行定时任务?

危险的做法

在web环境下,PHP脚本默认有超时时间。去掉超时设置,就可以让程序一直在后台运行(如果进程不退出的话)。例如以下代码在响应请求后继续后台运行,并且每五秒钟输出一次时间到文件:


# test.php

set_time_limit(0); # 取消超时设置,让脚本可一直运行

 

echo 'This is a background run forever script. Now you can leave me alone.';

 

fastcgi_finish_request();   # 结束当前请求

 

do{

   file_put_contents("/tmp/out.dat", "test script, now:" . date("Y-m-d H:i:s") . "\n", FILE_APPEND);

   sleep(5);

}while(true);

请求Http://localhost:8080/test.php文件后,监测/tmp/out.dat文件,会发现不断有内容输出,无论客户端是否断开连接、关闭浏览器或者重启电脑(不能重启服务器)。这说明程序一直在执行,并且也实现了我们想要的定时器功能。如果把sleep改成usleeptime_nanosleep,还能实现微秒、纳秒级定时器,岂不美哉?

实践中应当尽量避免用这种方式实现定时器,不仅因为低效,还略有危险。原因之一是每次请求会占用一个进程,请求十万次需要十万个进程,基本上会导致系统崩溃或后续请求无响应;另外如果打开了session,但是忘记调用session_write_close,会导致同一个用户的后续请求被hang住(session活跃时处于加状态,不关闭session会导致后续进程无法打开session)。

web开发应当越快响应用户的请求越好,在web开发中用这种方式强行实现定时器,会让整个web应用处于不稳定、不可靠或不可预测状态。孟子曰:知而慎行,君子不立于危墙之下。不靠谱的做法要尽量避免,顺带也避免背锅和甩锅。

接下来看看PHP中使用定时器的正确姿势。

正确的姿势

PHP实现定时器的做法可简单归结为如下几种:

  1. 使用cron、jenkins等调度工具做周期性定时任务(既可以是执行脚本,也可以是请求某个网址);
  2. 一次性执行任务通过消息队列数据库等方式投递给第三方程序执行;
  3. WordPress一样模拟定时任务,但要记住这种方式依赖于客户端请求,并需自行处理好进程并发问题;
  4. 使用常驻内存型方式运行PHP程序,即CLI模式。

除了第三种做法,其他方式都是推荐的,具体方案请结合实际需求。作为PHP程序员,当然还是首选用PHP来做,也就是CLI模式。

CLI模式

摸着良心说,CLI模式让PHP发挥的空间拓展不少。在CLI模式下,程序的入口点就是脚本,且代码可以常驻内存,进程完全由PHP代码控制。在这种形式下,实现定时器就有多种玩法。本文列出几种做法,抛砖引玉:

  1. 使用swooleworkerman框架,内置(高精度)定时器;
  2. 使用多进程(池)/多线程(池)技术(pcntlpthreads拓展在CLI模式下才可用);
  3. 处理tick或者alarm等信号;
  4. 使用libeventlibev等事件驱动库;
  5. sleep加循环或自己实现事件循环。

想折腾的话自己用2-5方案,不想折腾swooleworkerman等框架是首选,稳定可靠。

总结

区分HTTP请求和任务的关系,实现定时任务就简单了。至于用不用PHP来实现,那是另外一回事。当然作为web开发的首选语言,PHP实现定时任务也是轻而易举的。

到此这篇关于实例解析PHP定时器的具体实现的文章就介绍到这了,更多相关PHP 定时器内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: 实例解析PHP定时器的具体实现

本文链接: https://lsjlt.com/news/135975.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 实例解析PHP定时器的具体实现
    目录前言原因危险的做法正确的姿势CLI模式总结前言 常见的定时器有两种:一种周期性定时执行,例如每天的凌晨三点出报表;另一种在指定时间后执行(一次),例如会员登录系统五分钟后发放每日...
    99+
    2024-04-02
  • 如何实现定时推送的具体方案
    详细内容 详细内容大概分为4个部分,1.应用场景 2.遇到问题 3.设计 4.实现 5.运行效果 1.应用场景 需要定时推送数据,且轻量化的实现。 2.遇到问题 如果启动一...
    99+
    2024-04-02
  • php怎么实现时间戳转换具体时间
    这篇“php怎么实现时间戳转换具体时间”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“php怎么实现时间戳转换具体时间”文章吧...
    99+
    2023-07-05
  • checkpoint机制具体实现示例详解
    目录checkpoint 机制的具体实现BackNode 节点冷备份checkpoint 的实现checkpoint 机制的具体实现 我们都知道为了优化分布式存储系统中 NameN...
    99+
    2023-02-07
    checkpoint 机制实现 checkpoint 机制
  • Android 听筒模式的具体实现实例
    一、利用距离感应器监听听筒靠近耳朵事件准确的说距离感应器并不能监听到你是否把手机靠近耳朵,也许是你用手挡在了距离感应器前面,但这不是我们关心的,我们关心的是当你的耳朵靠近听筒时...
    99+
    2022-06-06
    Android
  • Android实现定时器的五种方法实例详解
    一、Timer Timer是Android直接启动定时器的类,TimerTask是一个子线程,方便处理一些比较复杂耗时的功能逻辑,经常与handler结合使用。 跟handle...
    99+
    2022-06-06
    方法 定时器 Android
  • RxJava2.x实现定时器的实例代码
    前言由于现在网络层已经升级到RxJava2.x相关的了,所以需要做些调整。虽然RxJava1.x和RxJava2.x同属RxJava系列,但由于RxJava2.x部分代码的重写,导致RxJava2.x与RxJava1.x已是两个不同的版本,...
    99+
    2023-05-31
    rxjava 定时器 ava
  • PHP表单验证的具体实现
    这篇文章主要讲解了“PHP表单验证的具体实现”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“PHP表单验证的具体实现”吧!PHP 表单验证表单验证我们应该尽可能的对用户的输入进行验证(通过客户...
    99+
    2023-06-04
  • iOSDispatchSourceTimer定时器的具体使用
    目录1. 概述2. DispatchSourceTimer2.1 GCD Timer 创建2.2 GCD Timer 配置2.3 GCD Timer 部署任务2.4 GCD Time...
    99+
    2024-04-02
  • GoStruct结构体的具体实现
    目录什么是结构体1. 基本实例化(方法1)2. new实例化(方法2)3. 键值对初始化(方法3 结构体能够使用指针就使用指针)结构体方法和接收者encoding-json包1. s...
    99+
    2023-03-15
    Go Struct结构体 Go Struct
  • Django实现视频播放的具体示例
    view视图 import re import os import mimetypes from wsgiref.util import FileWrapper from djang...
    99+
    2024-04-02
  • Vue插槽具体用法及实例分析
    目录单个插槽具名插槽作用域插槽Vue的插槽(Slot)是一种可以让父组件向子组件传递内容的机制。插槽可以让开发者将组件的结构和内容分离开来,从而实现更好的可维护性和复用性。 在Vue...
    99+
    2023-05-19
    Vue插槽slot用法 Vue slot Vue插槽
  • golang定时器Timer的用法和实现原理解析
    目录一文搞懂golang定时器Timer的用法和实现原理前言Timertimer结构体创建定时器停止定时器重置定时器实现原理数据结构runtimeTimer创建Timer停止Time...
    99+
    2023-05-15
    golang定时器 golang定时器Ticker
  • Java实现一个简单的定时器代码解析
    定时的功能我们在手机上见得比较多,比如定时清理垃圾,闹钟,等等.定时功能在java中主要使用的就是Timer对象,他在内部使用的就是多线程的技术.Time类主要负责完成定时计划任务的功能,就是在指定的时间的开始执行某个任务.Timer类的作...
    99+
    2023-05-30
    java 定时器 ava
  • Go定时器的三种实现方式示例详解
    目录SleepTimerTicker小结Sleep 很多时候需要周期性的执行某些操作,就需要用到定时器。定时器有三种思路。 本节源码位置 github.com/golang-min...
    99+
    2022-12-20
    Go定时器实现方式 Go定时器
  • PHP 开发中 Elasticsearch 实现社交媒体实时热点分析
    社交媒体已经成为了人们获取新闻和娱乐信息的重要渠道,如何从海量的社交媒体数据中获取有价值的信息,对于企业和个人来说都是一项重要的任务。而实时热点分析则是其中一个关键的挑战,因为社交媒体数据的更新速度非常快,如果不能及时分析出热点话题,可能错...
    99+
    2023-10-21
    PHP elasticsearch 实时热点分析
  • Android 实现定时器的四种方式总结及实现实例
    Android中实现定时器的四种方式 第一种方式利用Timer和TimerTask 1、继承关系 java.util.Timer 基本方法 schedule 例如: time...
    99+
    2022-06-06
    定时器 Android
  • python实现自定义日志的具体方法
    1、导入logging模块: import logging 2、创建日志收集器: logger = logging.getLogger(“日志收集器的name”) 3、设置日志收集器的日志级别: lo...
    99+
    2022-06-02
    python 自定义日志
  • Nodejs实现定时爬虫的完整实例
    目录事件起因使用 Node Schedule 实现定时任务一、安装 node-schedule二、基本用法三、高级用法四、终止任务总结事件起因 前两天要帮朋友B站舰长群审核,一个个...
    99+
    2024-04-02
  • linux创建PHP定时任务的实例
    linux创建PHP定时任务 下面所有的前提是服务器存在PHP环境 首先创建一个php文件:示例内容如下: <?php $ch=curl_init(); //设置请求 curl_setop...
    99+
    2022-06-04
    实例 linux PHP
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作