当前位置:首页 » 编程语言 » php任务队列

php任务队列

发布时间: 2022-07-08 18:34:04

‘壹’ php队列计划任务怎么做呢,用的是ignore

回答你第一个问题:其实文件名称不要改成html还是php但是,这浏览器中确实可以输入html来执行php文件有一个方法就是对服务器进行设置,也就是常说的伪静态比如:RewriteRule (\d+).html$ /index.php?id=$1这样,所有名称为数字的html请求,都会执行index.php文件,并提供参数id,值就是那个htm的文件名换句话说,这浏览器中访问 123.html 其实访问的url是 index.php?id=123 至于优点缺点,其实也没什么,只是伪装成html,一个是网址更好记,一个是对于搜索引擎来说,有益于优化至于模板的问题,不做评论,自己体会!详细的话楼主还是去后盾人自学一下吧

‘贰’ php怎么把各种任务做成多个任务队列,每3秒任务执行程序轮一次,分别按顺序从各队列里提取一个任务来执行

可以使用数组模拟队列,给定多个数组,然后将任务放入各个数组中,每次循环遍历数组,从数组中获取任务,然后调度执行。

对于每3秒执行一次,可以使用定时器。或者写一个死循环,循环里面执行一次程序,然后睡眠3秒,这样就可以简单实现每隔3秒的任务循环调度。

‘叁’ PHP使用Beanstalkd做任务队列,是不是代表需要有一个PHP常驻进程

不是必须,你可以用Beanstalkd支持的任何语言

这里有一份Client Libraries清单:https://github.com/kr/beanstalkd/wiki/client-libraries

‘肆’ 请教PHP+Redis实现任务队列的思路

// 创建请求ID标志, uniqid 无法保证唯一, 自己去搜索生成唯一的方法
$uuid = uniqid();
$tsk_name = "mytask";
$time_out = 30000; // 超时策略: 30秒
$time_start = time();
$redis->rPush($tsk_name, $uuid); // 右(后)插入队列

// 堵塞等待队列中第一个和$uuid匹配的(到我了)
while($uuid != $redis->lGet($tsk_name, 0)){
if((time()-$time_start)> $time_out) {
break; // 超时跳出(某些原因队列异常了, 可能永远取不到)
}
usleep(10); // sleep 10ms, 再次尝试
}

// 这里执行任务的处理代码....

// $response 已拼装好要返回的内容
// 处理完成后(数据库等已入库更新), 需要:
if($redis->lGet($tsk_name, 0) == $uuid){ // 再次确认第一个是本请求
$redis->lPop($tsk_name); // 完成任务了, 从队列中移除
}else{
// 出现这种情况, 是因为超时了, 或前面的$uuid没有被消费
// 若不清除, 后续的请求, 都将无法正常进入队列执行
// 取队列中的所有$uuid
$queues = $redis->lRange($tsk_name, 0, -1);
foreach($queues as $i=>$uid){
if($uid==$uuid){

‘伍’ PHP-php 怎么实现消息队列

消息队列
消息队列是线程间通讯的手段:

import java.util.*

public class MsgQueue{

private Vector queue = null;
public MsgQueue(){
queue = new Vector();
}
public synchronized void send(Object o)
{
queue.addElement(o);
}
public synchronized Object recv()
{
if(queue.size()==0)
return null;
Object o = queue.firstElement();
queue.removeElementAt(0);//or queue[0] = null can also work
return o;
}
}

因为java中是locked by object的所以添加synchronized 就可以用于线程同步锁定对象
可以作为多线程处理多任务的存放task的队列。他的client包括封装好的task类以及thread类

‘陆’ PHP队列执行任务的时候,如何防止进程之间抢夺资源

实际上有一个非常简单的办法,你可以利用数据库操作的原子性来实现,不需要那么复杂的锁机制,甚至队列。就按你的方法来,假设任务数据表 task 里有两个字段 id, status,我们定义status三个状态
0: 待处理1: 正在处理2: 处理完成

假设你有一堆 PHP 进程都用如下 SQL 语句去取出数据库里的待处理任务
SELECT * FROM task WHERE status = 0

取出来以后,我们为了防止其他用户不再重复取出要把它的状态标记为 1
UPDATE task SET status = 1 WHERE id = xxx

但是等等,这样就会产生如你所说的资源抢夺,但如果加上一个简单的技巧就可以避免,你把语句变成这样
UPDATE task SET status = 1 WHERE id = xxx AND status = 0

熟悉一点数据库的人可能会说这样还是避免不了抢夺,只是避免了重复写入。
我要说的是,能避免重复写入就够了,我们的进程在执行完这条操作后,去获取 affected_rows ,即更新的条数,根据数据库的原子性,只有第一个抢占的进程才会返回 1,它可以进行后面的操作。而剩下返回 0 的进程,直接进入下一个等待流程即可。

‘柒’ 利用php +swoole如何实现异步任务队列

  • class msgServer

  • {

  • private $serv;

  • function __construct()

  • {

  • $this->serv = new SwooleServer("127.0.0.1", 9501);//创建一个服务

  • $this->serv->set(array('task_worker_num' => 4)); //配置task进程的数量

  • $this->serv->on('receive', array($this, 'onReceive'));//有数据进来的时候执行

  • $this->serv->on('task', array($this, 'onTask'));//有任务的时候执行

  • $this->serv->on('finish', array($this, 'onFinish'));//任务结束时执行

  • $this->serv->start();

  • }

  • public function onReceive($serv, $fd, $from_id, $data)

  • {

  • $data = json_decode($data, true);

  • $task_id = $serv->task($data);//这里发起了任务,于是上面的on('task', array($this, 'onTask'))就会执行

  • }

  • public function onTask($serv, $task_id, $from_id, $data)

  • {

  • $data['send_res'] = $this->sendMsg($data); //发送短信

  • //1.7.3之前,是$serv->finish("result");

  • return "result.";//这里告诉任务结束,于是上面的on('finish', array($this, 'onFinish'))就会执行

  • }

  • public function onFinish($serv, $task_id, $data)

  • {

  • $this->addSendLog($data); //添加短信发送记录

  • }

  • }

‘捌’ PHP当中,怎么使用 beanstalk 来做队列如何在 TP 中简单引入呢

消息队列Beanstalk详解
先从安装开始
##Githubhttps://github.com/kr/beanstalkd
cdbeanstalkd-1.10
make或者makeCFLAGS=-O2

注意,你不需要运行configure命令哦,因为对应的makefie已经是建立好了的。make之后在当前目录下生成了beanstalkd可执行程序,你也可以makeinstall一下让它安装到/usr/local/bin中,或者你自己拷贝到一个自定义目录中即可。
./beanstalkd-hUse:./beanstalkd[OPTIONS]Options:-bDIRwaldirectory-(use-f0for"alwaysfsync")-Fneverfsync(default)-lADDRlistenonaddress(defaultis0.0.0.0)-pPORTlistenonport(defaultis11300)-uUSERbecomeuserandgroup-(defaultis65535)-sBYTESsetthesizeofeachwalfile(defaultis10485760)()-ccompactthebinlog(default)-ndonotcompactthebinlog-vshowversioninformation-Vincreaseverbosity-hshowthishelp##b设置二进制日志文件目录,Beanstalk支持把任务写入日志文件,便于恢复##l设置监听地址##p设置监听端口##v查看版本################启动不指定任何参数,表示在0.0.0.0端口11300监听./beanstalkd&./beanstalkd-l127.0.0.111301&./beanstalkd-l192.168.1.16811302&在实际中应该监控这个进程,防止意外终止退出。为了更好理解Beanstalk的原理,建议阅读官方文档:github.com/kr/beanstalkd/blob/master/doc/protocol.md,以下是我个人的学习笔记:当Put一个job时,取决于是否设置了delay,job可能进入READY或DELAYED状态,DELAYED的job超时后(或者调用kick)变成READY,reserve命令取一个最新的READY的job并把其变为RESERVED状态(这个时候是被取出执行),RESERVED状态的job可以发送delete删除,也可以使用release释放,根据是否设置delay时间,可能变成READY或DELAYED状态,也可以调用bury命令让job进入休眠,休眠中的job可以被delete也可以用kick命令让其变为READY。当reserve一个READY状态的job去执行时,如果设置的运行超时时间,则在取出时开始计时,如果超时则会从新放回到READY队列。job的运行的剩余时间可以通过stats-job命令来查看。如果要分配更多时间给job,可以发送touch命令。命令reserve取job时,这个job可能来自任一tube(当前链接的watchlist是多个时),默认,一个新链接watch一个叫default的tube。可以使用watch命令添加一个新的tube到watchlist中(如果这样,一般就不要试图使用tube的名字来区分要执行的任务,比如有两个tubeA和B,当reserve取job时,这个job可能来自A也可以来自B,不过前提是A和B都在watchlist中)。如果要取指定tube的job,明确使用use即可,这样只会获取指定tube的job。可以在消费方建立新链接后,watch某个tube以期望获取它的job(也可以使用use只获取特定tube的job)。同样道理,要put某个job都某个tub,需要先使用use命令,否则就是put到默认的叫default的tube中。reserve命令只是取状态为READY的job,如果要去其它状态的job,则需要使用peek和peek-xxxx命令(peek-readypeek-delayedpeek-buried)。job取出后根据它的状态可以做相应操作,比如deletereleaseburykick。PHP框架Phalcon中提供对Beanstalk的客户端库://Connecttothequeue$queue=newPhalconQueueBeanstalk(array('host'=>'127.0.0.1','port'=>11300));链接到Beanstalk只有两个参数,并没有验证等信息,以上指定的就是默认值。Beanstalk是支持多host的,PhalconQueueBeanstalk看来并没有实现这个。在调用put执行,应该首先调用choose()方法指定tube,否则就是使用default这个tube。(这个所谓的choose实际就是发送use命令)然后再调用put把job添加到你期望的tube中:1$qid=$queue->put("QueueMessage");注意,put成功就返回job的标识符。以下展示一个完整的例子:$queue=newPhalconQueueBeanstalk(array('host'=>'127.0.0.1','port'=>11300));$queue->choose("my_tube");for($i=0;$i<10;$i++){$qid=$queue->put("Mytube--QueueMeaage$i");echo$qid." ";}$queue->choose("default");for($i=0;$i<10;$i++){$qid=$queue->put("Defaulttube--QueueMeaage$i");echo$qid." ";}切换到消费端,首先要使用choose()来获取来自哪个tube的job(按照道理应该是调用watch()方法,但是实际测试,watch()没有起作用,只好换成choose指定特定tube),然后调用peekReady()获取一个PhalconQueueBeanstalkJob对象,当然如果失败就返回false,Job对象获取后,可以操作自然就有delete()release()bury()touch()kick()和getBody(),其中getBody()获取Job的实际内容。$queue=newPhalconQueueBeanstalk();//$queue->watch("my_tube");$queue->choose("my_tube");while(true){if(($job=$queue->peekReady())!==false){$message=$job->getBody();echo$message." ";$job->delete();}else{usleep(200000);}}PhalconQueueBeanstalk提供了Beanstalk协议的大部分内容,但是状态相关的没有实现。为了详细查看Beanstalk,可以使用一个第三方的PHP程序(github.com/ptrofimov/beanstalk_console):

‘玖’ PHP 做任务队列,现在常用的是哪个

生产环境用过 Gearman + Redis。

Gearman 用来做 worker 的调度,Redis 保存 workload。持久化用 MySQL 慢慢倒腾。
如对您有帮助,望采纳,谢谢

热点内容
php数组的数量 发布:2024-05-12 23:27:23 浏览:976
mc小骆解说我的世界服务器3 发布:2024-05-12 23:24:39 浏览:767
sql双写 发布:2024-05-12 23:16:13 浏览:945
定义一个python数组 发布:2024-05-12 23:11:00 浏览:50
电脑具体配置是哪些内容 发布:2024-05-12 22:56:10 浏览:526
公司办公室人员怎么配置 发布:2024-05-12 22:40:45 浏览:585
数据库启动服务器 发布:2024-05-12 22:40:32 浏览:432
链数据存储 发布:2024-05-12 22:26:41 浏览:426
android的web应用 发布:2024-05-12 22:19:00 浏览:171
如何反编译vfp 发布:2024-05-12 22:16:30 浏览:746