秋来冬风的博客

如何做到高可用高吞吐的web服务 | 硬件配置+TCP/IP协议栈调优实践

目录

背景

本文分享笔者一些搭建web服务时,做到高可用且高吞吐的经验。

硬件角度

服务器

通常,web服务被部署在云服务器上,而且比较可能是在成本较低的vps(虚拟专用服务器)。

注意仔细查看可接受使用政策,避免使用限制严格的vps。

如有长时间高占用CPU需求,不要吝啬这方面的支出。

选择好的服务器至关重要,否则高可用且高吞吐的web服务几乎无从谈起。

CPU

尽量多核,以达到更高的吞吐量。

内存

高内存有助于接收更多的网络请求,尽量确保物理内存充足。

注意虽然在低内存时,使用适量虚拟内存有助于高可用,但无论如何,也不如增加物理内存更好。

磁盘

尽量减少对磁盘的操作。

比如对于静态文件服务器,可以把对外提供的文件,缓存到内存,加快速度。

网络

注意网络带宽要够快,如果像比如只有1Mbps这样,实现高吞吐不现实。

还要注意距离和网络路由,例如在中国访问美国的web服务,受限于光速的物理限制,理论上RTT(往返时延)最短也要100多ms,若路由未优化,实际 RTT 可能远高于理论值。

温度

注意机器的温度,客户机的也要注意。

如果在机体发烫时测试,可能测试得出较低的吞吐量。

TCP/IP四层模型角度

应用层

使用高效的编程语言

可以使用Go,Rust等容易写出高吞吐服务器的高效编程语言。


使用http2

http2对比http1.1在服务器资源消耗方面有巨大优势,笔者实测,原本最高4000+rps的web服务,使用http2后,最高可达7000+rps,而且内存使用更少。


使用大日志写缓冲区

磁盘读写很影响吞吐量,使用大缓冲区,可尽量降低写日志等造成的性能下降。


使用浏览器缓存

用好HTTP响应头Cache-Control,减少重复请求。


使用cdn

通过减低源服务器负载,增强可用性。通过从距离用户近的地方响应静态文件,提高吞吐量。


使用多台服务器

单台服务器易因单点故障(如网络中断、程序崩溃、硬件故障)失效,通过使用多台服务器来确保高可用。


配置自动重启

服务器进程可能因各种原因崩溃退出,可配置自动重启,保证高可用。


调整GC

对于带自动垃圾回收的编程语言,根据情况调整GC,兼顾高可用和高吞吐。


限流

基于IP限流,令牌桶,滑动窗口等,根据应用场景选择,避免因为处理恶意请求,影响可用性。


不要使用TLS连接数据库

使用TLS连接数据库开销很大,而且TLS的配置很复杂,如有需要,可以使用wireguard组网,然后在内网直接tcp连接数据库。

传输层

按需启用SYN Cookies

配置net.ipv4.tcp_syncookies = 1,可确保在遭到SYN Flood攻击时,即使半连接队满,仍然可以建立新连接处理正常请求。


降低SYN-ACK重传次数

降低net.ipv4.tcp_synack_retries,默认为5,可降低为2或3,减少无效等待,加速资源回收,并防御SYN Flood,与 tcp_syncookies 配合,攻击者创建的半连接会被更快回收。


调大连接队列

调大net.ipv4.tcp_max_syn_backlog(半连接队列)和net.core.somaxconn(全连接队列),降低服务器在高并发时连接建立失败的几率。


调大发送/接收缓冲区

调大net.ipv4.tcp_rmem、net.ipv4.tcp_wmem、net.core.rmem_max、net.core.wmem_max,提升高带宽、高延迟网络环境下的吞吐量。


启用 TCP 窗口缩放

配置net.ipv4.tcp_window_scaling = 1,支持大带宽延迟积。


加快长连接的存活检测

配置net.ipv4.tcp_keepalive_time = 300、net.ipv4.tcp_keepalive_intvl = 15、net.ipv4.tcp_keepalive_probes = 2或视情况调低,更快清理僵尸连接,释放文件描述符和内存。


启用tcp快速打开

配置net.ipv4.tcp_fastopen = 3,加快TCP重新连接建立。需确保应用(如 Nginx、Go 服务)也支持 TFO


空闲后不重新进入慢启动

配置net.ipv4.tcp_slow_start_after_idle = 0,适合长连接的场景(如 HTTP/2 服务),可减少拥塞窗口反复重置的性能损耗。


不使用旧的拥塞控制相关统计信息

配置net.ipv4.tcp_no_metrics_save = 1,适应多样化的客户端网络环境,减少因历史参数不匹配导致的服务质量下降。


网络层

增加每次软中断处理的数据包数量

增大net.core.netdev_budget,让每次软中断能处理更多数据包,增加吞吐量。


增加网卡接收队列的最大长度

增大netdev_max_backlog,增强处理突发流量的能力,但不是越大越好,否则可能破坏拥塞控制,导致高延迟和低网速。

一个奇怪的现象,笔者实测,不管net.core.netdev_budget是多少,netdev_max_backlog为net.core.netdev_budget2到3倍时,网速最快,吞吐量最高。(不一定在其他机器一样


增加每次软中断处理的最大时间

增大net.core.netdev_budget_usecs,让每次软中断能处理更多数据包,增加吞吐量。


使用优化路由

使用优化路由(如选择 CN2、GIA、BGP 多线、智能调度等优质线路)能降低延迟和丢包率,增加带宽延迟积,保障高吞吐和高可用。


网络接口层

关闭GRO(通用接收卸载)、GSO(通用分段卸载)、TSO(TCP 分段卸载)

在http2服务器,关掉这些网卡特性可能让吞吐量更高。


Tags: