我的问题:我有一个进程每秒创建超过 10k 个到同一目标 IP 和端口的 TCP 连接。短暂一段时间后,无法再创建新连接,因为没有更多可用的源端口。
我已经尝试通过设置来缓解这个问题net.ipv4.ip_local_port_range
,net.ipv4.tcp_fin_timeout
但没有解决问题。
现在我的想法是:如果我可以告诉内核循环源 IP 地址,那么我就可以轻松地向我的一个接口添加更多 IP,从而具有更高的传出连接限制。
我尝试通过相同的接口添加到相同目的地的多个路由,但指定不同的源 IP:
ip route add default via 10.1.1.1 dev eth0 src 10.1.1.10
ip route add default via 10.1.1.1 dev eth0 src 10.1.1.11
但我明白RTNETLINK answers: File exists
。
我这样做对吗?在这些情况下,添加另一个源 IP 是“可行的方法”吗?
有没有办法通过内核循环/负载平衡源 IP 的使用?
我的希望是,如果我设法将两个具有相同权重但不同 src 地址的路由放置到同一个网络,内核就会循环执行。
(背景:我在该机器上运行 HAproxy,并且必须对超过 10k 个连接向单个后端服务器进行负载平衡)
答案1
不能轻易通过内核实现,不行。
我在该机器上运行 HAproxy,并且必须将超过 10k 个连接负载平衡到单个后端服务器
您可以告诉 haproxy 使用特定的源 IP 地址与服务器建立传出连接,例如:
server app1_s1 10.0.1.1:80 source 10.1.1.10
server app1_s2 10.0.1.1:80 source 10.1.1.11
server app2_s1 10.0.1.2:80 source 10.1.1.10
server app2_s2 10.0.1.2:80 source 10.1.1.11
答案2
你还是不知道。net.ipv4.ip_local_port_range
即使使用默认设置也应该足够了。所以我敢打赌,要么你的连接数远远超过 10K,要么你的诊断是错误的。
看到,“ipsrc:端口 ipdst:端口”四元组在整个机器 IP 堆栈中都是唯一的,并且由于网络堆栈中的端口总数为 65536,因此理论上您可以拥有 65536 个连接。好吧,我们减去了 WKS 块 (-1024),但这仍然为您提供了 55536 个带有篡改的连接net.ipv4.ip_local_port_range
。仅当您需要更多 IP/接口时,才需要使用其他 IP/接口。
通常,这个问题可以通过添加更多客户端 IP 来解决和/或如果目标也在你的堆栈内,则使用服务器IP,如果不在你的堆栈内,则使用多个路由表。