2

私は現在、作業中のプロジェクトの分散サービス アーキテクチャに取り組んでいます。基本的に、私たちは 200 台以上のマシンを管理しています。これらの各マシンには、特定の方法でマシンとやり取りできるサービスのインスタンスが実行されています。

センターには、これら 200 の同一のサービスと対話する必要がある制御アプリケーションがあります。これを実現するために、Spring Remoting を介して RMI を使用することを望んでいました。これにより、リモート サービスを @Autowire で @Controller に接続し、ローカル サービスのように例外伝播を使用して処理できます。将来的には、フックを介したトランザクション/セキュリティ コンテキストの伝播が可能になります。

これは、Spring 構成でリモート サービスをハードコーディングできる単一のマシン上の単一のサービスには最適ですが、どのサービス (別名、どのマシン) を話したいかを動的に選択する方法がわかりません。実行時にそのリモートサービスを「Spring」の方法で利用できるようにします。

これをデータベース テーブルから動的に構成し、同じテーブル情報を使用してサービス ルックアップを実行しながら、依存性注入を利用できるようにしたいと考えています。

ある種のサービス ルックアップを実行できる何らかのサービス マネージャーを注入することを考えましたが、他の誰かがこの (または同様の) 問題をエレガントに解決してくれることを期待していました。

ハードコーディングされた単一のサービス インスタンスの例は次のようになります。

最初の 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>

2 番目の 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>

動的にしようとしているのは、構成の 2 番目のビットです。ご覧のとおり、このサービス プロキシを作成するには、Bean の作成時にサービス URL を知る必要があります。サービス URL は、どのマシンと話したいかによって、200 以上のバリエーションのうちの 1 つになります。私が話しているサービスは同じインターフェースですが、現在の要求コンテキストに応じて、実行時までどのマシンかわかりません。

4

1 に答える 1

2

追加のサービスを使用してサーバーへの接続を動的に作成し、クライアント/コントロール アプリから「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>

ロジックでサービスを自動配線し、次のように使用します。

DeviceService server1 = rmiService.connect("127.0.0.1");

データベース構成の場合、DAO をこのサービスに追加して、正しい URL をロードします。ポートと URL、またはインターフェイス クラスでさえ、この方法で構成できます。

これをテストするための RMI サービスはありませんが、Hessian でも機能しました。これがお役に立てば幸いです。

于 2012-03-16T20:35:58.160 に答える