[英]How to create a new, unique RMI registry on some free port?
I'm writing a Jenkins build step plugin, and want my other processes on localhost to call my plugin's main process' functions and give it data objects.我正在编写一个 Jenkins 构建步骤插件,并希望本地主机上的其他进程调用我的插件的主进程函数并为其提供数据对象。
For this, I decided to use RMI, therefore I want to create an RMI registry, so the other processes can call my functions:为此,我决定使用 RMI,因此我想创建一个 RMI 注册表,以便其他进程可以调用我的函数:
https://docs.oracle.com/javase/7/docs/api/java/rmi/registry/LocateRegistry.html https://docs.oracle.com/javase/7/docs/api/java/rmi/registry/LocateRegistry.html
I want the registry to take any free port available on the system.我希望注册表采用系统上可用的任何空闲端口。 Usually this is done by providing a port of 0 to the registry/socket creation.
通常这是通过为注册表/套接字创建提供端口 0 来完成的。
However, an RMI registry maintains an ID, preventing a subsequent creation if a registry of that ID already exists on the JVM.但是,RMI 注册表维护一个 ID,如果 JVM 上已经存在该 ID 的注册表,则阻止后续创建。 With a port of 0, that registry's ID is 0.
如果端口为 0,则该注册表的 ID 为 0。
There are other actors on the same JVM instance (plugins), that may have created or may want to create a RMI registry on port 0 for port discovery.在同一 JVM 实例(插件)上还有其他参与者,他们可能已经创建或可能希望在端口 0 上创建 RMI 注册表以进行端口发现。 This prevents me from creating my own registry with a free port.
这使我无法使用空闲端口创建自己的注册表。 This is my problem, because I don't want to collide with other registries on this JVM, yet still get an available free port.
这是我的问题,因为我不想与此 JVM 上的其他注册表发生冲突,但仍然可以获得可用的免费端口。
Is there some solution for this?有什么解决办法吗?
Did I get something wrong?我是不是搞错了什么?
If I used an existing registry, I'd be concerned that my bindings will collide with existing bindings.如果我使用现有的注册表,我会担心我的绑定会与现有的绑定发生冲突。
I tried to provide a custom RMIServerSocketFactory
implementation to LocateRegistry.createRegistry
, choosing a free port (port = 0), and calling createRegistry
itself with any other port for id.我尝试为
LocateRegistry.createRegistry
提供自定义RMIServerSocketFactory
实现,选择一个空闲端口(端口 = 0),并使用任何其他端口调用createRegistry
本身作为 id。 However, the created Registry somehow uses the correct port, but internally thinks it uses the given port.但是,创建的注册表以某种方式使用了正确的端口,但内部认为它使用给定的端口。 I am concerned, this will lead to further problems later on.
我担心,这会导致以后出现更多问题。 Also, I cannot reliable choose a nonexisting id, as I'd have to try several if they turn out to be used already.
另外,我不能可靠地选择一个不存在的 id,因为如果它们已经被使用,我必须尝试几个。 This is the same problem I set out to solve with the ports.
这与我打算用端口解决的问题相同。
Poking a port with a socket connection, then creating a Registry on that port does not work for me.用套接字连接戳一个端口,然后在该端口上创建一个注册表对我不起作用。 Because this introduces a gap between forfeiting the port and creating the registry on that port.
因为这在没收端口和在该端口上创建注册表之间引入了差距。 And I don't want another process to jump in and take the port in the mean time.
而且我不希望另一个进程同时加入并占用该端口。
Summarizing what I found out in the mean time, RMI is not a good fit for the scenario I want to cover.总结一下我同时发现的情况,RMI 并不适合我想要涵盖的场景。
Java's RMI mechanism is designed for: Java 的 RMI 机制设计用于:
In both cases these problems apply:在这两种情况下,这些问题都适用:
The RMI mechanism is not designed for creating an ad-hoc RMI registry that is dedicated to a single server/client communication: RMI 机制不是为创建专用于单个服务器/客户端通信的 ad-hoc RMI 注册表而设计的:
Therefore, in a plugin scenario, where, within the same JVM, other actors may execute code, and you need to start several communications to very similar spawned processes, and there may be other processes around, that do the same thing, RMI opens several points of failure that cannot easily be mitigated.因此,在插件场景中,在同一个 JVM 中,其他参与者可能会执行代码,并且您需要启动几个与非常相似的衍生进程的通信,并且周围可能有其他进程做同样的事情,RMI 会打开几个无法轻易缓解的故障点。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.