Java REST客户端在将主机的动态地址移动到另一台主机后仍然连接到旧主机
我正在开发具有以下特征的客户端和服务器系统: 这里的客户机和服务器在Linux上运行 有一对冗余服务器主机(用于硬件生存能力)。 每个主机都有一个固定的IP地址。 还有一个浮动IP地址,一次绑定到一台主机 在转换期间,备用主机解除浮动IP的绑定,然后新的活动主机绑定到它。 绑定是通过ifconfig up/down命令完成的。 arping-U用于通知交换机与地址相关的MAC已更改 两台服务器主机都连接到同一个交换机 在此系统中,不使用主机名(fqdn) 服务器主机运行两个java进程和一个erlang进程 客户端在erlang进程上打开了一个永久侦听套接字, 还可以使用RMI接口和REST接口与Java进程通信。 Jersey V1.17框架用于REST。 所有Java进程都运行Java1.6 当客户机使用浮动地址连接到活动服务器时,最初一切正常。 在某一点上,我强制切换服务器。 前活动主机解除浮动地址的绑定,前备用主机绑定到浮动地址 乐趣从这里开始。 根据客户端运行的位置,可以看到三种不同的行为Java REST客户端在将主机的动态地址移动到另一台主机后仍然连接到旧主机,java,linux,jersey,Java,Linux,Jersey,我正在开发具有以下特征的客户端和服务器系统: 这里的客户机和服务器在Linux上运行 有一对冗余服务器主机(用于硬件生存能力)。 每个主机都有一个固定的IP地址。 还有一个浮动IP地址,一次绑定到一台主机 在转换期间,备用主机解除浮动IP的绑定,然后新的活动主机绑定到它。 绑定是通过ifconfig up/down命令完成的。 arping-U用于通知交换机与地址相关的MAC已更改 两台服务器主机都连接到同一个交换机 在此系统中,不使用主机名(fqdn) 服务器主机运行两个java进程和一个er
- A) 客户端运行在与主机不同的网络上 (需要路由才能到达服务器)
- B) 客户机正在原来的备用主机上运行(请记住 (两台服务器主机位于同一网络/交换机上)
- C-客户端在最初活动的主机上运行
- 操作系统(即内核tcp/ip处理)
- JavaVM或其标准库
- 泽西图书馆
- Linux内核IP堆栈正在缓存连接,并且没有 请注意,地址已移动,直到缓存超时。我 尝试各种命令来冲洗它;不行。事实上 与erlang的连接以及名称查找的工作,使我倾向于 相信内核不会在这里产生问题
- 我认为可能存在一些特权java到java的东西 发生在Java或VM的内部。这个名字 查找有效,可能也会使其无效
- 我的最后一个假设是Jersey正在进行某种缓存。
web正在讨论Http连接池。其实 可能是由Java完成的HttpUrlConnection池。我试着 了解更多信息,但只找到模糊的参考资料。然而大多数 我得到的信息表明插座应该被打开和关闭 关闭每个休息请求
谢谢大家给我的建议。我设法抽出更多的时间来研究这个问题 我对一些人关于HttpUrlConnection实例使用的套接字池的引用进行了更多的搜索 我发现的一个有趣的链接是: 它确认默认情况下为HTTP连接保留一个套接字池。 底层套接字保持活动状态 这意味着,当您为每个请求使用新的HttpUrlConnection实例时, 您可能会重用已打开的套接字。 这使得客户端更加高效,尤其是在使用HTTPS的情况下 在我的例子(用例C)中,Linux提供了一个套接字,它在两个本地进程之间保持功能, 即使用来打开它的原始IP地址不见了 这意味着以前从池中打开的套接字现在指向错误的主机。 (即,本地主机不再与该地址关联,将创建一个新主机) 这就解释了我(终于)看到的行为 修复很容易 Oracle的文章指出,您可以设置系统属性http.keepAlive 设置为false(默认为true) 这使得系统为每个HTTP请求打开一个新的套接字。 你失去了效率,但得到了一个能够在地址移动中生存下来的客户。 这对我来说是至关重要的(但可能不是常见的情况) 这篇文章还提到了一些其他可以用来控制池的事情(例如池的大小) 另一种方法公司
System.setProperty("http.keepAlive", "false");