现象:
监控系统中需要采用轮寻udp包的方式,对系统配置内的节点发送UDP包,并根据返回的UDP报文确定目标节点的状态。测试环境中未发现异常,但在实际工程应用时发现使用节点判断功能后,交换机出现故障报警,tcpdump观察发现大量的ARP报文,最终导致网络处理速度较慢的现地设备出现网络异常。
UDP与ARP的关系:
在《TCP/IP详解 卷2:实现》21章ARP:地址解析协议中,找到相关的描述:
当某主机要向以太网中另一台主机发送IP数据时,它首先根据目的主机的IP地址在ARP高速缓存中查询相应的以太网地址,ARP高速缓存是主机维护的一个IP地址到相应以太网地址的映射表。如果查到匹配的节点,则相应的以太网地址被写入以太帧首部,数据报被加入输出队列等候发送。如果查询失败,ARP会先保留待发送的IP数据报,然后广播一个询问目的主机硬件地址的ARP报文,等收到回答后再将IP数据报发送出去。
结合工程实际情况和上述描述,可以确认:
1. ARP数据包,是因为UDP消息的目标节点在本机ARP表中不存在而产生的;
2. UDP为了判断目标节点情况按照200ms的间隔进行发送,但由于存在大量不在线的目标节点,导致ARP包大量产生。
在该书的561页,描述了防止ARP洪泛的机制:
RFC1122要求ARP避免在收到ARP回答前以过高的速度对一个以太网地址重发ARP请求。Net/3采用以下方法来避免ARP洪泛:
- Net/3不在同一秒内发送多个对应统一目标地址的ARP请求;
- 如果在连续5个ARP请求后还没有收到回答,路由节点的RTF_REJECT标志置为1,时间设为往后的20秒。这会在20秒内拒绝发往该目标地址的IP数据报。
- 20秒后,arpresolve会继续发送该目标地址的ARP请求。
该文字所描述的机制和实际情况存在略微出入,但是大致机制相同。本机会对所有的数据发送做统一的控制,如果主机信息在ARP表中不存在,则进行ARP请求;该请求存在请求次数和请求失败延时的控制,以避免ARP洪泛。
为了深入理解ARP包的发送,查询了系统内核参数:
可以看到,失败重试的参数为3,发送间隔为1000ms。这与tcpdump观察的结果吻合。
解决方案:
知道了原因,下一步就是处理。考虑有如下处理方法:
- 修改发送策略
大量ARP包是向不在线设备发送UDP报文而导致的,因此考虑对不在线节点,间隔较长时间发送UDP。这里不能不发送,因为该UDP机制存在的目的就是为了判断节点的工作状态,如果不在线节点不进行发送,就意味着永远无法判断重新上线节点的状态。
- 修改内核参数
修改ucast_solicit或retrans_time参数,ucast_solicit代表尝试的次数,retrans_time代表重试的间隔时间。增加 retrans_time参数,就可以防止ARP洪泛。