gearman任务分发改进
基于我上次在这里发现的问题,就是一次性投递20个消息,用sleep等待后发现,最后一个任务需要等前面19个都跑完才能执行,所以这里做一下改进。
client.php
<?php
$client = new GearmanClient();
$client->addServer('127.0.0.1', 4730);
for ($i=0; $i < 20; $i++) {
$ret[$i] = $client->doBackground('runLaterJob', json_encode(array(
'uid' => 'test user id '.$i,
'title' => '添加一个需要延时处异步执行的代码标题',
'body' => '执行这个异步的具体内容',
'run_time' => time() + 2,
)));
}
worker.php
<?php $worker = new GearmanWorker();
$worker->addServer('127.0.0.1', 4730);
$worker->addFunction('runLaterJob', function($job) {
$data = json_decode($job->workload(), true);
if (isset($data['run_time']) && $data['run_time'] > time()) {
// 如果需要延时还没到时间就下次再处理
add_work($data);
}
else {
echo "处理任务 uid:{$data['uid']}--title:{$data['title']}--body:{$data['body']} 成功\n";
}
});
while($worker->work()); function add_work($data = []) {
$client = get_client();
$client->doBackground('runLaterJob', json_encode($data));
} function get_client() {
static $client = NULL;
if (!$client) {
$client = new GearmanClient();
$client->addServer('127.0.0.1', 4730);
}
return $client;
}
核心思路是,加入任务的时候就计算好自己什么时候执行,然后在执行任务这里不断的判断是不是到时间了 到时间就执行,否则就再次加入任务,这样就能避免最后一个任务被sleep给阻塞住了。虽然这里一直加入任务感觉会很傻瓜,不过可以稍微做个改进,用usleep(1000)这样每毫秒去跑一次,这样就既能控制在毫秒级别,又能减轻循环压力。
说干就干,接下来是改进的代码。
client.php
<?php
$client = new GearmanClient();
$client->addServer('127.0.0.1', 4730);
$sleep_time = [2, 0.001, 0.005, 0.8, 0.007, 0.5, 1, 5, 0.1, 2, 2.03, 1.24, 0.12, 3.08, 4.77, 1.42, 2.69, 3.49, 0.29, 1.99];
for ($i=0; $i < 20; $i++) {
$ret[$i] = $client->doBackground('runLaterJob', json_encode(array(
'uid' => 'test user id '.$i,
'title' => '添加一个需要延时处异步执行的代码标题',
'body' => '执行这个异步的具体内容',
'run_time' => microtime(true) + $sleep_time[$i],
)));
}
worker.php
<?php $worker = new GearmanWorker();
$worker->addServer('127.0.0.1', 4730);
$worker->addFunction('runLaterJob', function($job) {
$data = json_decode($job->workload(), true);
if (isset($data['run_time']) && $data['run_time'] > microtime(true)) {
// 如果需要延时还没到时间就下次再处理
usleep(1000);
add_work($data);
}
else {
echo "处理任务 uid:{$data['uid']}--title:{$data['title']}--body:{$data['body']} 成功\n";
}
});
while($worker->work()); function add_work($data = []) {
$client = get_client();
$client->doBackground('runLaterJob', json_encode($data));
} function get_client() {
static $client = NULL;
if (!$client) {
$client = new GearmanClient();
$client->addServer('127.0.0.1', 4730);
}
return $client;
}
运行php worker.php
然后新开一个终端运行php client.php
控制台打印结果为
处理任务 uid:test user id 1--title:添加一个需要延时处异步执行的代码标题--body:执行这个异步的具体内容 成功
处理任务 uid:test user id 2--title:添加一个需要延时处异步执行的代码标题--body:执行这个异步的具体内容 成功
处理任务 uid:test user id 4--title:添加一个需要延时处异步执行的代码标题--body:执行这个异步的具体内容 成功
处理任务 uid:test user id 8--title:添加一个需要延时处异步执行的代码标题--body:执行这个异步的具体内容 成功
处理任务 uid:test user id 12--title:添加一个需要延时处异步执行的代码标题--body:执行这个异步的具体内容 成功
处理任务 uid:test user id 18--title:添加一个需要延时处异步执行的代码标题--body:执行这个异步的具体内容 成功
处理任务 uid:test user id 5--title:添加一个需要延时处异步执行的代码标题--body:执行这个异步的具体内容 成功
处理任务 uid:test user id 3--title:添加一个需要延时处异步执行的代码标题--body:执行这个异步的具体内容 成功
处理任务 uid:test user id 6--title:添加一个需要延时处异步执行的代码标题--body:执行这个异步的具体内容 成功
处理任务 uid:test user id 11--title:添加一个需要延时处异步执行的代码标题--body:执行这个异步的具体内容 成功
处理任务 uid:test user id 15--title:添加一个需要延时处异步执行的代码标题--body:执行这个异步的具体内容 成功
处理任务 uid:test user id 19--title:添加一个需要延时处异步执行的代码标题--body:执行这个异步的具体内容 成功
处理任务 uid:test user id 0--title:添加一个需要延时处异步执行的代码标题--body:执行这个异步的具体内容 成功
处理任务 uid:test user id 9--title:添加一个需要延时处异步执行的代码标题--body:执行这个异步的具体内容 成功
处理任务 uid:test user id 10--title:添加一个需要延时处异步执行的代码标题--body:执行这个异步的具体内容 成功
处理任务 uid:test user id 16--title:添加一个需要延时处异步执行的代码标题--body:执行这个异步的具体内容 成功
处理任务 uid:test user id 13--title:添加一个需要延时处异步执行的代码标题--body:执行这个异步的具体内容 成功
处理任务 uid:test user id 17--title:添加一个需要延时处异步执行的代码标题--body:执行这个异步的具体内容 成功
处理任务 uid:test user id 14--title:添加一个需要延时处异步执行的代码标题--body:执行这个异步的具体内容 成功
处理任务 uid:test user id 7--title:添加一个需要延时处异步执行的代码标题--body:执行这个异步的具体内容 成功
可以看到确实是按照时间距离排序的,第0个元素排后面去了,第1个元素排最前面来了,因为它只需要0.001秒就要执行
gearman任务分发改进的更多相关文章
- 分布式任务分发框架Gearman教程和PHP实现实例
1.Gearman介绍和使用场景 Gearman是一个分发任务的程序框架,可以用在各种场合,与Hadoop相 比,Gearman更偏向于任务分发功能.它的任务分布非常简单,简单得可以只需要用脚本即可完 ...
- 用 Gearman 分发 PHP 应用程序的工作负载【转载】
通过本文,了解工作分发系统 Gearman 并分发用 PHP.C.Ruby 及其他受支持语言编写的应用程序的工作负载. 尽管一个 Web 应用程序的大部分内容都与表示有关,但它的价值与竞争优势却可能体 ...
- Gearman实战第一弹:异步处理结算单
昨天梦回jm,醒来之后看着窗外万里晴空,想大声喊一句:爷青回! 我想起之前使用gearman的岁月.不知不觉也过了快5年,想总结一篇关于gearman的技术文章算是一种对青春的祭奠,再不写的话更少有p ...
- 必学PHP类库/常用PHP类库大全,php 类库分类-收集
依赖管理( Dependency Management ) 用于依赖管理的包和框架 Composer / Packagist - 一个包和依赖管理器. Composer Installers - 一个 ...
- vivo 自研Jenkins资源调度系统设计与实践
作者:vivo 互联网服务器团队- Wu Qinghua 本文从目前业界实现Jenkins的高可用的实现方案,分析各方案的优缺点,引入vivo目前使用的Jenkins高可用方案,以及目前Jenkins ...
- Gearman介绍、原理分析、实践改进
gearman是什么? 它是分布式的程序调用框架,可完成跨语言的相互调用,适合在后台运行工作任务.最初是2005年perl版本,2008年发布C/C++版本.目前大部分源码都是(Gearmand服务j ...
- 分布式的任务分发框架-Gearman
官方文档:http://gearman.org/getting-started/ 安装方法和示例都有,可以详细看一下. Gearman是一个分发任务的程序框架,可以用在各种场合,与Hadoop相比,G ...
- 用 Gearman 分发 PHP 应用程序的工作负载
尽管一个 Web 应用程序的大部分内容都与表示有关,但它的价值与竞争优势却可能体现在若干专有服务或算法方面.如果这类处理过于复杂或拖沓,最好是进行异步执行,以免 Web 服务器对传入的请求没有响应.实 ...
- 任务分发系统gearman
1 Gearman是什么 Gearman Job Server@http://gearman.org/. Gearman 是一个任务分发系统,它提供了一个分发框架,能够分发某类任务到更适合处理这类任务 ...
- 高CPU业务场景下的任务分发方案Gearman搭建一览
Gearman是当年LiveJournal用来做图片resize的,大家也明白图片resize是一个高CPU的操作,如果让web网站去做这个高CPU的功能,有可能会拖垮你的 web应用,那本篇我们 ...
随机推荐
- Oracle数据库安装与还原
安装Oracle 11g数据库 安装数据库参考这位大佬的文章:(135条消息) Oracle 11g版本下载及安装超详细教程图解_oracle11g下载_田夜的博客-CSDN博客 非常详细 利用dmp ...
- 【Burp Suite】Mac之破解明文密码
一.安装CA证书 安装证书是为了代理的时候可以继续访问地址,否则的话会提示网络异常 参考文章:<Mac系统Burp Suite的安装>,文章中是火狐浏览器的操作 1.谷歌浏览器 选择导出的 ...
- 四,分析Spring Boot底层机制(Tomcat 启动分析+Spring容器初始化+Tomcat如何关联 Spring 容器) 以及个人编写启动 Tomcat
四,分析Spring Boot底层机制(Tomcat 启动分析+Spring容器初始化+Tomcat如何关联 Spring 容器) 以及个人编写启动 Tomcat @ 目录 四,分析Spring Bo ...
- K8s文件解析 涉及 SLS、MSE、NAS存储卷等
k8s.yml模板 涉及配置: 1. 存储卷(NAS) 2. SLS设定(阿里云日志采集系统) 3. MSE配置(阿里云版nacos) 4. 配置应用参数(包括路径,布尔类型数据等) apiVersi ...
- 人形动画常见IK的处理
Unity中常见人形动画IK的处理方式 本文将尝试仅使用Untiy内置的Animator来解决常见的几种运动所需的IK.也会给出核心功能的代码实现. 效果一览:b站视频 Unity中人形角色的IK I ...
- Round #2022/11/26
问题 B:染色 题目描述 有长度为 \(n\) 的一个序列,编号为 \(1\) 到 \(n\) ,现要对这些元素进行染色标记,若编号 \(i-j\) 为素数,且 \(1\le i < j \le ...
- pycharm批量注释
pycharm批量注释不像是spyder可以鼠标右键选择,pycharm是要用快捷键的,选中要注释的代码,然后快捷键就可以了. 注释代码和取消注释代码的快捷键都一样ctrl + /
- JavaScript中if嵌套assert的方法
在JavaScript中,通常我们不会直接使用assert这个词,因为JavaScript标准库中并没有直接提供assert函数(尽管在一些测试框架如Jest.Mocha中经常看到).但是,我们可以模 ...
- 无人值守的IDC机房动环综合运维方案
企业数字化转型以及5G.物联网.云计算.人工智能等新业态带动了数据中心的发展,在国家一体化大数据中心及"东数西算"节点布局的推动下,数据中心机房已成为各大企事业单位维持业务正常 ...
- LeetCode 1819. 序列中不同最大公约数的数目(数论)
题目描述 给你一个由正整数组成的数组 nums . 数字序列的 最大公约数 定义为序列中所有整数的共有约数中的最大整数. 例如,序列 [4,6,16] 的最大公约数是 2 . 数组的一个 子序列 本质 ...