我目前正在为一个工作项目开发分布式服务架构。基本上,我们管理着超过 200 台机器。每台机器上都有一个运行的服务实例,允许我们以特定方式与机器交互。
在中心,我有一个控制应用程序,它需要与这 200 个相同的服务进行通信。我希望通过 Spring Remoting 使用 RMI 来实现这一点,允许我将我的远程服务 @Autowire 到我的 @Controller 中,并将其视为具有异常传播的本地服务,并且可能在未来通过钩子(Hook)传播事务/安全上下文。
这对于单台机器上的单个服务非常有用,我可以在 Spring 配置中对远程服务进行硬编码,但我无法弄清楚如何动态选择我要使用的服务(又名哪台机器)想要在运行时进行对话,并使远程服务以“Spring”方式可用。
我希望能够从数据库表动态配置它,并使用相同的表信息进行服务查找,同时仍然利用依赖项注入(inject)。
我想到也许注入(inject)某种可以进行某种服务查找的服务管理器,但希望其他人能够优雅地解决这个(或类似的)问题。
硬编码的单个服务实例的示例如下所示:
第一个 XML 片段位于机器服务本身,告诉 Spring 通过 RMI 公开它
<!-- Expose DeviceService via RMI -->
<bean class="org.springframework.remoting.rmi.RmiServiceExporter">
<property name="serviceName" value="DeviceService" />
<property name="service" ref="deviceService" />
<property name="serviceInterface"
value="com.example.service.DeviceService" />
<property name="registryPort" value="1199" />
</bean>
第二个 XML 片段位于客户端(控制应用程序)上,它允许我访问公开的服务
<!-- Proxy our remote DeviceService via RMI -->
<bean id="remoteDeviceService" class="org.springframework.remoting.rmi.RmiProxyFactoryBean">
<property name="serviceUrl" value="rmi://machineurl:1199/DeviceService"/>
<property name="serviceInterface" value="com.example.service.DeviceService"/>
</bean>
这是我试图使其动态化的第二个配置。正如您所看到的,要创建此服务代理,我需要在创建 bean 时知道服务 URL。服务 URL 可以是 200 多种变体中的一种,具体取决于我想要与之通信的机器。我正在谈论的服务是相同的接口(interface),但直到运行时我才知道是哪台机器,具体取决于当前的请求上下文。
最佳答案
您可以使用附加服务动态创建与服务器的连接,并从客户端/控制应用程序中删除“remoteDeviceService”,即:
public class RMIConnectionService {
public DeviceService connect(String serverUrl) {
RmiProxyFactoryBean factory = new RmiProxyFactoryBean();
factory.setServiceInterface(DeviceService.class);
factory.setServiceUrl("rmi://" + serverUrl + ":1099/SERVICE_URL");
factory.afterPropertiesSet();
//...
return (DeviceService) factory.getObject();
}
}
然后将此服务添加到您的服务层:
<bean id="rmiService" class="...RMIConnectionService" >
//...
</bean>
在您的逻辑中 Autowiring 服务并使用它,如下所示:
DeviceService server1 = rmiService.connect("127.0.0.1");
对于数据库配置,将您的 DAO 添加到此服务,以加载正确的 url。端口和url,甚至接口(interface)类也可以这样配置。
我没有 RMI 服务来测试这个,但它也适用于 Hessian。我希望这对您有帮助。
关于java - 动态远程服务位置-如何用Spring注入(inject)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9742837/