2012-03-16 11 views
2

私は現在、仕事中のプロジェクトの分散サービスアーキテクチャに取り組んでいます。基本的には、200台以上のマシンを管理しています。これらのマシンのそれぞれは、特定の方法でマシンとインターフェースすることを可能にするサービスのインスタンスを実行します。動的リモートサービスの場所 - Springのインジェクト方法

私は、これらの200の同じサービスと話す必要のある制御アプリケーションを持っています。これを実現するためにSpring Remotingを介してRMIを使用したいと考えていました。@Controllerにリモートサービスを@Autowireして、例外サービスがあるローカルサービスのように扱いました。

これは、Springの設定でリモートサービスをハードコードすることができる単一のマシン上の単一のサービスに最適ですが、私が理解できないのは、どのサービス(どのマシン)を動的に選択するか、私は実行時に話をして、そのリモートサービスを「春」の方法で利用できるようにしたいと思います。

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

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

ハードコードされ、単一のサービス・インスタンスの例はそうのようになる:

最初のXMLの抜粋は、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ビットIが作るしようとしているということです動的。ご覧のとおり、このサービスプロキシを作成するには、Bean作成時にサービスURLを知る必要があります。私が話したいマシンに応じて、サービスURLは200以上のバリエーションの1つになります。私が話しているサービスは同じインターフェースですが、現行の要求コンテキストに応じて実行時までどのマシンがわからないでしょう。

+0

あなたのコントロールのアプリケーションはクライアントですか?ハードコードされたバージョンはどのように見えるのですか? – Stefan

+0

私はできるだけ一般的な質問にしようとしていますが、この場合の「制御」アプリは、実際にはこれらのリモートサービスのクライアントである別のサービス層です。ハードコードされたXML設定の例を追加します。 –

答えて

2

あなたはすなわち、追加のサービスを使用して動的にサーバーへの接続を作成し、クライアント/ controllアプリから「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> 
サービスautowireあなたのロジックで

と同じようにそれを使用します。

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

データベース設定では、このサービスにDAOを追加して、適切なURLをロードします。ポートとURL、さらにはインターフェイスクラスもこの方法で設定できます。

私はこれをテストするためのRMIサービスはありませんが、ヘッセンと一緒に作業しました。これがあなたに役立つことを願っています

+0

これは、実装がどのように見えるかはっきりとは分かっていませんでしたが、私がServiceManagerのアイディアを思いついたことを思い起こしています。さらに、リモートサービスURLごとに1つのプロキシインスタンスしか持てないように、キャッシュを追加したいと思うかもしれません。実装は実行可能なオプションのように見えます。 –

+0

この実装を使用すると、新しいエンドポイントを使用してこのメ​​ソッドを新たに呼び出すと、**キャッシュされた古いエンドポイントにアクセスできないため、接続例外が発生します。 * new *を使用していても、新しいエンドポイントを使用するように更新されません。 –

関連する問題