问候朋友!
在前两篇文章(
一 ,
二 )中,我们陷入了技术选择之间的复杂性,并在
Ostrovok.ru中为我们的解决方案寻找了最佳设置。 今天我们要提出什么主题?
每个服务应在某个服务器上工作,并通过操作系统的工具与硬件进行通信。 这些工具很多,还有它们的设置。 在大多数情况下,它们的默认设置将绰绰有余。 在本文中,我想谈谈标准设置还不够的情况,而我必须更深入地了解操作系统-在我们的
Linux中 。

我们明智地使用内核
在
上一篇文章中,我讨论了
Haproxy中的
cpu-map 选项 。 使用它,我们将Haproxy进程绑定到双处理器服务器上一个内核的线程。 我们为网卡中断处理提供了第二个核心。
下面是一个屏幕,您可以在其中看到类似的分隔。 左侧是Haproxy在
user space
中占用的内核,而右侧是通过处理
kernel space
中断来
kernel space
。

使用此功能可以自动将中断绑定到网卡
Internet上有许多合适的简单和更复杂的脚本可以完成相同的工作,但是此脚本足以满足我们的需求。
在Haproxy,我们从第一个内核开始将进程链接到内核。 相同的脚本从最后一个开始绑定中断。 因此,我们可以将服务器处理器分为两个阵营。
为了更深入地了解中断和网络,我强烈建议您阅读
本文 。
我们揭示网络设备的功能
碰巧一次有很多帧可以在网络上飞过,并且即使有机会这样做,卡队列也可能尚未准备好迎接这种来宾。
让我们谈谈网卡缓冲区。 大多数情况下,默认值不会使用整个可用缓冲区。 您可以使用功能强大的ethtool实用程序查看当前设置。
命令用法示例:
> ethtool -g eno1 Ring parameters for eno1: Pre-set maximums: RX: 4096 RX Mini: 0 RX Jumbo: 0 TX: 4096 Current hardware settings: RX: 256 RX Mini: 0 RX Jumbo: 0 TX: 256
现在,让我们从生活中汲取一切:
> ethtool -G eno1 rx 4096 tx 4096 > ethtool -g eno1 Ring parameters for eno1: Pre-set maximums: RX: 4096 RX Mini: 0 RX Jumbo: 0 TX: 4096 Current hardware settings: RX: 4096 RX Mini: 0 RX Jumbo: 0 TX: 4096
现在,您可以确定该卡没有受到约束并且可以最大程度地发挥其功能。
最小的sysctl设置以获得最大的收益
Sysctl提供了您可以想象的所有颜色和大小的多种选择。 而且,通常,Internet上有关优化问题的文章涵盖了这些参数中相当令人印象深刻的部分。 在我们的案例中,我将只考虑那些对改变确实有用的东西。
net.core.netdev_max_backlog-从网卡获取帧的队列,然后由内核处理。 凭借快速的接口和大量的流量,它可以快速填满。
默认值 :1000
我们可以通过查看/ proc / net / softnet_stat文件中的第二列来观察该队列的剩余部分。
awk '{print $2}' /proc/net/softnet_stat
该文件本身描述了系统中每个CPU的每行
netif_rx_stats的结构。
具体而言,第二列描述处于丢弃状态的数据包数量。 如果第二列中的值随时间增长,那么可能值得增加
net.core.netdev_max_backlog
的值或使CPU更快。
net.core.rmem_default /
net.core.rmem_max &&
net.core.wmem_default /
net.core.wmem_max-这些参数指示套接字读取和写入缓冲区的默认值/最大值。 可以在创建套接字时在应用程序级别更改
默认值(顺便说一下,Haproxy具有执行此操作的
参数 )。 我们遇到过这样的情况:内核抛出的数据包超过了Haproxy设法耙开的数据包,然后问题开始了。 因此,事情很重要。
net.ipv4.tcp_max_syn_backlog-负责限制尚未建立的新连接的接收
SYN
数据包。 如果有大量新连接(例如,来自
Connection: close
的许多HTTP请求),则提高此值很有意义,以免浪费时间发送转发的数据包。
net.core.somaxconn-在这里,我们讨论的是已建立的连接,但尚未由应用程序处理。 如果服务器是单线程服务器,并且有两个请求,则第一个请求将由
accept()
函数处理,第二个请求将挂在
backlog
,后者的大小负责此参数。
nf_conntrack_max可能是所有参数中最著名的。 我认为几乎所有处理iptables的人都知道这一点。 当然,理想情况下,如果不需要使用伪装的iptables,则可以卸载conntrack模块,而不用考虑它。 就我而言,使用的
是Docker ,因此您不会上传任何特殊内容。
监控方式 很明显,不是很明显
为了避免盲目搜索“代理速度变慢”的原因,建立一些图表并将其与触发器重叠将非常有用。
nf_conntrack_count是最明显的指标。 在它上面,您可以监视
conntrack表中现在有多少个连接。 当表溢出时,新连接的路径将关闭。
当前值可以在这里找到:
cat /proc/sys/net/netfilter/nf_conntrack_count
重传的TCP分段 -
分段传输的次数。 该指标非常庞大,因为它可以讨论不同级别的问题。 传输量的增加可能表明存在网络问题,需要优化系统设置,甚至可能表明最终软件(例如Haproxy)没有发挥作用。 尽管如此,此值的异常增长可能会成为进行诉讼的原因。

在我们国家,价值增加通常表示供应商之一存在问题,尽管服务器和网络的性能均存在问题。
验证示例:
netstat -s|grep 'segments retransmited'
套接字Recv-Q-记住,我们谈论的时刻是应用程序可能没有足够的时间来处理请求,然后
socket backlog
会增加吗? 该指标的增长清楚地表明应用程序有问题,无法解决。
当Haproxy中的maxconn参数具有默认值(2000),并且它根本不接受新连接时,我在具有该度量的图形中看到了山脉。
再举一个例子:
ss -lntp|awk '/LISTEN/ {print $2}'

具有按TCP连接状态进行细分的图不会是多余的:

并分别渲染
time-wait/established
,因为 通常,它们的值与其余值有很大不同:

除了这些指标以外,还有许多其他指标,但更为明显-例如,网络接口或CPU上的负载。 他们的选择将更多地取决于您的工作负载。
而不是结论
通常,仅此而已-我试图描述设置http反向代理时必须面对的关键点。 看起来任务并不困难,但是随着负载的增加,总是在错误的时间出现的陷阱也增加了。 我希望本文能帮助您避免遇到我遇到的困难。
一切和平