乐趣区

关于后端:Linux-TCPIP-协议栈调优

Linux TCP/IP 协定栈调优

鸟窝大佬
原文地址:https://colobu.com/2014/09/18…
https://colobu.com/2015/05/22…

最近忙于零碎性能的 DEBUG 和调优。有些性能瓶颈和 Linux 的 TCP/IP 的协定栈的设置无关,所以特地 google 了一下 Linux TCP/IP 的协定栈的参数意义和配置,记录一下。

如果想永恒的保留参数的设置,能够将参数退出到 /etc/sysctl.conf 中。如果想长期的更改参数的配置,能够批改 /proc/sys/net/ipv4/ 下的参数,机器重启后更改生效。

杨云 1028 整顿的参数的阐明:
参考文章:
linux 内核 TCP 相干参数解释

linux 内核参数优化

linux 内核参数正文

依据参数文件所处目录不同而进行分表整顿
下列文件所在目录:/proc/sys/net/ipv4/

所处目录 /proc/sys/net/ipv4/netfilter/
文件须要关上防火墙才会存在

两种批改内核参数办法

  1. 应用 echo value 形式间接追加到文件里如 echo “1” >/proc/sys/net/ipv4/tcp_syn_retries,但这种办法设施重启后又会复原为默认值
  2. 把参数增加到 /etc/sysctl.conf 中,而后执行 sysctl - p 使参数失效,永恒失效

内核生产环境优化参数
生产中罕用的参数:

net.ipv4.tcp_syn_retries = 1
net.ipv4.tcp_synack_retries = 1
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_probes = 3
net.ipv4.tcp_keepalive_intvl =15
net.ipv4.tcp_retries2 = 5
net.ipv4.tcp_fin_timeout = 2
net.ipv4.tcp_max_tw_buckets = 36000
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_max_orphans = 32768
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 16384
net.ipv4.tcp_wmem = 8192 131072 16777216
net.ipv4.tcp_rmem = 32768 131072 16777216
net.ipv4.tcp_mem = 786432 1048576 1572864
net.ipv4.ip_local_port_range = 1024 65000
net.core.netdev_max_backlog = 16384

不同的生产环境须要优化的参数根本差不多,只是值有相应的变动。具体优化值要参考利用场景,这儿所列只是罕用优化参数,是否适宜,可在下面查看该参数形容,了解后,再依据本人生产环境而设。

其它相干 linux 内核参数调整文章:
Linux 内核参数优化
http://flandycheng.blog.51cto…

优化 linux 的内核参数来进步服务器并发解决能力
http://www.ha97.com/4396.html

nginx 做 web 服务器 linux 内核参数优化
http://blog.csdn.net/force_ea…

sudops 网站提供的优化例子:

Linux 下 TCP/IP 及内核参数优化有多种形式,参数配置切当能够大大提高零碎的性能,也能够依据特定场景进行专门的优化,如 TIME_WAIT 过高,DDOS 攻打等等。
如下配置是写在 sysctl.conf 中,可应用 sysctl - p 失效,文中附带了一些默认值和中文解释(从网上收集和翻译而来),确有些辛苦,转载请保留链接,谢谢~。
相干参数仅供参考,具体数值还须要依据机器性能,利用场景等理论状况来做更轻微调整。

net.core.netdev_max_backlog = 400000
#该参数决定了,网络设备接管数据包的速率比内核解决这些包的速率快时,容许送到队列的数据包的最大数目。net.core.optmem_max = 10000000
#该参数指定了每个套接字所容许的最大缓冲区的大小
 
net.core.rmem_default = 10000000
#指定了接管套接字缓冲区大小的缺省值(以字节为单位)。net.core.rmem_max = 10000000
#指定了接管套接字缓冲区大小的最大值(以字节为单位)。net.core.somaxconn = 100000
#Linux kernel 参数,示意 socket 监听的 backlog(监听队列)下限
 
net.core.wmem_default = 11059200
#定义默认的发送窗口大小;对于更大的 BDP 来说,这个大小也应该更大。net.core.wmem_max = 11059200
#定义发送窗口的最大大小;对于更大的 BDP 来说,这个大小也应该更大。net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
#谨严模式 1 (举荐)
#涣散模式 0
 
net.ipv4.tcp_congestion_control = bic
#默认举荐设置是 htcp
 
net.ipv4.tcp_window_scaling = 0
#敞开 tcp_window_scaling
#启用 RFC 1323 定义的 window scaling;要反对超过 64KB 的窗口,必须启用该值。net.ipv4.tcp_ecn = 0
#把 TCP 的间接拥塞通告 (tcp_ecn) 关掉
 
net.ipv4.tcp_sack = 1
#敞开 tcp_sack
#启用有抉择的应答(Selective Acknowledgment),#这能够通过有选择地应答乱序接管到的报文来进步性能(这样能够让发送者只发送失落的报文段);#(对于广域网通信来说)这个选项应该启用,然而这会减少对 CPU 的占用。net.ipv4.tcp_max_tw_buckets = 10000
#示意零碎同时放弃 TIME_WAIT 套接字的最大数量
 
net.ipv4.tcp_max_syn_backlog = 8192
#示意 SYN 队列长度,默认 1024,改成 8192,能够包容更多期待连贯的网络连接数。net.ipv4.tcp_syncookies = 1
#示意开启 SYN Cookies。当呈现 SYN 期待队列溢出时,启用 cookies 来解决,可防备大量 SYN 攻打,默认为 0,示意敞开;net.ipv4.tcp_timestamps = 1
#开启 TCP 工夫戳
#以一种比重发超时更准确的办法(请参阅 RFC 1323)来启用对 RTT 的计算;为了实现更好的性能应该启用这个选项。net.ipv4.tcp_tw_reuse = 1
#示意开启重用。容许将 TIME-WAIT sockets 从新用于新的 TCP 连贯,默认为 0,示意敞开;net.ipv4.tcp_tw_recycle = 1
#示意开启 TCP 连贯中 TIME-WAIT sockets 的疾速回收,默认为 0,示意敞开。net.ipv4.tcp_fin_timeout = 10
#示意如果套接字由本端要求敞开,这个参数决定了它放弃在 FIN-WAIT- 2 状态的工夫。net.ipv4.tcp_keepalive_time = 1800
#示意当 keepalive 起用的时候,TCP 发送 keepalive 音讯的频度。缺省是 2 小时,改为 30 分钟。net.ipv4.tcp_keepalive_probes = 3
#如果对方不予应答,探测包的发送次数
 
net.ipv4.tcp_keepalive_intvl = 15
#keepalive 探测包的发送距离
 
net.ipv4.tcp_mem
#确定 TCP 栈应该如何反映内存应用;每个值的单位都是内存页(通常是 4KB)。#第一个值是内存应用的上限。#第二个值是内存压力模式开始对缓冲区应用利用压力的下限。#第三个值是内存下限。在这个档次上能够将报文抛弃,从而缩小对内存的应用。对于较大的 BDP 能够增大这些值(然而要记住,其单位是内存页,而不是字节)。net.ipv4.tcp_rmem
#与 tcp_wmem 相似,不过它示意的是为主动调优所应用的接收缓冲区的值。net.ipv4.tcp_wmem = 30000000 30000000 30000000
#为主动调优定义每个 socket 应用的内存。#第一个值是为 socket 的发送缓冲区调配的起码字节数。#第二个值是默认值(该值会被 wmem_default 笼罩),缓冲区在零碎负载不重的状况下能够增长到这个值。#第三个值是发送缓冲区空间的最大字节数(该值会被 wmem_max 笼罩)。net.ipv4.ip_local_port_range = 1024 65000
#示意用于向外连贯的端口范畴。缺省状况下很小:32768 到 61000,改为 1024 到 65000。net.ipv4.netfilter.ip_conntrack_max=204800
#设置系统对最大跟踪的 TCP 连接数的限度
 
net.ipv4.tcp_slow_start_after_idle = 0
#敞开 tcp 的连贯传输的慢启动,即先休止一段时间,再初始化拥塞窗口。net.ipv4.route.gc_timeout = 100
#路由缓存刷新频率,当一个路由失败后多长时间跳到另一个路由,默认是 300。net.ipv4.tcp_syn_retries = 1
#在内核放弃建设连贯之前发送 SYN 包的数量。net.ipv4.icmp_echo_ignore_broadcasts = 1
# 防止放大攻打
 
net.ipv4.icmp_ignore_bogus_error_responses = 1
# 开启歹意 icmp 谬误音讯爱护
 
net.inet.udp.checksum=1
#避免不正确的 udp 包的攻打
 
net.ipv4.conf.default.accept_source_route = 0
#是否承受含有源路由信息的 ip 包。参数值为布尔值,1 示意承受,0 示意不承受。#在充当网关的 linux 主机上缺省值为 1,在个别的 linux 主机上缺省值为 0。#从安全性角度登程,倡议你敞开该性能。

最后的幸福 ever 也提供了一些参数的阐明。

/proc/sys/net 目录

所有的 TCP/IP 参数都位于 /proc/sys/net 目录下(请留神,对 /proc/sys/net 目录下内容的批改都是长期的,任何批改在零碎重启后都会失落),例如上面这些重要的参数:

服务器的参数调优

个别会批改两个文件,/etc/sysctl.conf 和 /etc/security/limits.conf,用来配置 TCP/IP 参数和最大文件描述符。

TCP/IP 参数配置
批改文件 /etc/sysctl.conf, 配置网络参数。

net.ipv4.tcp_wmem = 4096 87380 4161536
net.ipv4.tcp_rmem = 4096 87380 4161536
net.ipv4.tcp_mem = 786432 2097152 3145728

数值依据需要进行调整。更多的参数能够看以前整顿的一篇文章: Linux TCP/IP 协定栈调优。
执行 /sbin/sysctl - p 即时失效。

最大文件描述符

Linux 内核自身有文件描述符最大值的限度,你能够依据须要更改:

  • 零碎最大关上文件描述符数:/proc/sys/fs/file-max

    • 临时性设置:echo 1000000 > /proc/sys/fs/file-max
    • 永恒设置:批改 /etc/sysctl.conf 文件,减少 fs.file-max = 1000000
  • 过程最大关上文件描述符数

    • 应用 ulimit - n 查看以后设置。应用 ulimit -n 1000000 进行临时性设置。
    • 要想永恒失效,你能够批改 /etc/security/limits.conf 文件,减少上面的行:
  • hard nofile 1000000
  • soft nofile 1000000
    root hard nofile 1000000
    root soft nofile 1000000

    还有一点要留神的就是 hard limit 不能大于 /proc/sys/fs/nr_open,因而有时你也须要批改 nr_open 的值。

执行 echo 2000000 > /proc/sys/fs/nr_open

查看以后零碎应用的关上文件描述符数,能够应用上面的命令:

[root@localhost ~]# cat /proc/sys/fs/file-nr             
1632    0       1513506

其中第一个数示意以后零碎已调配应用的关上文件描述符数,第二个数为调配后已开释的(目前已不再应用),第三个数等于 file-max。

总结一下:

  • 所有过程关上的文件描述符数不能超过 /proc/sys/fs/file-max
  • 单个过程关上的文件描述符数不能超过 user limit 中 nofile 的 soft limit
  • nofile 的 soft limit 不能超过其 hard limit
  • nofile 的 hard limit 不能超过 /proc/sys/fs/nr_open

利用运行时调优

Java 利用内存调优

服务器应用 12G 内存,吞吐率优先的垃圾回收器:

JAVA_OPTS="-Xms12G -Xmx12G -Xss1M -XX:+UseParallelGC"

V8 引擎

node --nouse-idle-notification --expose-gc --max-new-space-size=1024 --max-new-space-size=2048 --max-old-space-size=8192 ./webserver.js

OutOfMemory Killer

如果服务器自身内存不大,比方 8G,在不到 100 万连贯的状况下,你的服务器过程有可能呈现 ”Killed” 的问题。运行 dmesg 能够看到

Out of memory: Kill process 10375 (java) score 59 or sacrifice child

这是 Linux 的 OOM Killer 被动杀死的。开启 oom-killer 的话,在 /proc/pid 下对每个过程都会多出 3 个与 oom 打分调节相干的文件。长期对某个过程能够疏忽 oom-killer 能够应用上面的形式:

echo -17 > /proc/$(pidof java)/oom_adj

解决办法有多种,能够参看文章最初的参考文章, 最好是换一个内存更大的机器。

客户端的参数调优

在一台零碎上,连贯到一个近程服务时的本地端口是无限的。依据 TCP/IP 协定,因为端口是 16 位整数,也就只能是 0 到 65535,而 0 到 1023 是预留端口,所以能调配的端口只是 1024 到 65534,也就是 64511 个。也就是说,一台机器一个 IP 只能创立六万多个长连贯。
要想达到更多的客户端连贯,能够用更多的机器或者网卡,也能够应用虚构 IP 来实现, 比方上面的命令减少了 19 个 IP 地址,其中一个给服务器用,其它 18 个给 client, 这样
能够产生 18 * 60000 = 1080000 个连贯。

ifconfig eth0:0 192.168.77.10 netmask 255.255.255.0 up
ifconfig eth0:1 192.168.77.11 netmask 255.255.255.0 up
ifconfig eth0:2 192.168.77.12 netmask 255.255.255.0 up
ifconfig eth0:3 192.168.77.13 netmask 255.255.255.0 up
ifconfig eth0:4 192.168.77.14 netmask 255.255.255.0 up
ifconfig eth0:5 192.168.77.15 netmask 255.255.255.0 up
ifconfig eth0:6 192.168.77.16 netmask 255.255.255.0 up
ifconfig eth0:7 192.168.77.17 netmask 255.255.255.0 up
ifconfig eth0:8 192.168.77.18 netmask 255.255.255.0 up
ifconfig eth0:9 192.168.77.19 netmask 255.255.255.0 up
ifconfig eth0:10 192.168.77.20 netmask 255.255.255.0 up
ifconfig eth0:11 192.168.77.21 netmask 255.255.255.0 up
ifconfig eth0:12 192.168.77.22 netmask 255.255.255.0 up
ifconfig eth0:13 192.168.77.23 netmask 255.255.255.0 up
ifconfig eth0:14 192.168.77.24 netmask 255.255.255.0 up
ifconfig eth0:15 192.168.77.25 netmask 255.255.255.0 up
ifconfig eth0:16 192.168.77.26 netmask 255.255.255.0 up
ifconfig eth0:17 192.168.77.27 netmask 255.255.255.0 up
ifconfig eth0:18 192.168.77.28 netmask 255.255.255.0 up

批改 /etc/sysctl.conf 文件:

net.ipv4.ip_local_port_range = 1024 65535

执行 /sbin/sysctl - p 即时失效。

服务器测试

理论测试中我应用一台 AWS C3.4xlarge (16 cores, 32G memory)作为应用服务器,两台 AWS C3.2xlarge (8 cores, 16G memory)服务器作为客户端。
这两台机器作为测试客户端入不敷出,每台客户端机器创立了十个内网虚构 IP, 每个 IP 创立 60000 个 websocket 连贯。

客户端配置如下:
/etc/sysctl.conf 配置

fs.file-max = 2000000
fs.nr_open = 2000000
net.ipv4.ip_local_port_range = 1024 65535

/etc/security/limits.conf 配置

* soft    nofile      2000000
* hard    nofile      2000000
* soft nproc 2000000
* hard nproc 2000000

服务端配置如下:
/etc/sysctl.conf 配置

fs.file-max = 2000000
fs.nr_open = 2000000
net.ipv4.ip_local_port_range = 1024 65535

/etc/security/limits.conf 配置

* soft    nofile      2000000
* hard    nofile      2000000
* soft nproc 2000000
* hard nproc 2000000

原文地址:https://colobu.com/2014/09/18…
https://colobu.com/2015/05/22…

关注 vx golang 技术实验室
获取更多好文

本文由 mdnice 多平台公布

退出移动版