300万PV用5台服务器,核心思路是“分层部署、按需扩容”:2台Nginx负载均衡、2台应用服务器、1台数据库服务器,搭配合理的缓存和集群方案,完全能扛住日常流量,还能应对突发峰值。
这套设计不是拍脑袋定出来的,300万PV看着吓人,换算成每秒请求数,实际压力比想象中小得多,假设流量集中在8小时,平均QPS大概在104左右,即便高峰翻5倍,也就500 QPS,这个量级对服务器硬件的要求并不苛刻,关键是架构要合理。
5台服务器怎么分配最合理?
很多团队习惯把服务全堆一起,出问题再临时加机器,但既然有5台,就要发挥集群的价值,我们按“前端代理、业务逻辑、数据存储”三个维度来拆。
| 角色 | 数量 | 配置建议 | 承担职责 |
|---|---|---|---|
| Nginx负载均衡 | 2台 | 4核8G,SSD系统盘 | 静态资源、SSL终结、流量分发 |
| 应用服务器 | 2台 | 8核16G,SSD | 业务接口、定时任务、缓存操作 |
| MySQL主库 | 1台 | 8核16G,SSD高IOPS | 数据持久化,主从延迟可接受则单机 |
核心逻辑在于:把Nginx和应用拆开,Nginx负责收流量、挡网络攻击,应用只聚焦业务逻辑,如果未来PV涨到500万,只需要在Nginx层加机器,应用层保持不动,扩容成本很低。
这是基础版,现实中还要考虑数据库读写分离,如果300万PV里包含大量读操作,建议把“1台数据库”拆成“1主1从”,把另外2台应用里拨出1台做从库读写分离?这样应用就只剩1台,扛不住,所以5台是起步门槛,更好的方案是:3台应用+2台Nginx,数据库单独外置,用云数据库,但题目给定5台,我们就按混合部署来调优。
深化一下:应用服务器上能不能挂MySQL?
可以,但要明确一点:MySQL要独享一台机器,如果把数据库和应用混布在同一台,一旦CPU打满,数据库查询延迟会指数级上升,最终拖垮整个集群,行业共识认为,数据库和业务必须物理隔离。
那5台里,Nginx占2台,应用占2台,数据库1台,这个模型没问题,但若业务有大量图片上传、文件下载,Nginx还要承担静态资源分发,磁盘IO会成瓶颈,此时建议把两个Nginx挂一个
共享存储,或者直接用对象存储托管静态文件,Nginx只做反向代理,压力瞬间降一半。
300万PV流量下,缓存要怎么做?
缓存是整个架构的灵魂,没有缓存,5台服务器扛不住系统性的读压力,我们分三层说:
- 浏览器缓存:Nginx设置
expires指令,给图片、CSS、JS配置7天过期,用户二次访问根本不触达服务器,据统计,这部分能减少60%左右的请求量。 - 缓存服务层:在应用服务器上部署Redis,把热点数据甩进内存,比如首页运营位、商品分类、用户Session,Redis命中率做到90%以上,数据库就轻松了。
- Nginx Lua缓存:如果接口响应要毫秒级,用Nginx的
lua-resty-redis直接读缓存,绕过PHP/Java进程,许多大站都这么干。
具体实操命令如下(以CentOS为例):
# 生成2048位DH密钥,启用Nginx SSL
openssl dhparam -out /etc/nginx/dhparam.pem 2048
# 配置Nginx缓存静态文件
location ~ .(jpg|png|css|js)$ {
expires 7d;
add_header Cache-Control "public, no-transform";
}
缓存里还有一类特殊数据热点新闻或活动页,这类页面瞬时流量巨大,建议直接生成静态HTML,从Nginx直接返回,不走应用逻辑,之前有客户搞秒杀,5台服务器扛住了20万并发,靠的就是把商品页静态化加缓存。
数据库层怎么设计才不会崩?
MySQL单机在300万PV下,如果缓存不力,很容易把连接数打满,我们要做三件事:
一是慢查询治理。 开启慢查询日志,定位SELECT漏网之鱼。long_query_time设成2秒,每天看一次日志。
set global slow_query_log = ON;
set global long_query_time = 2;
二是连接池调优。 应用服务器和MySQL之间用连接池接管,最大连接数控制在300以下,很多人踩坑是因为框架里连接泄漏,最后MySQL报Too many connections,改配置不是重点,排查泄漏才是根本。
三是分库分表预案。 300万PV日活用户大约20到50万,用户表、订单表基本在百万级,单库单表够用,但业务模型如果是社交类或弹幕类,数据量增长快,就要提前设计user_id取模分表,具体拆分规则不宜过度设计,等单表超过2000万再拆也来得及。
突发流量来了,5台服务器扛得住吗?
扛得住,但前提是你做了限流和熔断,抢购和热点新闻是两回事,如果是被人恶意刷量,5台服务器再大也白搭。
Nginx层限流是基础操作:
# 限制每个IP每秒1个请求
limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
location /api/ {
limit_req zone=one burst=5;
}
应用层还要用Redis做分布式限流,比如同一个用户订单提交接口每秒超过2次,直接返回“操作频繁”,别小看这个,很多小团队忽略这层,结果活动开启半小时应用就宕机。
Nginx要开Gzip压缩,300万PV里前端资源占比高,不压缩的话带宽会吃满,配置如下:
gzip on;
gzip_comp_level 5;
gzip_types text/plain text/css application/json application/javascript;
压缩后传输体积减少70%,服务器带宽成本大幅下降。
5台服务器怎么做高可用和容灾?
很多人的误区是“5台服务器只能做集群,做不了高可用”,其实可以,我们按主备思路来:
- Nginx层:2台Nginx用keepalived绑定VIP,默认走主节点,主节点宕机,备用节点自动接管,切换时间控制在1秒以内。
- 应用层:2台应用服务器无状态化,把Session存Redis,Nginx负载均衡策略用
least_conn,保证两台机器连接数均衡,其中一台挂掉,Nginx自动摘除,不影响整体服务。 - 数据库层:这一层弱一些,只有1台MySQL,没法做主从,但我们可以做物理备份加Binlog定时同步到异地机器,如果机器硬件损坏,用最近备份加Binlog重放,数据丢失控制在5分钟以内。
如果预算允许,哪怕再加1台机器,也要给数据库搭建主从复制,实现秒级故障转移,5台服务器是经济型方案
,不是极致可用方案,但通过配置能达到9%的可用性,对大多数业务够用。
设计这套架构时常见的几个问题
为什么不用Docker容器化部署?
容器化确实方便,但5台服务器做集群,Docker会增加一层网络转发损耗,更重要的是,很多人对容器安全不熟悉,容易把数据目录挂载到本地,反而加大故障概率,建议直接用ansible脚本写好部署步骤,同样可以做到快速交付。
300万PV需要多少带宽?
这是很关键的参数,如果页面平均大小1MB,300万PV就是3TB流量,按30天算平均每天100GB,按8小时忙时算峰值带宽约28Mbps,听起来不高,但若是API接口返回JSON,再减去缓存和压缩,实际需求更小。50Mbps带宽富裕,100Mbps绝对够。
Nginx和应用服务器要不要选不同配置?
Nginx是IO密集型,CPU要求不高,4核8G就够了,应用服务器是计算密集型,8核16G是标配,另外内存要预留给Redis使用,如果Redis和应用部署在同一台,建议应用服务器内存加到32G,一半分给Redis。
Q&A:300万PV服务器设计常见疑问
300万PV能用云服务器吗?物理机和云主机哪个好?
可以用云服务器,5台云服务器(如ECS、轻量级)搭配SLB负载均衡,比自建机房更省心,物理机优势是硬件性能极致,适合对延迟和IO要求极高的场景,但多数业务云服务器完全胜任,而且扩容方便,不用提前采购硬件。
5台服务器怎么应对晚高峰和周末的流量突增?
晚高峰和周末流量通常是平日的1.5到2倍,建议提前在负载均衡层配置定时扩容策略:晚高峰前增加1台临时云主机,加入Nginx后端的upstream,高峰期过后自动释放,另外也可以在应用层做开关降级,比如关闭非核心的推荐算法,保证下单和支付链路稳定。
如果综合方案里要处理HTTPS证书,怎么分配?
证书统一放在Nginx层做SSL卸载,2台Nginx使用同一份证书,在keepalived里让它随VIP漂移,应用服务器全部走内网HTTP请求,减少握手开销,实测这样配置,全站HTTPS的性能损耗可以控制在5%以内。
首发原创文章,作者:王坚,如若转载,请注明出处:https://idctop.com/article/686445.html





