多接口点对点连接路由表配置及套接字绑定流量异常排查
听起来你遇到的问题很典型——应用层已经把套接字分别绑定到ens0和ens1接口,但S2上所有跨服务器流量都走了ens0,而S1正常。结合你的排查方向(路由表),大概率是S2的路由配置存在优先级覆盖或缺失,导致系统没有为ens1的流量选择正确的接口。下面是一步步的排查和解决思路:
一、先确认路由表的基础配置
首先用ip route show查看S2的路由表,重点看针对两台服务器点对点网段的路由条目:
- 假设你的ens0网段是
192.168.0.0/24(S1 ens0: 192.168.0.1,S2 ens0: 192.168.0.2),ens1网段是192.168.1.0/24(S1 ens1:192.168.1.1,S2 ens1:192.168.1.2) - 正常情况下,S2的路由表应该有两条链路范围的路由:
192.168.0.0/24 dev ens0 scope link 192.168.1.0/24 dev ens1 scope link - 如果ens1对应的路由条目缺失,或者存在更笼统的路由(比如默认路由
default via x.x.x.x dev ens0),系统会优先把所有跨服务器流量丢给ens0。
修复方法:如果缺失ens1的路由,手动添加:
ip route add 192.168.1.0/24 dev ens1 scope link
(替换成你实际的ens1网段)
二、检查策略路由(ip rule)是否正确
有时候系统会基于源IP的路由规则来选择接口,如果S2没有配置针对ens1源IP的规则,即使绑定了套接字,流量还是会走主路由表的默认路径。
用ip rule show查看规则列表,正常应该有两条针对不同源IP的规则:
32764: from 192.168.1.2 lookup ens1-table 32765: from 192.168.0.2 lookup ens0-table
如果没有这类规则,说明所有流量都走主路由表,而主路由表中可能ens0的路由优先级更高。
修复方法:配置策略路由分离两个接口的流量:
- 先在路由表配置文件中添加自定义表:
echo "10 ens0-table" >> /etc/iproute2/rt_tables echo "20 ens1-table" >> /etc/iproute2/rt_tables - 给每个自定义表添加对应网段的路由:
ip route add 192.168.0.0/24 dev ens0 table ens0-table ip route add 192.168.1.0/24 dev ens1 table ens1-table - 添加源IP匹配规则:
ip rule add from 192.168.0.2 table ens0-table ip rule add from 192.168.1.2 table ens1-table
这样就能保证:从S2 ens0 IP发出的流量,强制走ens0接口;从ens1 IP发出的流量,强制走ens1接口。
三、验证套接字绑定是否真的生效
虽然S1正常,但还是可以快速验证S2上的套接字绑定状态,排除代码层面的小疏漏:
用ss -tulpn | grep <你的进程名称>查看进程的套接字信息,确认绑定的IP是否是ens1的实际IP(而不是0.0.0.0或者错误的IP)。
四、用tcpdump抓包确认流量走向
如果上面的配置都没问题,用抓包工具验证流量实际走了哪个接口:
- 在S2上执行
tcpdump -i ens0 host 192.168.1.1(监听ens0上到S1 ens1的流量) - 同时执行
tcpdump -i ens1 host 192.168.1.1(监听ens1上的对应流量) - 然后触发绑定到ens1的套接字发送数据,看哪个接口有数据包。如果ens0有流量,说明路由还是有问题;如果ens1有流量,那可能是你之前的测试判断有误。
总结
因为S1的配置能正常工作,说明你的C++套接字绑定逻辑是对的,问题肯定出在S2的网络路由配置上。优先排查路由表的条目完整性,再检查策略路由规则,最后用抓包工具验证,应该能快速定位并解决问题。
内容的提问来源于stack exchange,提问作者floatJoe

