Home>Article>PHP Framework> High-concurrency instance sharing: Swoole efficiently implements business through aggregation of requests
This article will share with you an example of Swoole's high-concurrency aggregation request, and introduce how to make full use of the batch processing of the database to implement business functions more efficiently through aggregation of requests in high-concurrency scenarios. This example is only used as a starting point, hoping to stimulate more in-depth thinking.
Recommended related video courses: "Tens of millions of data concurrency solutions (theoretical and practical)"
Share some high-concurrency interview questions:15 PHP interview questions about high concurrency (summary)
The background selected for this example is the concurrent order business. Under normal circumstances, creating an order on the backend is ainsert
operation one by one. When concurrency is low, the database'sinsert
operation can indeed maintain good efficiency, but when the number of requests increases, the databasefrequently performs a singleinsert
This will make the overall efficiency of the order business lower(this article simply assumes that 1 order = 1insert
).
Through the above description, it is actually easy to think of the areas that need optimization. Analogy to the scene of taking an elevator in real life: an elevatoris filled and then goes up, which can relieve the pressure of people flow as quickly as possible.
Let’s simply implement our idea with code:
pop(1); // 保存1个正常的请求数据 if (!empty($rq)) { $rqQueue[] = $rq; } // 请求数量未达上限或者还有等待次数时, 提前进入下一次循环 if ($times > 0 && count($rqQueue) < MAX_REQUEST) { continue; } // 重置等待次数 $times = MAX_TIMES; // 初始化SQL $sql = "INSERT INTO orders VALUES "; $inserts = []; // 模拟数据验证 $validator = function ($input): bool { // 为了缩减代码, 没有真的做数据验证的处理 array_filter($input); return true; }; // $rqQueue在协程上下文是并发安全的, 所以遍历时不用担心 foreach ($rqQueue as $index => $rq) { list($data, $chan) = $rq; // 这里可以考虑后置执行, 原因是后面可以有一些补救逻辑 unset($rqQueue[$index]); // 判断$chan是否关闭å if ($chan->errCode === SWOOLE_CHANNEL_CLOSED) { $data = null; continue; } $bool = $validator($data); if ($bool) { $inserts[] = "({$data['user_name']}, {$data['amount']}, {$data['mobile']})"; $chan->push(['state' => 1]); } else { $chan->push(['state' => 0]); } // unset($rqQueue[$index]); } $sql .= (implode(',', $inserts) . ';'); // 模拟创建订单落库的逻辑 echo $sql; } }; // 新手要注意这一句代码的位置, 原因是 $server->start() 之后的代码不会执行 go($createOrder); // 路由处理器 $orderHandler = function ($rq, $res) use ($rqChannel) { $chan = new Swoole\Coroutine\Channel(1); // 使用timeout参数模拟超时 $bool = $rqChannel->push([$rq->post, $chan], MAX_TIMEOUT); if (!$bool) { // 关闭$chan $chan->close(); $res->end('timeout'); } if (!empty($data = $chan->pop())) { // 关闭$chan $chan->close(); // 区分成功或失败状态再输出响应 if ($data['state'] === 1) { $res->end(microtime()); } else { $res->end('error'); } } }; $server = new Co\Http\Server("0.0.0.0", 9502, false); $server->handle('/order/create', $orderHandler); // 当前协程容器的终点 $server->start(); });
The code is still very easy to understand as a whole,Variables$rqQueue
is the analogy of an elevator. The number of times a hold request has to wait for a certain period of time$times
is analogous to the need for an elevator to wait for the flow of people to enterone after another. Of course, the most important thing I hope readers will pay attention to is:In a coroutine environment, do not use shared memory for communication, but use communication to share memory.
Recommended learning:swoole tutorial
The above is the detailed content of High-concurrency instance sharing: Swoole efficiently implements business through aggregation of requests. For more information, please follow other related articles on the PHP Chinese website!