Home
Download
Document
Forum
Video
Donate
Source Code
Sponsors
AI 助理
Products
Swoole-Compiler
CRMEB 新零售社交电商系统
Vprix 远程桌面系统
Login
Register
全部
提问
分享
讨论
建议
公告
开发框架
CodeGalaxy
发表新帖
在 Swoole 服务器程序中如何实现压力反馈
为什么要反馈压力 ==== 服务端程序在遇到高并发请求时,一旦超过程序所能处理的极限,可能会导致崩溃,引发线上服务的大规模雪崩。压力反馈(`Back Pressure`)是一种由服务端主动告知客户端自身资源不足,无法提供服务的一种手段。在 Web 服务中可以返回 `HTTP 503` (`Service Unavailable`)告知客户端当前服务器处于比较高的负载状态。这时客户端可以选择: 1. 等待一定时间后进行重试 2. 切换其他负载较低的节点或者服务器上 3. 暂时停止使用此服务,对相关的业务进行降级处理 PHP-FPM 如何反馈压力 ==== 在传统 `Nginx+PHP-FPM` 服务端程序中,底层有 `3` 个关键的配置影响压力反馈: 1. `php-fpm.conf` 中 `pm.max_chindren` 配置的最大进程数,如配置为 `200` 表示最大启动 `200` 个进程,一旦超过最大进程数,新的请求将不会被 `Accept`,而是进入到 `Listen Backlog` 队列中进行排队,直到有空闲进程才会从队列弹出一个新的请求进行处理 2. `php-fpm.conf` 中 `listen.backlog` 配置 `Listen Backlog` 队列长度,如配置为 `512` ,则表示若没有空闲进程时,最大允许有 `512` 个请求排队 3. 内核参数 `net.core.somaxconn` ,`listen.backlog` 设置的数值不一定是有效的,这取决于内核参数 `net.core.somaxconn` 的设置,实际队列长度为 `min(listen.backlog, net.core.somaxconn)`,例如 `net.core.somaxconn=128`、`listen.backlog=512`,实际的队列长度为 `128` 而不是 `512` 因此在 `Nginx+PHP-FPM` 程序中,最大并发为 `pm.max_chindren + min(listen.backlog, net.core.somaxconn)`,一旦超过之后,就会拒绝新的请求,返回 `502` 错误,向客户端反馈压力。实际项目中,应当设置为一个合适的值,不宜过大或过小。否则就出产生客户端等时间过长,低负载拒绝请求两种问题。 > `Nginx` 无法区分 `502` 和 `503` 错误,这是一个缺点 Swoole 程序如何反馈压力 === 由于 `Swoole` 是完全异步的架构,并发能力更强,在机器资源未耗尽的前提下,是可以无限接受、处理请求的。相比 `Nginx+PHP-FPM` 不好实现压力反馈,一般需要框架层面或者应用层代码中自行抛出 `503` 错误。`Swoole` 底层提供了多项配置可以解决一部分问题。 max_connection --- 限制最大连接数, 超过最大连接数之后,会拒绝新的连接。返回 `502` 错误给 `Gateway` max_coroutine --- 限制最大进程数,`Swoole` 会在接收到客户端请求时创建一个新的协程进行处理,超过最大协程数之后,就会向客户端发送 `HTTP 503` 错误 max_concurrency --- 限制最大并发 `HTTP` 请求数,当前正在处理的请求数超过 `max_concurrency` 后,底层会立即向客户端发送 `HTTP 503` 错误,并关闭连接。 ```php use Swoole\Http\Server; $http = new Server('127.0.0.1', 9501); $http->set([ 'max_connection' => 10000, 'max_coroutine' => 50000, 'max_concurrency' => 500, ]); $http->on('start', function ($server) { echo "Swoole http server is started at http://127.0.0.1:9501\n"; }); $http->on('request', function ($request, $response) { Co::sleep(0.1); // sleep 100ms 模拟请求处理的过程 $response->header('Content-Type', 'text/plain'); $response->end('Hello World'); }); $http->start(); ``` 启动服务器后使用 `ab` 或 `wrk` 压测。 ``` wrk -c 1000 -d 5s http://127.0.0.1:9501/ Running 5s test @ http://127.0.0.1:9501/ 2 threads and 1000 connections Thread Stats Avg Stdev Max +/- Stdev Latency 70.89ms 132.48ms 1.10s 95.39% Req/Sec 7.99k 3.68k 13.03k 66.32% 77521 requests in 5.09s, 5.41MB read Socket errors: connect 0, read 55182, write 0, timeout 0 Non-2xx or 3xx responses: 55182 Requests/sec: 15242.49 Transfer/sec: 1.06MB ``` 可以看到 `5秒` 之内,共发送了 `77521` 个请求,但是有 `55182` 个请求返回了 `503` 。这部分请求就是超过负载后压力反馈的结果。
发布于1年前 · 40 次浏览 · 来自
分享
Rango
为什么要反馈压力 ==== 服务端程序在遇到高并发请求时,一旦超过程序所能处理的极限,可能会导致崩溃,引发线上服务的大规模雪崩。压力反馈(`Back Pressure`)是一种由服务端主动告知客户端自身资源不足,无法提供服务的一种手段。在 Web 服务中可以返回 `HTTP 503` (`Service Unavailable`)告知客户端当前服务器处于比较高的负载状态。这时客户端可以选择: 1. 等待一定时间后进行重试 2. 切换其他负载较低的节点或者服务器上 3. 暂时停止使用此服务,对相关的业务进行降级处理 PHP-FPM 如何反馈压力 ==== 在传统 `Nginx+PHP-FPM` 服务端程序中,底层有 `3` 个关键的配置影响压力反馈: 1. `php-fpm.conf` 中 `pm.max_chindren` 配置的最大进程数,如配置为 `200` 表示最大启动 `200` 个进程,一旦超过最大进程数,新的请求将不会被 `Accept`,而是进入到 `Listen Backlog` 队列中进行排队,直到有空闲进程才会从队列弹出一个新的请求进行处理 2. `php-fpm.conf` 中 `listen.backlog` 配置 `Listen Backlog` 队列长度,如配置为 `512` ,则表示若没有空闲进程时,最大允许有 `512` 个请求排队 3. 内核参数 `net.core.somaxconn` ,`listen.backlog` 设置的数值不一定是有效的,这取决于内核参数 `net.core.somaxconn` 的设置,实际队列长度为 `min(listen.backlog, net.core.somaxconn)`,例如 `net.core.somaxconn=128`、`listen.backlog=512`,实际的队列长度为 `128` 而不是 `512` 因此在 `Nginx+PHP-FPM` 程序中,最大并发为 `pm.max_chindren + min(listen.backlog, net.core.somaxconn)`,一旦超过之后,就会拒绝新的请求,返回 `502` 错误,向客户端反馈压力。实际项目中,应当设置为一个合适的值,不宜过大或过小。否则就出产生客户端等时间过长,低负载拒绝请求两种问题。 > `Nginx` 无法区分 `502` 和 `503` 错误,这是一个缺点 Swoole 程序如何反馈压力 === 由于 `Swoole` 是完全异步的架构,并发能力更强,在机器资源未耗尽的前提下,是可以无限接受、处理请求的。相比 `Nginx+PHP-FPM` 不好实现压力反馈,一般需要框架层面或者应用层代码中自行抛出 `503` 错误。`Swoole` 底层提供了多项配置可以解决一部分问题。 max_connection --- 限制最大连接数, 超过最大连接数之后,会拒绝新的连接。返回 `502` 错误给 `Gateway` max_coroutine --- 限制最大进程数,`Swoole` 会在接收到客户端请求时创建一个新的协程进行处理,超过最大协程数之后,就会向客户端发送 `HTTP 503` 错误 max_concurrency --- 限制最大并发 `HTTP` 请求数,当前正在处理的请求数超过 `max_concurrency` 后,底层会立即向客户端发送 `HTTP 503` 错误,并关闭连接。 ```php use Swoole\Http\Server; $http = new Server('127.0.0.1', 9501); $http->set([ 'max_connection' => 10000, 'max_coroutine' => 50000, 'max_concurrency' => 500, ]); $http->on('start', function ($server) { echo "Swoole http server is started at http://127.0.0.1:9501\n"; }); $http->on('request', function ($request, $response) { Co::sleep(0.1); // sleep 100ms 模拟请求处理的过程 $response->header('Content-Type', 'text/plain'); $response->end('Hello World'); }); $http->start(); ``` 启动服务器后使用 `ab` 或 `wrk` 压测。 ``` wrk -c 1000 -d 5s http://127.0.0.1:9501/ Running 5s test @ http://127.0.0.1:9501/ 2 threads and 1000 connections Thread Stats Avg Stdev Max +/- Stdev Latency 70.89ms 132.48ms 1.10s 95.39% Req/Sec 7.99k 3.68k 13.03k 66.32% 77521 requests in 5.09s, 5.41MB read Socket errors: connect 0, read 55182, write 0, timeout 0 Non-2xx or 3xx responses: 55182 Requests/sec: 15242.49 Transfer/sec: 1.06MB ``` 可以看到 `5秒` 之内,共发送了 `77521` 个请求,但是有 `55182` 个请求返回了 `503` 。这部分请求就是超过负载后压力反馈的结果。
赞
1
分享
收藏
提问
分享
讨论
建议
公告
开发框架
CodeGalaxy
评论
还没有评论!
微信公众号
热门内容
作者其它话题
- CodeGalaxy K3s 轻量集群节点之间如何实现负载均衡
- 有没有办法判断当前是否运行在swoole守护进程里面?
暂无回复的问答
- CodeGalaxy K3s 轻量集群节点之间如何实现负载均衡
- 关于openssl CURL WARNING swSSL_connect: SSL_connect(fd=69) failed. Error: error:141A318A:SSL routines:tls_process_ske_dhe:dh key too small[1|394]
- 多个模型如何进行事务异常回退?
- websocket开启wss报错
- 协程tcp服务器如何使用多进程?recv()方法接收信息,打印出来的pid一直是同一个。没用使用到多进程啊。