引入背景:假如我们每天有10000个订单生成,需要同步到仓储系统中去,以前做法是开启一个crontab去跑这些任务,但是发现总有感觉同步效率低,间隔时间都是分钟级别的。

解决方案测试:我们将同步订单的任务表添加一个hash作为key,作为分发条件,因为mysql中select如果做mod函数是用不到索引的,所以我们自己做随机hash,但是务必不需要范围太大,以免服务器资源不够,方法是根据hashkey投放到不同的进程中进行同步,测试代码如下

<?php
/**
* Created by PhpStorm.
* User: xujun
* Date: 2017/8/26
* Time: 9:37
*/
//假定需要处理的数据如下
class Process{
public $mpid=0;
public $max_precess=5;
//代替从数据库中读取的内容
public $task = [
['uid'=>1,'uname'=>'bot','hash'=>1,'handle'=>'test'],
['uid'=>2,'uname'=>'bot1','hash'=>2,'handle'=>'test'],
['uid'=>3,'uname'=>'bot2','hash'=>3,'handle'=>'test'],
['uid'=>4,'uname'=>'bot3','hash'=>4,'handle'=>'test'],
['uid'=>2,'uname'=>'bot4','hash'=>2,'handle'=>'test'],
['uid'=>3,'uname'=>'bot5','hash'=>3,'handle'=>'test'],
['uid'=>4,'uname'=>'bot6','hash'=>1,'handle'=>'test'],
];
public $works = [];
public $swoole_table = NULL;
//public $new_index=0;
function test($index,$task){
print_r("[".date('Y-m-d H:i:s')."]".'work-index:'.$index.'处理'.$task['uname'].'完成'.PHP_EOL);
} public function __construct(){
try {
$this->swoole_table = new swoole_table(1024);
$this->swoole_table->column('index', swoole_table::TYPE_INT);//用于父子进程间数据交换
$this->swoole_table->create(); swoole_set_process_name(sprintf('php-ps:%s', 'master'));
$this->mpid = posix_getpid();
$this->run();
$this->processWait();
}catch (\Exception $e){
die('ALL ERROR: '.$e->getMessage());
}
} public function run(){
for ($i=0; $i < $this->max_precess; $i++) {
$this->CreateProcess();
}
} private function getTask($index){
$_return = [];
foreach ($this->task as $v){
if($v['hash']==$index){
$_return[] = $v;
}
}
return $_return;
} public function CreateProcess($index=null){
if(is_null($index)){//如果没有指定了索引,新建的子进程,开启计数
$index=$this->swoole_table->get('index');
if($index === false){
$index = 0;
}else{
$index = $index['index']+1;
}
print_r($index);
}
$this->swoole_table->set('index',array('index'=>$index));
$process = new swoole_process(function(swoole_process $worker)use($index){ swoole_set_process_name(sprintf('php-ps:%s',$index));
$task = $this->getTask($index);
foreach ($task as $v){
call_user_func_array(array($this,$v['handle']),array($index,$v));
}
sleep(20);
}, false, false);
$pid=$process->start(); $this->works[$index]=$pid;
return $pid;
} public function rebootProcess($ret){
$pid=$ret['pid'];
$index=array_search($pid, $this->works);
if($index!==false){
$index=intval($index);
$new_pid=$this->CreateProcess($index);
echo "rebootProcess: {$index}={$new_pid} Done\n";
return;
}
throw new \Exception('rebootProcess Error: no pid');
} public function processWait(){
while(1) {
if(count($this->works)){
$ret = swoole_process::wait();
if ($ret) {
$this->rebootProcess($ret);
}
}else{
break;
}
}
} }
$process = new Process();

这里代码中,使用了swoole_table作为进程间共享的内存,为了分配index。以及当进程退出后,父进程通过wait重新拉起该进程任务。

测试截图

进程ps

结果 休眠20s后退出后会被自动拉起

PHP swoole process的使用的更多相关文章

  1. swoole深入学习 4. process

    swoole-1.7.2增加了一个进程管理模块,用来替代PHP的pcntl扩展.pcntl是php新增的一个多进程扩展,用来实现多进程,但是有很多不完善的地方,swoole 就完善了这些地方,而且使得 ...

  2. Swoole 进程管理模块 Process 之单进程的使用

    PHP 自带的 pcntl,存在很多不足,如: 没有提供进程间通信的功能: 不支持重定向标准输入和输出: 只提供了 fork 这样原始的接口,容易使用错误: Swoole\Process 提供了如下特 ...

  3. 【swoole】如果使用好定时器功能

    swoole中提供了一个定期器的用法 $server->tick(1000, function() use ($server, $fd) { $server->send($fd, &quo ...

  4. 安装使用swoole

    swoole首页:https://www.swoole.com/ 方法1:使用pecl安装 pecl install swoole 注意,php版本必须是7.0以及7.0以上的版本. 方法2:编译源码 ...

  5. swoole创建工作进程,执行滞后工作

    一,创建守候进程,因为这里不需要Server,也没有Client,数据交换通过redis进行 <?php namespace Kuba\Saas; require_once __DIR__ . ...

  6. swoole 连接池

    proxy_pool.php <?php class ProxyServer { protected $frontends; protected $backends; /** * @var sw ...

  7. LaravelS - 基于Swoole加速Laravel/Lumen

    LaravelS LaravelS是一个胶水项目,用于快速集成Swoole到Laravel或Lumen,然后赋予它们更好的性能.更多可能性.Github 特性 内置Http/WebSocket服务器 ...

  8. swoole 监控文件改动

    <?php /** * 场景: * 进程监控文件改动 */ date_default_timezone_set('PRC'); echo '进程id:' . posix_getpid() . P ...

  9. swoole 消息队列

    <?php /** * 场景: * 监控订单表状态 队列通信 * 一个进程向队列发布消息 另外两个进程争抢 */ //设置主进程名 echo '主进程id:' . posix_getpid() ...

随机推荐

  1. C#中Graphics的画图代码【转】

    我要写多几个字上去 string str = "Baidu"; //写什么字? Font font = Font("宋体",30f); //字是什么样子的? B ...

  2. springboot 集成dubbo

  3. 对一个结果集(List)进行手动分页

    对一个链表List,进行手动分页,核心代码就是pagin函数: import lombok.extern.slf4j.Slf4j; import org.junit.Before; import or ...

  4. export default 与 export

    export default 只能导出一个 可以用任意的变量来接收 export 可以暴露多个成员,需要用 import {} 接受成员 需要用名字接受 名字必须跟导出名字一致  //或者as作为别名 ...

  5. eclipse egit(版本回退)

    在公司一年多了,用到的项目都是用svn代码托管,没有git 的用武之地,趁国庆假期稍微自学了一下,然后人比较懒,不愿用原生敲命令行的形式,就在eclipse上学学怎么用git,话说回来用了svn再来学 ...

  6. Gradle安装和在IDEA使用 基本操作

    阅读目录 简单介绍 安装 使用idea创建一个web的Gradle项目 如何进行打包 解释build.gradle和settings.gradle 有关gradle的jar冲突 本地jar包位置和修改 ...

  7. Hibernate一对多单向关联和双向关联映射方法及其优缺点 (待续)

    一对多关联映射和多对一关联映射实现的基本原理都是一样的,既是在多的一端加入一个外键指向一的一端外键,而主要的区别就是维护端不同.它们的区别在于维护的关系不同: 一对多关联映射是指在加载一的一端数据的同 ...

  8. JMeter学习(十)参数化User Defined Variables与User Parameters(转载)

    转载自 http://www.cnblogs.com/yangxia-test 偶然发现JMeter中有两个元件(User Defined Variables与User Parameters)很相近, ...

  9. python学习day3 编程语言分类 变量 格式化输出

    1.编程语言分类 机器语言:直接使用二进制指令直接编写程序,直接操作计算机硬件,必须考虑硬件细节 汇编语言:使用英文标签代替二进制指令去编写程序,直接操作计算机硬件,必须考虑硬件细节对,不过相比机器语 ...

  10. 一分钟了解Android横竖屏 mdpi hdpi xhdpi xxhdpi xxxhdpi (转)

    转自:http://blog.csdn.net/a704755096/article/details/46342689 DPI:每英寸像素数 简单的屏幕分辨率计算方法: DisplayMetrics ...