先说一下流程:
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参数