求助 1000 并发量所需服务器配置

求助点:
1.具体服务器几核几G
2.接口域名并发设置大小
3.数据库连接设置大小

我的处理:
1台主服务器 8核 16g 8m带宽
1从服务器 2和2g 2m带宽 (按量付费)

主从服务器环境:
php7.2,(swoole扩展,opcache扩展,redis扩展)
mysql5.6,
nginx1.16.1

框架laravel5.5(因为6.0很多插件不成熟),缓存采用redis,访问量大的表都做了索引处理。图片存储oss,js,css存储oss
主从都采用swoole加速,
主从swoole配置

SWOOLE_HTTP_HOST=127.0.0.1
SWOOLE_MAX_REQUEST=1
SWOOLE_HTTP_WEBSOCKET=false
SWOOLE_HTTP_REACTOR_NUM=16
SWOOLE_HTTP_WORKER_NUM=100
SWOOLE_HTTP_TASK_WORKER_NUM=100
SWOOLE_MAX_REQUEST=3000

我的结果:单页面接口请求返回最大数据150kb,能稳定运行600-800并发;
600并发用户访问流畅(小于3秒),800并发用户访问缓慢(平均8秒)

本帖已被设为精华帖!
本帖由系统于 4年前 自动加精
984054610
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
最佳答案

千万不要被网上的言论带歪了,辟谣:

  1. 单纯凭经验断定一个 PHP-FPM workers 进程占用多少内存是没用的,单个 worker 进程的最高内存占用至少是「在 max_requests 内,内存占用最高的那次 request 所申请的内存」。
  2. 启动大量的 PHP-FPM workers 进程并不能提升高并发的承载能力,反而会导致大量 CPU 上下文切换,尤其是如果你的业务偏向于计算、单次请求所消耗的时间很长,增加 PHP-FPM 进程数量反而会导致平均请求处理时长飙升。
  3. Swoole / 容器 / Kubernetes 之类的东西并不是银弹,你需要深入学习才能了解它(们)适不适合你的场景和需求。如果你没有投入大量精力改造的准备,我不建议你考虑这些方案。并且,使用所谓的「容器」的确能够将单个容器的 CPU 和内存压到很低,但容器还是要运行在实际的物理机器上的,这对提升并发量并没有什么帮助,反而将一部分计算资源划分给了容器调度进程。

我的建议是:

在新业务上线前,要得出你需要多大机器,你需要:(QPS*ART)/NOW=1

  • QPS = Queries per Second. 每秒请求数量,也就是所谓的「并发量」。
  • ART = Average Response Time. 平均响应时间,单位秒。
  • NOW = Number of Workers. PHP-FPM Worker 的数量。

根据单位推算,这个公式可以写为 (N/s*s)/N = 1,因此成立。

假设 QPS = 1000,ART = 0.1s,那么 NOW 为 100 才能够在理想状态下,刚好满足你的业务需求(也就是所有请求都可以在不排队的情况下完成处理)。

那么为了推算 NOW,你就需要知道 ART。你可以在一台 1 核心 CPU 的机器上跑一下你的业务,PHP-FPM max_children 保持为 1 即可。随后用压测工具跑单并发,即可计算大概的平均响应时间。务必单线程,否则没有参考价值。

得到 NOW,也就是所需的 Worker 数量之后,你就可以开始推算需要多大机器了。

一般来说,Worker 进程不建议超过 CPU 核心数的 2~4 倍。因此你可以使用 NOW / 2 甚至 NOW / 4 得到你所需要的 CPU 核心数。

至于内存,你同样可以在一台内存足够的机器上跑一跑你的业务,max_children 调大些,通过 systemctl 之类的工具观察 FPM Worker 进程的内存占用,得出一个大概内存占用量的大概数值,随后将平均内存占用量 * NOW 即可。

最后,在生产环境中,建议你:

  1. 先按照推算数量向上提高一个档位,部署一台机器。
  2. 随后通过 htop 等工具观察实际的 CPU 和内存使用率,尤其是 Load Average 的值。
  3. 如果比较稳定或者偏低,可以再降低一个档位部署一台机器(先不要销毁老机器)。
  4. 随后在业务低峰将 DNS 记录指向新机器,注意 DNS 记录的 TTL 不要太高。
  5. 观察新机器的 Load Average,如果偏高或者雪崩可以立即将 DNS Record 回滚到老机器,恭喜你找到了适合你的机型。如果仍然偏低,可以继续循环第 3 - 5 步,最终实践出最适合你的 Instance Type。
4年前 评论
d186004 3年前
Wi1dcard (作者) 3年前
d186004 3年前
984054610 (楼主) 4年前
EmptyCup 4年前
Wi1dcard (作者) 4年前
EmptyCup 4年前
d186004 3年前
臭鼬 3年前
讨论数量: 15

千万不要被网上的言论带歪了,辟谣:

  1. 单纯凭经验断定一个 PHP-FPM workers 进程占用多少内存是没用的,单个 worker 进程的最高内存占用至少是「在 max_requests 内,内存占用最高的那次 request 所申请的内存」。
  2. 启动大量的 PHP-FPM workers 进程并不能提升高并发的承载能力,反而会导致大量 CPU 上下文切换,尤其是如果你的业务偏向于计算、单次请求所消耗的时间很长,增加 PHP-FPM 进程数量反而会导致平均请求处理时长飙升。
  3. Swoole / 容器 / Kubernetes 之类的东西并不是银弹,你需要深入学习才能了解它(们)适不适合你的场景和需求。如果你没有投入大量精力改造的准备,我不建议你考虑这些方案。并且,使用所谓的「容器」的确能够将单个容器的 CPU 和内存压到很低,但容器还是要运行在实际的物理机器上的,这对提升并发量并没有什么帮助,反而将一部分计算资源划分给了容器调度进程。

我的建议是:

在新业务上线前,要得出你需要多大机器,你需要:(QPS*ART)/NOW=1

  • QPS = Queries per Second. 每秒请求数量,也就是所谓的「并发量」。
  • ART = Average Response Time. 平均响应时间,单位秒。
  • NOW = Number of Workers. PHP-FPM Worker 的数量。

根据单位推算,这个公式可以写为 (N/s*s)/N = 1,因此成立。

假设 QPS = 1000,ART = 0.1s,那么 NOW 为 100 才能够在理想状态下,刚好满足你的业务需求(也就是所有请求都可以在不排队的情况下完成处理)。

那么为了推算 NOW,你就需要知道 ART。你可以在一台 1 核心 CPU 的机器上跑一下你的业务,PHP-FPM max_children 保持为 1 即可。随后用压测工具跑单并发,即可计算大概的平均响应时间。务必单线程,否则没有参考价值。

得到 NOW,也就是所需的 Worker 数量之后,你就可以开始推算需要多大机器了。

一般来说,Worker 进程不建议超过 CPU 核心数的 2~4 倍。因此你可以使用 NOW / 2 甚至 NOW / 4 得到你所需要的 CPU 核心数。

至于内存,你同样可以在一台内存足够的机器上跑一跑你的业务,max_children 调大些,通过 systemctl 之类的工具观察 FPM Worker 进程的内存占用,得出一个大概内存占用量的大概数值,随后将平均内存占用量 * NOW 即可。

最后,在生产环境中,建议你:

  1. 先按照推算数量向上提高一个档位,部署一台机器。
  2. 随后通过 htop 等工具观察实际的 CPU 和内存使用率,尤其是 Load Average 的值。
  3. 如果比较稳定或者偏低,可以再降低一个档位部署一台机器(先不要销毁老机器)。
  4. 随后在业务低峰将 DNS 记录指向新机器,注意 DNS 记录的 TTL 不要太高。
  5. 观察新机器的 Load Average,如果偏高或者雪崩可以立即将 DNS Record 回滚到老机器,恭喜你找到了适合你的机型。如果仍然偏低,可以继续循环第 3 - 5 步,最终实践出最适合你的 Instance Type。
4年前 评论
d186004 3年前
Wi1dcard (作者) 3年前
d186004 3年前
984054610 (楼主) 4年前
EmptyCup 4年前
Wi1dcard (作者) 4年前
EmptyCup 4年前
d186004 3年前
臭鼬 3年前

网上看的一个并发计算公式,并发=QPS * 平均响应时间。你的并发是一千,假设平均响应时间为100ms,那么QPS就是10000,一个php-fpm进程一秒中理论上可以处理10个请求,10000个请求需要1000个php-fpm,一个php-fpm进程占用内存大概在8-20M之间(具体根据实际情况查看),那么php-fpm最少需要占8G内存,所以一台8核16G的服务器应该可以支撑(mysql、redis需要单独其他服务器),考虑到高可用,可再增加一台8核16G服务器做负载均衡。你可以根据你们公司的实际压测情况进行服务器购置。

4年前 评论
zyxcba 4年前
984054610 (楼主) 4年前
EmptyCup (作者) 4年前

@xiaopeng 1台机器怕是开不了1000个fpm,还是要多做负载才行。或者考虑不用fpm用swoole或者go.

4年前 评论
EmptyCup 4年前
984054610 (楼主) 4年前
goodgood (作者) 4年前
EmptyCup 4年前
农村闲散劳动力 4年前
zyxcba

1000qps对应的业务体量并不小,到了这个量级,强烈推荐使用 容器 技术,单纯的堆配置or简单的负载均衡可能无法满足高可用要求,或不是最优选择(如成本控制)。

下面是我们的做法,当然,是以我们的程序为样本得到的数据:

单个容器配置非常低(350mb内存,200mhz cpu),运行laravel开发的服务端api程序。设置fmp模式为静态(static),并设置 max_children = 10 。 单容器的qps大概是不会超过20,但是,如果把 laravel 跑在 swoole 上,qps 可以极大的提升到 100-140 左右。

配合自动扩所容,4h8g的物理机器(甚至更低)或许就已绰绰有余。

4年前 评论
984054610 (楼主) 4年前
zyxcba (作者) 4年前

@zyxcba 你这应该就是把一台机器搞成多个容器做负载吧~,按你这么说 4h8g 的物理机器跑fpm能跑到20*20= 400qps(理论值)。 实际应该远远不够400

4年前 评论

@984054610 我们公司有个服务之前和你差不多 QPS,经过多此趟坑,现在演变成了 redis 和数据库都是独立服务器,然后 1 核 2G 的服务器 7 台左右来支撑这个服务。

4年前 评论
984054610 (楼主) 4年前
农村闲散劳动力 4年前

代码方面能重构 就上swoole 或者Go 拆分服务 有条件可以做成微服务架构 服务器做成集群 多走redis 分布式处理 有条件可以上k8s

4年前 评论
984054610 (楼主) 4年前
Dragonbuf 4年前

单纯上来顶一把,终于碰到 1000 并发而不是动不动就百万并发千万并发的了。

4年前 评论

还是这个实际,终于碰到 1000 并发而不是动不动就百万并发千万并发的了。

4年前 评论
984054610

做了swoole,做了2个域名的负载,服务器配置4核16g,1M带宽,为啥jmeter跑1000并发错误率还是在30%以上,数据库连接用的安装默认选项,nginx限制的1200并发。求哪位大佬能给一个详细的解决方案么,配置:数据库放在服务器上的,目前有2个服务器,1个4核16G,一个2核8g,图片放在oss上的,缓存是用的redis,redis也是放在服务器上的

4年前 评论

千万不要被网上的言论带歪了,辟谣:

  1. 单纯凭经验断定一个 PHP-FPM workers 进程占用多少内存是没用的,单个 worker 进程的最高内存占用至少是「在 max_requests 内,内存占用最高的那次 request 所申请的内存」。
  2. 启动大量的 PHP-FPM workers 进程并不能提升高并发的承载能力,反而会导致大量 CPU 上下文切换,尤其是如果你的业务偏向于计算、单次请求所消耗的时间很长,增加 PHP-FPM 进程数量反而会导致平均请求处理时长飙升。
  3. Swoole / 容器 / Kubernetes 之类的东西并不是银弹,你需要深入学习才能了解它(们)适不适合你的场景和需求。如果你没有投入大量精力改造的准备,我不建议你考虑这些方案。并且,使用所谓的「容器」的确能够将单个容器的 CPU 和内存压到很低,但容器还是要运行在实际的物理机器上的,这对提升并发量并没有什么帮助,反而将一部分计算资源划分给了容器调度进程。

我的建议是:

在新业务上线前,要得出你需要多大机器,你需要:(QPS*ART)/NOW=1

  • QPS = Queries per Second. 每秒请求数量,也就是所谓的「并发量」。
  • ART = Average Response Time. 平均响应时间,单位秒。
  • NOW = Number of Workers. PHP-FPM Worker 的数量。

根据单位推算,这个公式可以写为 (N/s*s)/N = 1,因此成立。

假设 QPS = 1000,ART = 0.1s,那么 NOW 为 100 才能够在理想状态下,刚好满足你的业务需求(也就是所有请求都可以在不排队的情况下完成处理)。

那么为了推算 NOW,你就需要知道 ART。你可以在一台 1 核心 CPU 的机器上跑一下你的业务,PHP-FPM max_children 保持为 1 即可。随后用压测工具跑单并发,即可计算大概的平均响应时间。务必单线程,否则没有参考价值。

得到 NOW,也就是所需的 Worker 数量之后,你就可以开始推算需要多大机器了。

一般来说,Worker 进程不建议超过 CPU 核心数的 2~4 倍。因此你可以使用 NOW / 2 甚至 NOW / 4 得到你所需要的 CPU 核心数。

至于内存,你同样可以在一台内存足够的机器上跑一跑你的业务,max_children 调大些,通过 systemctl 之类的工具观察 FPM Worker 进程的内存占用,得出一个大概内存占用量的大概数值,随后将平均内存占用量 * NOW 即可。

最后,在生产环境中,建议你:

  1. 先按照推算数量向上提高一个档位,部署一台机器。
  2. 随后通过 htop 等工具观察实际的 CPU 和内存使用率,尤其是 Load Average 的值。
  3. 如果比较稳定或者偏低,可以再降低一个档位部署一台机器(先不要销毁老机器)。
  4. 随后在业务低峰将 DNS 记录指向新机器,注意 DNS 记录的 TTL 不要太高。
  5. 观察新机器的 Load Average,如果偏高或者雪崩可以立即将 DNS Record 回滚到老机器,恭喜你找到了适合你的机型。如果仍然偏低,可以继续循环第 3 - 5 步,最终实践出最适合你的 Instance Type。
4年前 评论
d186004 3年前
Wi1dcard (作者) 3年前
d186004 3年前
984054610 (楼主) 4年前
EmptyCup 4年前
Wi1dcard (作者) 4年前
EmptyCup 4年前
d186004 3年前
臭鼬 3年前

建议 @984054610 持续将调优结果列在这里,正好验证一下各种计算方式的差异。

这个 1000qps 的实践比那些百万千万并发的强多了。

4年前 评论

@Wi1dcard
假设 QPS = 1000,ART = 0.1s,那么 NOW 为 100 才能够在理想状态下,
Worker 进程不建议超过 CPU 核心数的 2~4 倍(按4倍算)
QPS = 1000,ART = 0.1s 得不得要25核

4年前 评论
Wi1dcard 4年前

前司电商业务 618 QPS最高峰值 2200 多,三个端 12 台 web 机器 16 核 64 G ,物理机托管。MySQL Redis 队列 搜索等,几百台。

4年前 评论

单纯的QPS没有任何意义

4年前 评论

老板的小说网站,70、80在线人数,用了 8核 16G,挺多都是当缓存了,6M带宽 :joy:

4年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!