当前位置: 首页 > 科技观察

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

时间:2023-03-20 14:56:37 科技观察

作者个人研发在高并发场景下提供了一个简单、稳定、可扩展的延迟消息队列框架,具有精准的定时任务和延迟队列处理功能。开源半年多以来,已成功为十几家中小企业提供精准定时调度解决方案,经受住了生产环境的考验。为了造福更多的童鞋,这里给出开源框架的地址:https://github.com/sunshinelyz/mykit-delay之前写的。最近有朋友在群里提问:linux系统中tcp_nodelay参数怎么设置?也有朋友问我。今天,我们就基于这个问题来谈谈如何在高并发场景下优化服务器性能。其实在操作系统层面并没有配置tcp_nodelay参数,而是在TCPsocket中加入tcp_nodelay参数,关闭粘包算法,使数据包可以立即投递。tcp_nodelay参数主要针对TCP套接字。对于服务器硬件来说,如果我们想让它支持百万级甚至千万级并发,应该怎么优化呢?文章已收录于:https://github.com/sunshinelyz/technology-binghehttps://gitee.com/binghe001/technology-binghe操作系统这里我使用的操作系统是CentOS8,我们可以进入以下命令查看操作系统的版本。CentOSLinuxrelease8.0.1905(Core)针对高并发场景,我们主要优化了操作系统的网络性能。在操作系统中,有很多与网络协议相关的参数。我们对服务器网络性能的优化主要是优化这些系统参数。调优,以达到提高我们应用访问性能的目的。系统参数在CentOS操作系统中,我们可以通过以下命令查看所有系统参数。/sbin/sysctl-a的部分输出如下所示。这里的参数太多了,大概一千个吧。在高并发场景下,我们不可能调优操作系统的所有参数。我们更关心与网络相关的参数。如果我们要获取网络相关的参数,首先需要获取操作系统参数的类型。下面的命令可以获取操作系统参数的类型。/sbin/sysctl-a|awk-F"."'{print$1}'|sort-k1|uniq命令输出如下。abicryptodebugdevfskernelnetsunrpcuservm中的net类型是我们要注意的与网络相关的操作系统参数。我们可以得到网络类型下的子类型如下图。/sbin/sysctl-a|grep"^net."|awk-F"[.|]"'{print$2}'|sort-k1|uniq结果信息输出如下。bridgecoreipv4ipv6netfilternf_conntrack_maxunix在Linux操作系统中,可以在/etc/sysctl.conf文件中修改这些网络相关的参数。如果这些参数在/etc/sysctl.conf文件中不存在,我们可以在/etc/sysctl.conf文件中添加这些参数。在net类型的子类型中,我们需要关注的子类型有:core和ipv4。优化socket缓冲区如果服务器的网络socket缓冲区太小,会导致应用程序多次读写来处理数据,这将极大地影响我们程序的性能。如果网络套接字缓冲区设置得足够大,我们程序的性能可以得到一定程度的提升。我们可以在服务器的命令行中输入以下命令来获取服务器的套接字缓冲区的信息。/sbin/sysctl-a|grep"^net."|grep"[r|w|_]mem[_|]"输出结果信息如下。net.core.rmem_default=212992net.core.rmem_max=212992net.core.wmem_default=212992net.core.wmem_max=212992net.ipv4.tcp_mem=435455806287090net.ipv4.tcp_rmem=4096873806291456net.ipv4.tcp_wmem=4096163844194304net.ipv4.udp_mem=87093116125174186net.ipv4.udp_rmem_min=4096net.ipv4.udp_wmem_min=4096其中,带max、default、min的关键字分别表示:最大值、默认值、最小值;mem、rmem和wmem的关键字是:总内存、接收缓冲区内存、发送缓冲区内存。这里要注意,rmem和wmem关键字的单位是“字节”,而mem关键字的单位是“页”。“页”是操作系统管理的最小内存单元。在Linux系统中,一个页面的默认大小是4KB。大文件频繁收发如何优化如果在高并发场景下,需要频繁收发大文件,那么如何优化服务器的性能呢?这里,我们可以修改的系统参数如下。net.core.rmem_defaultnet.core.rmem_maxnet.core.wmem_defaultnet.core.wmem_maxnet.ipv4.tcp_memnet.ipv4.tcp_rmemnet.ipv4.tcp_wmem这里,我们假设系统最多可以分配2GB内存给TCP,并且最小值为256MB,压力值为1.5GB。按照一页为4KB计算,tcp_mem的最小值、压力值、最大值分别为65536、393216、524288,单位为“页”。假设每个文件数据包平均为512KB,每个socket读写缓冲区至少可以容纳2个数据包,默认4个数据包,最多10个数据包,那么我们可以计算出最小值、默认值和最大值tcp_rmem和tcp_wmem的大小分别为1048576、2097152和5242880,单位是“字节”。而rmem_default和wmem_default为2097152,rmem_max和wmem_max为5242880。注:后面会详细介绍这些值是如何计算的~~这里需要注意的是:buffer超过65535,net.ipv4.tcp_window_scalingparameter需要设置为1。经过上面的分析,我们最终得到系统调优参数如下。net.core.rmem_default=2097152net.core.rmem_max=5242880net.core.wmem_default=2097152net.core.wmem_max=5242880net.ipv4.tcp_mem=65536393216524288net.ipv4.tcp_rmem=104857620971525242880net.ipv4.tcp_wmem=104857620971525242880优化TCP连接对计算机网络有想必知道的朋友都知道,TCP连接需要经过“三次握手”和“四次挥手”,以及慢启动、滑动窗口、粘包算法等一系列可靠传输的技术支持.虽然,这些可以保证TCP协议的可靠性,但是有时候这会影响我们程序的性能。那么,我们如何在高并发场景下优化TCP连接呢?(1)关闭粘包算法如果用户对请求的耗时比较敏感,我们需要在T??CPsocket中添加tcp_nodelay参数来关闭粘包算法,这样数据包就可以立即发送出去。此时,我们也可以将net.ipv4.tcp_syncookies的参数值设置为1。(2)避免连接资源的频繁创建和回收网络连接的创建和回收是非常消耗性能的。我们可以通过关闭空闲连接和重用分配的连接资源来优化服务器性能。我们对分配的连接资源的复用并不陌生,比如:线程池、数据库连接池就是线程和数据库连接的复用。我们可以通过以下参数关闭服务器的空闲连接,重新使用分配的连接资源。net.ipv4.tcp_tw_reuse=1net.ipv4.tcp_tw_recycle=1net.ipv4.tcp_fin_timeout=30net.ipv4.tcp_keepalive_time=1800(3)避免重复发送数据包TCP支持超时重传机制。如果发送方已经将数据包发送给接收方,但是发送方还没有收到反馈,此时如果达到设定的时间间隔,就会触发TCP超时重传机制。为了避免再次发送成功发送的数据包,我们需要将服务器的net.ipv4.tcp_sack参数设置为1。(4)增加服务器文件描述符的个数在Linux操作系统中,一个网络连接也占用一个文件描述符,连接越多,占用的文件描述符越多。如果文件描述符设置的比较小,也会影响我们服务器的性能。此时,我们需要增加服务器文件描述符的数量。例如:fs.file-max=10240000,表示服务器最多可以打开10240000个文件。本文转载自微信公众号“冰河科技”,可通过以下二维码关注。转载本文请联系冰川科技公众号。