版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/z15818264727/article/details/80804932
1.Swoole应用场景
Traditional PHP applications almost always run behind Apache/Nginx,
without much control of the request. This brings several limitations:
1.All memory will be freed after the request. All PHP code needs be re-compiled on every request. Even with opcache enabled, all opcode still needs to be re-executed.
2.It is almost impossible to implement long connections and connection pooling techniques.
3.Implementing asynchronous tasks requires third-party queue servers, such as rabbitmq and beanstalkd.
4.Implementing realtime applications such as chatting servers requires third-party languages, such as nodejs, for example.
2.Swoole运行流程图
首先,我们需要了解一下Swoole的进程模型。Swoole是一个多进程模式的框架(可以类比Nginx的进程模型),当启动一个Swoole应用时,一共会创建2 + n + m个进程,其中n为Worker进程数,m为TaskWorker进程数,2为一个Master进程和一个Manager进程,它们之间的关系如上图所示。
其中,Master进程为主进程,该进程会创建Manager进程、Reactor线程等工作进/线程。
Reactor线程实际运行epoll实例,用于accept客户端连接以及接收客户端数据;
Manager进程为管理进程,该进程的作用是创建、管理所有的Worker进程和TaskWorker进程。
task进程主要处理耗时比较的业务逻辑(例如:第三方调用),在work进程中调用task
3.简单实践
server.php
<?php
$serv = new swoole_server("0.0.0.0", 9566);
// Sets server configuration, we set task_worker_num config greater than 0 to enable task workers support
$serv->set(array('task_worker_num' => 4));
// Attach handler for receive event, which has been explained above.
$serv->on('receive', function($serv, $fd, $reactor_id, $data) {
// We dispath a task to task workers by invoke the task() method of $serv
// This method returns a task id as the identity of ths task
$param = [
'client'=>$data,
'fd'=>$fd
];
$task_id = $serv->task($param);
echo "From thread: reactor_id=$reactor_id\n";
echo "Dispath AsyncTask: task_id=$task_id\n";
});
// Attach handler for task event. The handler will be executed in task workers.
$serv->on('task', function ($serv, $task_id, $src_worker_id, $data) {
// Handle the task and do what you want with $data
echo "New AsyncTask[id=$task_id]" . PHP_EOL;
echo "COME FROM [from_id=$src_worker_id]" . PHP_EOL;
echo "i will deal with: {$data['client']}" . PHP_EOL;
// After the task is handled, we return the results to the caller worker.
$data['apd'] = "I will finish";
//$serv->finish($data);
//or use return where v>1.7.2
return $data;
});
// Attach handler for finish event. The handler will be executed in server workers. The same worker dispatched this task before.
$serv->on('finish', function ($serv, $task_id, $data) {
echo "AsyncTask[$task_id] Finish: {$data['apd']}" . PHP_EOL;
$serv->send($data['fd'],"i have received");
});
$serv->start();
client.php
<?php
for($i=0; $i < 5; $i++)
{
$client = new swoole_client(SWOOLE_TCP | SWOOLE_KEEP);
if(!$client->connect('0.0.0.0', 9566))
{
exit("connect failed\n");
}
$client->send("Client plan to send");
$data = $client->recv(7000, 0);
if($data === false)
{
echo "recv fail\n";
break;
}
var_dump($data);
$client->close();
}