yii2利用swoole的http服务器提供高性能接口

8 篇文章 0 订阅

先说一下流程:

1.编写代码,开启http服务器

2.http服务器通过请求过来的url来分发到yii的不同模块不同控制器不同方法来处理业务

3.进行压测

 

1.新建一个php文件HttpController,代码里面用来统一分发请求

代码:

<?php

namespace console\controllers;

use yii\console\Controller;
use Yii;

class HttpController extends Controller
{

    public function actionIndex()
    {
        Yii::getLogger()->flushInterval = 1;
        if (!extension_loaded('swoole')) {
            $this->stderr('Swoole is not installed');
        }
        $this->stdout('Yii2版本:' . Yii::getVersion() . PHP_EOL);
        $this->stdout('Swoole版本:' . SWOOLE_VERSION . PHP_EOL);
        $this->stdout('PHP版本:' . PHP_VERSION . PHP_EOL);
        $this->setProcessName(sprintf('php-swoole:%s', 'http-master'));
        $http = new \Swoole\Http\Server("0.0.0.0", 9501);
        $http->set([
            'worker_num' => 4,
            'request_max' => 1000
        ]);
        $http->on('start', function ($server) {
            echo 'HTTP服务器已经开启' . PHP_EOL;
        });
        $http->on('request', function (\swoole_http_request $request, \swoole_http_response $response) {
            list($controller, $action) = explode('/', trim($request->server['request_uri'], '/'));
            $ReflectionController = '\\api\\controllers\\' . ucfirst($controller) . 'Controller';
            $responseData = (new $ReflectionController($this->id, $this->module))->runAction($action, ['data' => $request->rawContent()]);
            $response->end($responseData);
        });
        $http->start();
    }

    /**
     * 设置进程名
     * @param $name
     */
    public function setProcessName($name)
    {
        if (function_exists('cli_set_process_title')) {
            cli_set_process_title($name);
        } else {
            swoole_set_process_name($name);
        }
    }
}

开启服务:

2.测试url是否进行分发,这里的分发控制器为api\controllers\processController,方法为tasks方法

<?php

namespace api\controllers;

use common\models\Task;
use Yii;

class ProcessController extends AppController
{
    public $enableCsrfValidation = false;

    public function actionCreate($data)
    {
        try {
            while (true) {
                $isLock = Yii::$app->redis->setnx('TASK_LOCK', mt_rand(10000, 99999));
                if ($isLock) {
                    $lpushResult = Yii::$app->redis->lpush('TASK:TASK_MSG', $data);
                    if ($lpushResult) {
                        Yii::$app->redis->del('TASK_LOCK');
                        return json_encode(['status' => 200, 'description' => '存入redis成功']);
                    }
                } else {
                    usleep(200);
                }
            }
        } catch (\Exception $exception) {
            Yii::$app->redis->del('TASK_LOCK');
            Yii::error($exception->__toString());
            throw $exception;
        }
    }
    public function actionTasks()
    {
        return Task::getTasks();
    }
}

这里的Task模型中的getTasks方法为:

<?php


namespace common\models;


use yii\db\ActiveRecord;
use Yii;

class Task extends ActiveRecord
{
    public static function tableName()
    {
        return '{{%task}}';
    }

    public static function getTasks()
    {
        $result = Yii::$app->redis->get('TASK:INFO');
        if ($result) {
            return $result;
        }
        return json_encode(self::find()->where(['type' => 'ok'])->asArray()->all());
    }
}

下面进行postman请求:

我们可以看到已经查询到消息了,说明已经分发到不同模块的不同控制器的不同方法去了

下面进行开启了swoole的http服务压测:进行1000次请求,100次并发,我们开了4个worker进程,压测结果如果:

qps大概为1316左右

然后我们再用php-fpm来进行同样的压测

结果发现qps只有10左右

相对比一下,可以发现性能提升了差不多130倍

当然实际效果和机器配置有关,这里只是做一个参考。

注释:可能需要修改网站的nginx配置:

如图参考:

如果需要开启swoole的http服务器,这里还需要先配置nginx参数

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值