简体   繁体   English

哪个主机名或 ip 是 linux 中的 java rmi 绑定的?

[英]which hostname or ip is java rmi bind in linux?

i am new with java rmi.我是java rmi的新手。 And i have a question about rmi usage.我有一个关于 rmi 使用的问题。
Firstly, i created a server with port(the interface only has a port argument).首先,我创建了一个带有端口的服务器(接口只有一个端口参数)。

this.registry = LocateRegistry.createRegistry(1099);

Then i bind a server like this:然后我像这样绑定服务器:


public interface MyRmiService extends Remote {
    // return "service name" for example
    String getName() throws RemoteException;
}

 public void register(MyRmiService service) {
        try {
            this.registry.rebind(syncDataService.getName(), service);
        } catch (RemoteException var3) {
            FineLoggerFactory.getLogger().error(var3.getMessage(), var3);
        }

}

and my client code is like this:我的客户代码是这样的:

// linux ip
Registry tempRegistry = LocateRegistry.getRegistry(ip, 1099);
MyRmiService service = (MyRmiService)tempRegistry.lookup("service name");

These code looks fine if my machine ip looks the same with linux shell:如果我的机器 ip 与 linux shell 看起来相同,这些代码看起来很好:

[root@node26 ~]# hostname
node26
[root@node26 ~]# hostname -i
192.168.101.26
[root@node26 ~]# hostname -I
192.168.101.26 192.168.122.1 172.17.0.1 

if i use 192.168.101.26 as ip.如果我使用 192.168.101.26 作为 ip。
But if i get some different ip like this:但是如果我得到一些像这样的不同的ip:

# for example
[root@a ~]# hostname -I
172.16.5.199 172.17.0.1 
[root@iZbp124z80qrl3rd8pk42xZ ~]# hostname -i
10.162.107.99
[root@iZbp124z80qrl3rd8pk42xZ ~]# hostname
iZbp124z80qrl3rd8pk42xZ

It doesn't work fine and stuck in the client finding service with lookup .它不能正常工作,并且卡在使用lookup的客户端查找服务中。
Normally i want to use 172.16.5.199 as ip.通常我想使用172.16.5.199作为 ip。 But maybe rmi is using 10.162.107.99 which i cannot ping from client.但也许 rmi 正在使用10.162.107.99我无法从客户端 ping。 Is this linux server has the right hostname config?这个 linux 服务器是否有正确的主机名配置?
Then I'm confused.然后我很困惑。

  1. which hostname or ip is used when LocateRegistry.createRegistry(1099); LocateRegistry.createRegistry(1099); called?叫?
  2. which hostname or ip is used when registry.rebind(syncDataService.getName(), service); registry.rebind(syncDataService.getName(), service);时使用哪个主机名或 ip called?叫?
  3. which ip should i use to call LocateRegistry.getRegistry(ip, 1099);我应该使用哪个 ip 来调用LocateRegistry.getRegistry(ip, 1099); ? ? My question is, what exactly the ip should i use?我的问题是,我应该使用什么IP?

TLDR: it's not the registry TLDR:这不是注册表

To get your first and third questions out of the way让你的第一个和第三个问题不碍事

  • the registry created by LocateRegistry.createRegistry (like the one created by running the JRE/bin/registry[.exe] program ) listens on 0.0.0.0 for IPv4 and/or ::0 for IPv6 depending on your JVM config.LocateRegistry.createRegistry创建的注册表(如通过运行JRE/bin/registry[.exe]程序创建的注册表)根据您的 JVM 配置侦听 IPv4 的 0.0.0.0 和/或 IPv6 的 ::0 。 This can receive on any address (and over any interface) that works in your OS.这可以在您的操作系统中工作的任何地址(和任何接口)上接收。

  • LocateRegistry.getRegistry(String[,int]) connects to whatever address or name (resolved to an address) you specify; LocateRegistry.getRegistry(String[,int])连接到您指定的任何地址或名称(解析为地址); ([int]) calls InetAddress.getLocalHost() which dispatches to getLocalHostName() in Inet4AddressImp or Inet6AddressImpl depending on your JVM as above, but in either case that is a native method with implementation depending on your OS which for Unix including Linux is here or here . ([int])调用InetAddress.getLocalHost() ,它根据上面的 JVM 调度到Inet4AddressImpInet6AddressImpl中的getLocalHostName() ,但在任何一种情况下,这都是一种本机方法,其实现取决于你的操作系统,包括 Linux 在内的 Unix 在这里在这里 As you can see these are identical and thus it always calls gethostname() which should return the same value the hostname progam (with no options) displays;正如您所看到的,它们是相同的,因此它总是调用gethostname() ,它应该返回与hostname程序(没有选项)显示的相同的值; if the call fails (returns nonzero) Java substitutes the literal string "localhost" .如果调用失败(返回非零)Java 将替换文字字符串"localhost" That name is then resolved, typically by a host file and/or DNS but may vary depending on the OS and configuration;然后解析该名称,通常由主机文件和/或 DNS 解析,但可能因操作系统和配置而异; on a properly configured system gethostname() will be a name that resolves to a valid address of the machine (displayed by hostname -i ), while localhost is special-cased to always give the loopback address (for the IP version) which is a valid address only when used on the same machine ie not really RMI.在正确配置的系统上, gethostname()将是一个解析为机器有效地址的名称(由hostname -i显示),而localhost是特殊情况下始终提供环回地址(对于 IP 版本),它是只有在同一台机器上使用时才有效地址,即不是真正的 RMI。 (A properly configured OS also resolves localhost to loopback, but Java does so here even if the OS doesn't.) Note that none of these look at the addresses actually existing on your interfaces (which hostname -I returns). (正确配置的操作系统也将 localhost 解析为环回,但即使操作系统没有,Java 也会在此处这样做。)请注意,这些都不会查看接口上实际存在的地址( hostname -I返回的地址)。

That connection, to the registry, worked fine.这种与注册表的连接运行良好。 You say it's the lookup call that hangs, and that is trying to connect to the remote service .您说这是挂起的lookup调用,并且正在尝试连接到远程服务 This relates to your second question about registry.rebind(name, remoteobject) -- but it's not the rebind (or bind ) call that sets the location of the remoteobject, rather the remoteobject already contains its location.这与您关于registry.rebind(name, remoteobject)的第二个问题有关——但设置远程对象位置的不是rebind (或bind )调用,而是远程对象已经包含其位置。 You use a parameter service without showing where it comes from and particularly where it was created, and that's what matters, because such an object is created to contain a LiveRef which in turn creates and contains a TCPEndpoint which contains the name or address to be used to connect it.您使用参数service时没有显示它来自哪里,特别是它是在哪里创建的,这很重要,因为这样一个对象被创建为包含一个LiveRef ,而 LiveRef 又创建并包含一个TCPEndpoint ,其中包含要使用的名称或地址连接它。

Now the code in TCPEndpoint which determines that name or address is a bit complicated.现在TCPEndpoint中确定名称或地址的代码有点复杂。 The simple case is that if sysprop java.rmi.server.hostname is set, that is used -- and can be either a resolvable name or an address in string form.最简单的情况是,如果设置了 sysprop java.rmi.server.hostname ,则使用它——并且可以是可解析的名称字符串形式的地址。 Otherwise it calls InetAddress.getLocalHost() as described above for getRegistry and by default it uses the resulting address , but if sysprop java.rmi.server.useLocalHostName is set true it uses the name (ie from gethostname() ) except if the name doesn't contain a dot (doesn't 'look like' a DNS name) it attempts reverse resolution on the address and if successful uses that name;否则,它调用InetAddress.getLocalHost() ,如上面对getRegistry的描述,默认情况下它使用结果地址,但如果 sysprop java.rmi.server.useLocalHostName设置为true它使用名称(即来自gethostname() ),除非名称不包含点(不“看起来像”DNS 名称)它尝试对地址进行反向解析,如果成功则使用名称; it's not quite clear to me what happens if that fails, and I can't easily test right now.我不太清楚如果失败会发生什么,我现在不能轻易测试。

So the simple answer to your problem, but not your question, is use java.rmi.server.hostname to specify a name or address that the client(s) should use to reach your server.因此,对您的问题(但不是您的问题)的简单答案是使用java.rmi.server.hostname来指定客户端应该用来访问您的服务器的名称或地址。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM