我有一个运行自定义 UDP 服务器的两节点集群。集群有一个公共 IP 地址,每个节点在同一子网中都有自己的私有 IP 地址。
UDP 服务器绑定到通配符地址,因此它可以接收来自公共或私有 IP 的数据报。问题是我无法控制发送回复的 IP 选择。无论出于何种原因,它似乎默认使用私有 IP。
现在,如果客户端只是向服务器发送命令并在同一端口上侦听回复,那不是问题。但是,一些客户端使用 connect() 调用,这限制了它们从最初发送命令的地址接收回复。如果他们向公共 IP 发送命令并在另一个 IP 上收到答案,他们就会忽略它。值得注意的例子是 Nagios 的 check_udp 插件。
服务器是用 Java 编写的,使用普通的 java.net.DatagramSocket。我在 DatagramPacket 类中看不到任何用于获取接收数据包的本地 IP 地址的方法。
我能做什么:
- 重写 check_udp 以使用 bind() 而不是 connect()。这很痛苦,没有人保证将来不会有任何类似的客户。
- 仅将服务器绑定到公共 IP。可能,但需要一些额外的集群设置才能仅在 IP 启动后启动服务器。它既会增加故障转移时间,也会引入不必要的服务器重启。现在,服务器总是在两个节点上运行,准备好接受请求。
- 修改服务器以从收到请求的同一地址回复。这是最好的方法,但我需要弄清楚有问题的地址才能做到这一点。而且我还需要一种方法来从该地址发送回复 - 有没有办法在不关闭和重新打开套接字的情况下做到这一点?
- 修改服务器不定时尝试绑定公网IP。可能,但麻烦。如何处理已经在套接字上活动的客户端?
我在这里缺少什么吗?这似乎不是一项非常艰巨的任务,但我似乎没有找到一个简单的解决方案。