详解PHP swoole process的使用方法


Posted in PHP onAugust 26, 2017

引入背景:假如我们每天有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

详解PHP swoole process的使用方法

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

详解PHP swoole process的使用方法

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

PHP 相关文章推荐
PHP中使用crypt()实现用户身份验证的代码
Sep 05 PHP
基于php上传图片重命名的6种解决方法的详细介绍
Apr 28 PHP
非常实用的php弹出错误警告函数扩展性强
Jan 17 PHP
Discuz批量替换帖子内容的方法(使用SQL更新数据库)
Jun 23 PHP
php递归删除指定文件夹的方法小结
Apr 20 PHP
typecho插件编写教程(五):核心代码
May 28 PHP
PHP Callable强制指定回调类型的方法
Aug 30 PHP
PHP面向对象继承用法详解(优化与减少代码重复)
Dec 02 PHP
Yii框架用户登录session丢失问题解决方法
Jan 07 PHP
关于Curl在Swoole协程中的解决方案详析
Sep 12 PHP
Laravel开启跨域请求的方法
Oct 13 PHP
PHP项目多语言配置平台实现过程解析
May 18 PHP
Yii2框架可逆加密简单实现方法
Aug 25 #PHP
PHP5.6新增加的可变函数参数用法分析
Aug 25 #PHP
php变量与JS变量实现不通过跳转直接交互的方法
Aug 25 #PHP
CodeIgniter整合Smarty的方法详解
Aug 25 #PHP
PHP观察者模式原理与简单实现方法示例
Aug 25 #PHP
PHP实现的策略模式简单示例
Aug 25 #PHP
php实现简单的权限管理的示例代码
Aug 25 #PHP
You might like
php操作excel文件 基于phpexcel
2010/07/02 PHP
php入门学习知识点六 PHP文件的读写操作代码
2011/07/14 PHP
codeigniter使用技巧批量插入数据实例方法分享
2013/12/31 PHP
PHP获取php,mysql,apche的版本信息示例代码
2014/01/16 PHP
thinkphp四种url访问方式详解
2014/11/28 PHP
微信公众平台实现获取用户OpenID的方法
2015/04/15 PHP
PHP7之Mongodb API使用详解
2015/12/26 PHP
php实现学生管理系统
2020/03/21 PHP
基于js disabled=&quot;false&quot;不起作用的解决办法
2013/06/26 Javascript
javascript 获取iframe里页面中元素值的方法
2014/02/17 Javascript
javascript实现2016新年版日历
2016/01/25 Javascript
Node.js Streams文件读写操作详解
2016/07/04 Javascript
json定义及jquery操作json的方法
2016/10/03 Javascript
jquery 动态增加,减少input表单的简单方法(必看)
2016/10/12 Javascript
微信公众号  提示:Unauthorized API function 问题解决方法
2016/12/05 Javascript
微信小程序 解析网页内容详解及实例
2017/02/22 Javascript
vue数据双向绑定原理解析(get &amp; set)
2017/03/08 Javascript
Webpack打包慢问题的完美解决方法
2017/03/16 Javascript
jQuery动态添加.active 实现导航效果代码思路详解
2017/08/29 jQuery
浅谈vue中慎用style的scoped属性
2017/11/28 Javascript
微信小程序实现自定义加载图标功能
2018/07/19 Javascript
对angularJs中自定义指令replace的属性详解
2018/10/09 Javascript
python实现在pickling的时候压缩的方法
2014/09/25 Python
Python+tkinter使用80行代码实现一个计算器实例
2018/01/16 Python
python字典改变value值方法总结
2019/06/21 Python
详解python opencv、scikit-image和PIL图像处理库比较
2019/12/26 Python
Python函数递归调用实现原理实例解析
2020/08/11 Python
Python尾递归优化实现代码及原理详解
2020/10/09 Python
德国机场停车位比较和预订网站:Ich-parke-billiger
2018/01/08 全球购物
节省高达65%的城市景点费用:Go City
2019/07/06 全球购物
讲文明树新风演讲稿
2014/05/12 职场文书
乡镇党的群众路线教育实践活动个人整改方案
2014/10/31 职场文书
优秀学生干部事迹材料
2014/12/24 职场文书
涨工资申请书应该怎么写?
2019/07/08 职场文书
一文读懂navicat for mysql基础知识
2021/05/31 MySQL
船舶调度指挥系统——助力智慧海事
2022/02/18 无线电