高并发场景下如何优化服务器的性能?

写在前面

最近,有小伙伴在群里提问:Linux系统怎么设置tcp_nodelay参数?也有小伙伴说问我。那今天,我们就来根据这个问题来聊聊在高并发场景下如何优化服务器的性能这个话题。

image

其实,tcp_nodelay参数并不是在操作系统级别进行配置的,而是在TCP套接字上添加tcp_nodelay参数来关闭粘包算法,以便使数据包能够立即投递出去。tcp_nodelay参数主要是对TCP套接字来说的,那对于服务器硬件,如果要使其能够支撑上百万甚至上千万的并发,我们该如何对其进行优化呢?

文章已收录到:

https://github.com/sunshinelyz/technology-binghe

https://gitee.com/binghe001/technology-binghe

操作系统

这里,我使用的操作系统为CentOS 8,我们可以输入如下命令来查看操作系统的版本。

CentOS Linux release 8.0.1905 (Core) 

对于高并发的场景,我们主要还是优化操作系统的网络性能,而操作系统中,有很多关于网络协议的参数,我们对于服务器网络性能的优化,主要是对这些系统参数进行调优,以达到提升我们应用访问性能的目的。

系统参数

在CentOS 操作系统中,我们可以通过如下命令来查看所有的系统参数。

/sbin/sysctl -a

部分输出结果如下所示。

image

这里的参数太多了,大概有一千多个,在高并发场景下,我们不可能对操作系统的所有参数进行调优。我们更多的是关注与网络相关的参数。如果想获得与网络相关的参数,那么,我们首先需要获取操作系统参数的类型,如下命令可以获取操作系统参数的类型。

/sbin/sysctl -a|awk -F "." '{print $1}'|sort -k1|uniq

运行命令输出的结果信息如下所示。

abi
crypto
debug
dev
fs
kernel
net
sunrpc
user
vm
image

其中的net类型就是我们要关注的与网络相关的操作系统参数。我们可以获取net类型下的子类型,如下所示。

/sbin/sysctl -a|grep "^net."|awk -F "[.| ]" '{print $2}'|sort -k1|uniq

输出的结果信息如下所示。

bridge
core
ipv4
ipv6
netfilter
nf_conntrack_max
unix
image

在Linux操作系统中,这些与网络相关的参数都可以在/etc/sysctl.conf 文件里修改,如果/etc/sysctl.conf 文件中不存在这些参数,我们可以自行在/etc/sysctl.conf 文件中添加这些参数。

在net类型的子类型中,我们需要重点关注的子类型有:core和ipv4。

优化套接字缓冲区

如果服务器的网络套接字缓冲区太小,就会导致应用程序读写多次才能将数据处理完,这会大大影响我们程序的性能。如果网络套接字缓冲区设置的足够大,从一定程度上能够提升我们程序的性能。

我们可以在服务器的命令行输入如下命令,来获取有关服务器套接字缓冲区的信息。

/sbin/sysctl -a|grep "^net."|grep "[r|w|_]mem[_| ]"

输出的结果信息如下所示。

net.core.rmem_default = 212992
net.core.rmem_max = 212992
net.core.wmem_default = 212992
net.core.wmem_max = 212992
net.ipv4.tcp_mem = 43545        58062   87090
net.ipv4.tcp_rmem = 4096        87380   6291456
net.ipv4.tcp_wmem = 4096        16384   4194304
net.ipv4.udp_mem = 87093        116125  174186
net.ipv4.udp_rmem_min = 4096
net.ipv4.udp_wmem_min = 4096
image

其中,带有max、default、min关键字的为分别代表:最大值、默认值和最小值;带有mem、rmem、wmem关键字的分别为:总内存、接收缓冲区内存、发送缓冲区内存。

这里需要注意的是:带有rmem 和 wmem关键字的单位都是“字节”,而带有mem关键字的单位是“页”。“页”是操作系统管理内存的最小单位,在 Linux 系统里,默认一页是 4KB 大小。

如何优化频繁收发大文件

如果在高并发场景下,需要频繁的收发大文件,我们该如何优化服务器的性能呢?

这里,我们可以修改的系统参数如下所示。

net.core.rmem_default
net.core.rmem_max
net.core.wmem_default
net.core.wmem_max
net.ipv4.tcp_mem
net.ipv4.tcp_rmem
net.ipv4.tcp_wmem

这里,我们做个假设,假设系统最大可以给TCP分配 2GB 内存,最小值为 256MB,压力值为 1.5GB。按照一页为 4KB 来计算, tcp_mem 的最小值、压力值、最大值分别是 65536、393216、524288,单位是“页” 。

假如平均每个文件数据包为 512KB,每个套接字读写缓冲区最小可以各容纳 2 个数据包,默认可以各容纳 4 个数据包,最大可以各容纳 10 个数据包,那我们可以算出 tcp_rmem 和 tcp_wmem 的最小值、默认值、最大值分别是 1048576、2097152、5242880,单位是“字节”。而 rmem_default 和 wmem_default 是 2097152,rmem_max 和 wmem_max 是 5242880。

注:后面详细介绍这些数值是如何计算的~~

这里,还需要注意的是:缓冲区超过了 65535,还需要将 net.ipv4.tcp_window_scaling 参数设置为 1。

经过上面的分析后,我们最终得出的系统调优参数如下所示。

net.core.rmem_default = 2097152
net.core.rmem_max = 5242880
net.core.wmem_default = 2097152
net.core.wmem_max = 5242880
net.ipv4.tcp_mem = 65536  393216  524288
net.ipv4.tcp_rmem = 1048576  2097152  5242880
net.ipv4.tcp_wmem = 1048576  2097152  5242880

优化TCP连接

对计算机网络有一定了解的小伙伴都知道,TCP的连接需要经过“三次握手”和“四次挥手”的,还要经过慢启动、滑动窗口、粘包算法等支持可靠性传输的一系列技术支持。虽然,这些能够保证TCP协议的可靠性,但有时这会影响我们程序的性能。

那么,在高并发场景下,我们该如何优化TCP连接呢?

(1)关闭粘包算法

如果用户对于请求的耗时很敏感,我们就需要在TCP套接字上添加tcp_nodelay参数来关闭粘包算法,以便数据包能够立刻发送出去。此时,我们也可以设置net.ipv4.tcp_syncookies的参数值为1。

(2)避免频繁的创建和回收连接资源

网络连接的创建和回收是非常消耗性能的,我们可以通过关闭空闲的连接、重复利用已经分配的连接资源来优化服务器的性能。重复利用已经分配的连接资源大家其实并不陌生,像:线程池、数据库连接池就是复用了线程和数据库连接。

我们可以通过如下参数来关闭服务器的空闲连接和复用已分配的连接资源。

net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_keepalive_time=1800

(3)避免重复发送数据包

TCP支持超时重传机制。如果发送方将数据包已经发送给接收方,但发送方并未收到反馈,此时,如果达到设置的时间间隔,就会触发TCP的超时重传机制。为了避免发送成功的数据包再次发送,我们需要将服务器的net.ipv4.tcp_sack参数设置为1。

(4)增大服务器文件描述符数量

在Linux操作系统中,一个网络连接也会占用一个文件描述符,连接越多,占用的文件描述符也就越多。如果文件描述符设置的比较小,也会影响我们服务器的性能。此时,我们就需要增大服务器文件描述符的数量。

例如:fs.file-max = 10240000,表示服务器最多可以打开10240000个文件。

好了,本文结合群内读者的提问进行的一些总结,希望能够给小伙伴们带来实质性的帮助。今天就到这儿吧,我是冰河,大家有啥问题可以在下方留言,也可以加我微信:sun_shine_lyz,一起交流技术,一起进阶,一起牛逼~~

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,377评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,390评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,967评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,344评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,441评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,492评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,497评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,274评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,732评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,008评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,184评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,837评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,520评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,156评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,407评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,056评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,074评论 2 352

推荐阅读更多精彩内容