PHP多進程開發與Redis結合實踐

業務邏輯介紹:

  1. 用戶在 APP 上發帖子,然後存儲到 Redis 的 List 列表中
  2. 利用 Linux 的 crontab 定時任務功能,按秒請求執行PHP腳本文件(processNewsRedisList.php)
  3. 調用 redis_process 處理API,進行存儲到 Mysql 中

 

1.發帖子API

 

public function post_json() {

        $image = $_FILES['image'];
        $data = I();

        $images = $this->post_upload($image);
        $data['image'] = $images ? $images : '';

        if( count($data) ){
            $redis = new Redis();
            $data['creation_time'] = time();
            //把發過來的帖子存儲redis
            $result = $redis->lpush('news_list', json_encode($data));
//          $redis->lpush('news_list', json_encode($data));
//          while (TRUE){
//              if ($redis->lsize('news_list') > 0){
//                  $info = $redis->rpop('news_list');
//                  $info = json_decode($info, true);

//                  $result = $this->_model->news_publish( $info );
//              }else {
//                  sleep(1);break;
//              }
//          }
//          $redis->close();
            $data['creation_time'] = time();

//          $result = $this->_model->news_publish( $data );

            if( $result < 1 ){//redis方式
//          if( !$result ){//model方式

                $this->_data['data'] = '';
                $this->_data['error'] = true;
                $this->_data['message'] = L('_DATABASE_ERROR_');

            }else{//success

                $this->_data['data'] = $result;
                $this->_data['error'] = false;
            }

        }
        else{
            $this->_data['data'] = '';
            $this->_data['error'] = true;
            $this->_data['message'] = L('_Invalid_Parameters_');
        }

        $this->response($this->_data);
    }

 
 

2.processNewsRedisList.php

<?php
/**
*檢查隊列中帖子,並把帖子插入數據庫表中
*/

function worker()
{
        //再次克隆出子進程
        $pid = pcntl_fork();
        if ( $pid == -1 ) {
                exit('fork error');
        }
        if ( $pid == 0 ) {
                $redis = new Redis();
                $redis->connect('127.0.0.1', 7200);
                //業務邏輯代碼
                while(true) {//sleep(5);
                        if( $redis->lsize('news_list') > 0 ){
                                $info = $redis->rpop('news_list');
                                $info = json_decode($info, TRUE);
                                //使用curl調用API接口
                                $uri = "http://*.*.*.*:*/api.zmartec/News/redis_process";

                                $data = $info;
                                $ch = curl_init();
                                curl_setopt($ch, CURLOPT_URL, $uri);
                                curl_setopt($ch, CURLOPT_POST, 1);
                                curl_setopt($ch, CURLOPT_HEADER, 0);
                                curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
                                curl_setopt($ch, CURLOPT_POSTFIELDS, $data);

                                $result = curl_exec($ch);
                                curl_close($ch);
                        } else {
                                sleep(1);//隊列中沒有任務的時候,睡眠1s,讓出cpu給其它進程
                        }
                }
                $redis->close();
        }
}

/**
*子進程,負責設置子進程爲領導小組
*
*並調用處理函數,處理任務
*/
function children()
{
        $sid = posix_setsid();
        echo $sid;
        for( $i = 0; $i < 2; $i++ ) {
                worker();
        }
}

//克隆子進程,返回子進程的進程id
$pid = pcntl_fork();
if ( $pid == -1 ) {
        exit('fork error');
}

if ( $pid == 0 ) {
        children();
}else{
        exit('parent exit');
}

?>

 
 

3.存儲帖子到 Mysql

thinkphp 3.2框架:
public function redis_process()
{
        $data = $_POST;
        if ($this->_model->news_publish($data)) {
                    return true;
                } esle {
            return false;
              }
    }

public function news_publish( $data )
{

        try{
            return M('news')->add($data);
        }catch(Exception $ex){
            return FALSE;   
        }   
    }

 
 
 
 
不足有誤之處敬請指出,謝謝!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章