easyswoole框架生命周期

具体可参考核心代码文件:vendor/easyswoole/easyswoole/src/Core.php

 

框架生命周期

服务类型

EASYSWOOLE_SERVER (对应Swoole\Server)

EASYSWOOLE_WEB_SERVER (对应Swoole\Http\Server)

EASYSWOOLE_WEB_SOCKET_SERVER (对应Swoole\WebSocket\Server)

easyswoole案例演示

tcp请求:

#在CliExample目录下执行 php TCPClient3.php

服务端回复: 1557998515

服务端回复: your args is:{"name":"\u4ed9\u58eb\u53ef"}

#服务端内容响应:

已连接

tcp服务3 fd:3 发送消息:M{"controller":"Index","action":"index","param":{"name":"\u4ed9\u58eb\u53ef"}}

tcp服务3 fd:3 发送消息:L{"controller":"Index","action":"args","param":{"name":"\u4ed9\u58eb\u53ef"}}

tcp服务3 fd:3 已关闭

服务端通过addListener开启9504端口监听,客户端通过$client->connect('127.0.0.1', 9504, 0.5)发起链接后发送数据。服务端通过\EasySwoole\Socket\Dispatcher->dispatch进行路由解析,并执行具体动作后将数据返回给客户端。

http请求:

#按照demo案例添加App/HttpController/Test.php,并访问以下函数

function index()

{
$this->response()->write('test index');

}

# 访问 http://mytest.easyswoole.com/Test/index

输出:test index

压力测试:

#硬件信息

CPU:1核 Intel(R) Xeon(R) Gold 6148 CPU @ 2.40GHz

内存:1GB

操作系统: Ubuntu / 16.04 LTS amd64 (64bit)

# ab长连接压测swoole页面(ab -c 100 -n 100000 -k http://127.0.0.1:9501/Test/index)返回:

Concurrency Level: 100

Time taken for tests: 18.085 seconds

Complete requests: 100000

Failed requests: 0

Keep-Alive requests: 100000

Total transferred: 15500000 bytes

HTML transferred: 1000000 bytes

Requests per second: 5529.44 [#/sec] (mean)

Time per request: 18.085 [ms] (mean)

Time per request: 0.181 [ms] (mean, across all concurrent requests)

Transfer rate: 836.98 [Kbytes/sec] receive

#ab非长连接压测swoole页面(ab -c 100 -n 100000 http://127.0.0.1:9501/Test/index)返回:

Concurrency Level: 100

Time taken for tests: 46.141 seconds

Complete requests: 100000

Failed requests: 0

Total transferred: 15000000 bytes

HTML transferred: 1000000 bytes

Requests per second: 2167.29 [#/sec] (mean)

Time per request: 46.141 [ms] (mean)

Time per request: 0.461 [ms] (mean, across all concurrent requests)

Transfer rate: 317.47 [Kbytes/sec] received

#ab长连接压测nginx页面(ab -c 100 -n 100000 -k http://127.0.0.1/test.php)返回:

Concurrency Level: 100

Time taken for tests: 36.257 seconds

Complete requests: 100000

Failed requests: 0

Keep-Alive requests: 0

Total transferred: 14700000 bytes

HTML transferred: 1000000 bytes

Requests per second: 2758.12 [#/sec] (mean)

Time per request: 36.257 [ms] (mean)

Time per request: 0.363 [ms] (mean, across all concurrent requests)

Transfer rate: 395.94 [Kbytes/sec] received

swoole页面的长连接比非长连接qps高出一半,nginx非长连接压测的qps比swoole非长连接压测的qps要高

自定义进程

#按照demo部署代码,并稍微调整EasySwooleEvent.php下函数mainServerCreate代码

public static function mainServerCreate(EventRegister $register)

{
/**

* 除了进程名,其余参数非必须

*/

for($i=0;$i<3;$i++){
$myProcess = new ProcessOne("processName".$i,$i,false,2,true);

ServerManager::getInstance()->getSwooleServer()->addProcess($myProcess->getProcess());

}

}

#稍微调整App/Process/ProcessOne.php代码

public function run($arg)

{
Logger::getInstance()->console($this->getProcessName().'-'.$arg." start");

while (1){
\co::sleep(4-$arg);

Logger::getInstance()->console($this->getProcessName().'-'.$arg." run");

}

}

#查询执行的进程:

root@instance-wjbdyzhe:/data/web/mytest.easyswoole.com# ps -aux|grep processName

root 10288 0.0 0.0 14688 908 pts/0 S+ 20:53 0:00 grep --color=auto processName

root 24261 0.0 1.2 232932 12308 pts/2 S+ 20:04 0:00 processName0

root 24262 0.0 1.2 232932 12308 pts/2 S+ 20:04 0:00 processName1

root 24263 0.0 1.2 232932 12308 pts/2 S+ 20:04 0:00 processName2

#三个进程的执行结果:

[2019-04-28 08:56:37][default]processName0-0 start

[2019-04-28 08:56:37][default]processName2-2 start

[2019-04-28 08:56:37][default]processName1-1 start

[2019-04-28 08:56:39][default]processName2-2 run

[2019-04-28 08:56:40][default]processName1-1 run

[2019-04-28 08:56:41][default]processName0-0 run

[2019-04-28 08:56:41][default]processName2-2 run

[2019-04-28 08:56:43][default]processName1-1 run

[2019-04-28 08:56:43][default]processName2-2 run

可以看到以上代码及执行结果:执行程序后,创建了三个自定义进程,并且进程是并行执行的

异步任务:

#按照demo部署代码,并调整以下函数

function multiTaskConcurrency(){
// 多任务并发

$tasks[] = function () { sleep(1);return 'this is 1'; }; // 任务1

$tasks[] = function () { sleep(5);return 'this is 2'; }; // 任务2

$tasks[] = function () { sleep(3);return 'this is 3'; }; // 任务3

$results = \EasySwoole\EasySwoole\Swoole\Task\TaskManager::barrier($tasks, 6);

var_dump($results);

$this->response()->write('执行并发任务成功');

}

# 访问 http://mytest.easyswoole.com/index/multiTaskConcurrency

输出:

array(3) {
[0]=>

string(9) "this is 1"

[2]=>

string(9) "this is 3"

[1]=>

string(9) "this is 2"

}

由代码和打印来看,虽然任务2排在第二位,但由于执行时间长,执行结果排在最后,由此可知三个任务并非串行执行,而是并行执行

连接池

#最大进程配置数8个

'SETTING' => [

'worker_num' => 8,

'max_request' => 5000,

'task_worker_num' => 8,

'task_max_request' => 1000,

],

#每个进程连接池最大连接个数5个

'REDIS' => [

'host' => '127.0.0.1',

'port' => '6379',

'auth' => 'test',

'POOL_MAX_NUM' => '5',

'POOL_TIME_OUT' => 'utf8mb4',

],

#jmeter压测配置

线程数:100;ramp-up时间:10;循环次数:30

#通过redis客户端查看链接信息:

127.0.0.1:6379> info clients

# Clients

connected_clients:41

client_recent_max_input_buffer:4

client_recent_max_output_buffer:0

blocked_clients:0

理论最大redis链接数 = worker_num*POOL_MAX_NUM = 8*5 = 40

并发压测客户端显示 = 41-1 = 40(多一个1实际为手动链接)

只要不终止swoole/server服务客户端连接,显示一直为41,表示链接一直处于链接可用状态。

#最大进程配置数8个

'SETTING' => [

'worker_num' => 8,

'max_request' => 5000,

'task_worker_num' => 8,

'task_max_request' => 1000,

],

#匿名连接池最大配置10个链接

'MYSQL3' => [

'host' => '127.0.0.1',//防止报错,就不切换数据库了

'port' => '3306',

'user' => 'root',

'timeout' => '5',

'charset' => 'utf8mb4',

'password' => '123456',

'database' => 'test',//防止报错,就不切换数据库了

'POOL_MAX_NUM' => '10',

'POOL_TIME_OUT' => '0.1'

],

#jmeter压测配置

线程数:100;ramp-up时间:10;循环次数:30

#通过mysql查看链接个数

mysql> show processlist;

……

| 306155 | root | 172.17.0.1:48704 | test | Sleep | 30 | | NULL |

| 306156 | root | 172.17.0.1:48840 | test | Sleep | 36 | | NULL |

| 306157 | root | 172.17.0.1:48846 | test | Sleep | 29 | | NULL |

+--------+------+------------------+------+---------+------+----------+------------------+

81 rows in set (0.00 sec)

理论最大mysql链接数 = worker_num*POOL_MAX_NUM = 8*10 = 80

并发压测客户端显示 = 81-1 = 80(多一个1实际为手动链接)

过一段再show processlist发现已无链接,可能mysql主动超时中断,有兴趣的同学可主动排查