Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/385.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java REST客户端在将主机的动态地址移动到另一台主机后仍然连接到旧主机_Java_Linux_Jersey - Fatal编程技术网

Java REST客户端在将主机的动态地址移动到另一台主机后仍然连接到旧主机

Java REST客户端在将主机的动态地址移动到另一台主机后仍然连接到旧主机,java,linux,jersey,Java,Linux,Jersey,我正在开发具有以下特征的客户端和服务器系统: 这里的客户机和服务器在Linux上运行 有一对冗余服务器主机(用于硬件生存能力)。 每个主机都有一个固定的IP地址。 还有一个浮动IP地址,一次绑定到一台主机 在转换期间,备用主机解除浮动IP的绑定,然后新的活动主机绑定到它。 绑定是通过ifconfig up/down命令完成的。 arping-U用于通知交换机与地址相关的MAC已更改 两台服务器主机都连接到同一个交换机 在此系统中,不使用主机名(fqdn) 服务器主机运行两个java进程和一个er

我正在开发具有以下特征的客户端和服务器系统: 这里的客户机和服务器在Linux上运行

有一对冗余服务器主机(用于硬件生存能力)。 每个主机都有一个固定的IP地址。 还有一个浮动IP地址,一次绑定到一台主机

在转换期间,备用主机解除浮动IP的绑定,然后新的活动主机绑定到它。 绑定是通过ifconfig up/down命令完成的。 arping-U用于通知交换机与地址相关的MAC已更改

两台服务器主机都连接到同一个交换机

在此系统中,不使用主机名(fqdn)

服务器主机运行两个java进程和一个erlang进程

客户端在erlang进程上打开了一个永久侦听套接字, 还可以使用RMI接口和REST接口与Java进程通信。 Jersey V1.17框架用于REST。 所有Java进程都运行Java1.6

当客户机使用浮动地址连接到活动服务器时,最初一切正常。 在某一点上,我强制切换服务器。 前活动主机解除浮动地址的绑定,前备用主机绑定到浮动地址

乐趣从这里开始。 根据客户端运行的位置,可以看到三种不同的行为

  • A) 客户端运行在与主机不同的网络上 (需要路由才能到达服务器)
  • B) 客户机正在原来的备用主机上运行(请记住 (两台服务器主机位于同一网络/交换机上)
  • C-客户端在最初活动的主机上运行
B&C是需要的用例

案例A是最容易解决的。 一旦地址是无限的,我就会得到一个套接字异常,我可以对它做出反应,从连接到erlang进程。 只需等待地址再次绑定并重新连接,即可解决此问题。 RMI接口是相同的,再次执行名称查找将返回指向新活动主机的存根 (存根指向固定地址-我可以接受) 然后,当我发出REST请求时,它们也会被路由到新的活动主机

案例B提供了一个稍有不同的错误,心跳信号在检测变化时起作用, 但解决办法是一样的

我无法理解的案例是案例C。 在这种情况下,到erlang进程的连接正确地从本地主机移动到新的活动主机。 RMI名称查找也从新主机完成

但是,REST调用从本地主机(以前的活动主机)而不是新的活动主机返回数据。 这种情况持续几分钟(通常为3-4分钟),然后事情自行解决! 我非常努力地想弄明白这一点,测试,网络挖掘,到目前为止没有运气

我认为这种行为可能来自三个方面:

  • 操作系统(即内核tcp/ip处理)
  • JavaVM或其标准库
  • 泽西图书馆
我做了很多假设:

  • Linux内核IP堆栈正在缓存连接,并且没有 请注意,地址已移动,直到缓存超时。我 尝试各种命令来冲洗它;不行。事实上 与erlang的连接以及名称查找的工作,使我倾向于 相信内核不会在这里产生问题

  • 我认为可能存在一些特权java到java的东西 发生在Java或VM的内部。这个名字 查找有效,可能也会使其无效

  • 我的最后一个假设是Jersey正在进行某种缓存。
    web正在讨论Http连接池。其实 可能是由Java完成的HttpUrlConnection池。我试着 了解更多信息,但只找到模糊的参考资料。然而大多数 我得到的信息表明插座应该被打开和关闭 关闭每个休息请求

现在我绝望了,准备考虑任何假设。 ;-)

有人能解释一种机制,这种机制会继续将数据包路由到错误的主机吗 地址移动到主机后

对于3到4分钟后似乎会变清晰这一事实,我们能说些什么呢。 这可能是什么类型的缓存


谢谢大家给我的建议。

我设法抽出更多的时间来研究这个问题

我对一些人关于HttpUrlConnection实例使用的套接字池的引用进行了更多的搜索

我发现的一个有趣的链接是:

它确认默认情况下为HTTP连接保留一个套接字池。 底层套接字保持活动状态

这意味着,当您为每个请求使用新的HttpUrlConnection实例时, 您可能会重用已打开的套接字。 这使得客户端更加高效,尤其是在使用HTTPS的情况下

在我的例子(用例C)中,Linux提供了一个套接字,它在两个本地进程之间保持功能, 即使用来打开它的原始IP地址不见了

这意味着以前从池中打开的套接字现在指向错误的主机。 (即,本地主机不再与该地址关联,将创建一个新主机)

这就解释了我(终于)看到的行为

修复很容易

Oracle的文章指出,您可以设置系统属性http.keepAlive 设置为false(默认为true)

这使得系统为每个HTTP请求打开一个新的套接字。 你失去了效率,但得到了一个能够在地址移动中生存下来的客户。 这对我来说是至关重要的(但可能不是常见的情况)

这篇文章还提到了一些其他可以用来控制池的事情(例如池的大小)

另一种方法公司
System.setProperty("http.keepAlive", "false");