一、Swoole协程
应用场景: 一般结合for循环, 涉及到等待操作(io, sleep等)
代码示例:
use Swoole\Coroutine;
use Swoole\Runtime;
use function Swoole\Coroutine\run;
Runtime::enableCoroutine(SWOOLE_HOOK_ALL);
run(function () {
foreach (range(1, 100) as $i) {
Coroutine::create(function () use ($i) {
echo $i;
sleep(1);
});
}
});
echo '已经全部跑完了';
二、Swoole多进程
先安装拓展:sysvmsg(宝塔就有)
生产者和消费者模型
客户端发送消息队列
$key = 1;
$q = msg_get_queue($key);//获取消息队列id
foreach (range(1, 100) as $i) {
msg_send($q, 1, json_encode($i), false);//发送消息队列,参数1
}
echo '进去了';
服务端处理消息队列
//服务端多进程消息队列通信处理(需要单独一个php文件,然后执行php xxx.php)
if (!class_exists('\Swoole\Process') || !function_exists('msg_get_queue')) {
exit('请安装swoole和sysvmsg');
}
$key = 1;
$pool = new \Swoole\Process\Pool(4, SWOOLE_IPC_MSGQUEUE, $key, false);
$q = msg_get_queue($key);
$pool->on("message", function (\Swoole\Process\Pool $pool, $message) {
$message = json_decode($message, true);
echo $message;
});
$pool->start();
三、Swoole连接池
Ⅰ 代处理sql连接池
1.拉库
composer require "open-smf/connection-pool:~1.0"
2.应用代码
<?php
include 'vendor/autoload.php';
use Smf\ConnectionPool\ConnectionPool;
use Smf\ConnectionPool\ConnectionPoolTrait;
use Smf\ConnectionPool\Connectors\PDOConnector;
use Swoole\Coroutine\MySQL;
use Swoole\Http\Request;
use Swoole\Http\Response;
use Swoole\Http\Server;
class HttpServer
{
use ConnectionPoolTrait;
protected $swoole;
public function __construct(string $host, int $port)
{
$this->swoole = new Server($host, $port);
$this->setDefault();
$this->bindWorkerEvents();
$this->bindHttpEvent();
}
protected function setDefault()
{
$this->swoole->set([
'daemonize' => false,
'dispatch_mode' => 1,
'max_request' => 8000,
'open_tcp_nodelay' => true,
'reload_async' => true,
'max_wait_time' => 60,
'enable_reuse_port' => true,
'enable_coroutine' => true,
'http_compression' => false,
'enable_static_handler' => false,
'buffer_output_size' => 4 * 1024 * 1024,
'worker_num' => 4, // Each worker holds a connection pool
]);
}
protected function bindHttpEvent()
{
$this->swoole->on('Request', function (Request $request, Response $response) {
// $request->post接受的数据有点怪异,只能先这样处理
$sqlParams = json_decode($request->post[1], true);
$pool1 = $this->getConnectionPool('pdo');
$connection = $pool1->borrow();
$sql = $request->post[0];
$sth = $connection->prepare($sql);
$sth->execute($sqlParams);
$pool1->return($connection);//尽快归还连接
$data = $sth->fetch(\PDO::FETCH_ASSOC);
if (!$data) {
$data = [
'status' => 0,
'messages' => '没有数据',
];
} else {
$data = [
'status' => 1,
'data' => $data
];
}
$jsonData = json_encode($data);
$response->header('Content-Type', 'application/json');
$response->end($jsonData);
});
}
protected function bindWorkerEvents()
{
$createPools = function () {
// All MySQL connections: [4 workers * 2 = 8, 4 workers * 10 = 40]
$pool1 = new ConnectionPool(
[
'minActive' => 2,
'maxActive' => 10,
],
new PDOConnector,
[
'dsn' => 'mysql:host=192.168.152.129;port=3306;dbname=nwpanda36_com;charset=utf8mb4',
'username' => 'root',
'password' => '123456',
'options' => [
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
\PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC,
\PDO::ATTR_TIMEOUT => 30,
],
]);
$pool1->init();
$this->addConnectionPool('pdo', $pool1);
};
$closePools = function () {
$this->closeConnectionPools();
};
$this->swoole->on('WorkerStart', $createPools);
$this->swoole->on('WorkerStop', $closePools);
$this->swoole->on('WorkerError', $closePools);
}
public function start()
{
$this->swoole->start();
}
}
// Enable coroutine for PhpRedis
Swoole\Runtime::enableCoroutine();
$server = new HttpServer('127.0.0.1', 13200);
$server->start();
3.发送请求
客户端使用php curl请求即可 :php使用curl请求
Ⅱ
Ⅲ