JMSとActiveMQを使用したSpring Remoting

JMSとActiveMQを使用したSpring Remoting

1. 概要

previous articleで、Spring Remotingを使用して非同期チャネルの上にAMQPキューとしてRPCを提供する方法を確認しました。 ただし、JMSを使用しても同じ結果を得ることができます。

この記事では、実際、Spring Remoting JMSApache ActiveMQをメッセージングミドルウェアとして使用してリモート呼び出しを設定する方法について説明します。

2. ApacheActiveMQブローカーの起動

Apache ActiveMQは、アプリケーションが非同期で情報を交換できるようにするopen source message brokerであり、Java Message ServiceAPIと完全に互換性があります。

実験を実行するには、最初にActiveMQの実行インスタンスを設定する必要があります。 いくつかの方法から選択できます。official guideで説明されている手順に従って、Javaアプリケーションに埋め込むか、次のコマンドを使用してDockerコンテナを起動します。

docker run -p 61616:61616 -p 8161:8161 rmohr/activemq:5.14.3

これにより、ポート8081で単純な管理Web GUIを公開するActiveMQコンテナーが開始されます。これにより、使用可能なキュー、接続されているクライアント、およびその他の管理情報を確認できます。 JMSクライアントは、代わりにポート61616を使用してブローカーに接続し、メッセージを交換する必要があります。

3. Mavenの依存関係

Spring Remotingをカバーする以前の記事と同様に、サーバーとクライアントのSpring Bootアプリケーションをセットアップして、JMS Remotingがどのように機能するかを示します。

通常、Spring Bootのスターター依存関係、as explained hereを慎重に選択します。


    org.springframework.boot
    spring-boot-starter-activemq
    
        
            org.springframework.boot
            spring-boot-starter-tomcat
        
    

クラスパスにTomcat関連の.jarファイルが含まれないようにするために、spring-boot-starter-tomcatを明示的に除外しました。

これにより、Spring Bootの自動構成メカニズムが、アプリケーションの起動時に組み込みWebサーバーを必要としないため、起動できなくなります。

4. サーバーアプリケーション

4.1. サービスを公開する

クライアントが呼び出すことができるCabBookingServiceを公開するサーバーアプリケーションをセットアップします。

The first step is to declare a bean that implements the interface of the service we want to expose to the clients.これは、サーバー上でビジネスロジックを実行するBeanです。

@Bean
CabBookingService bookingService() {
    return new CabBookingServiceImpl();
}

次に、コンストラクターで名前を指定して、サーバーが呼び出しを取得するキューを定義しましょう。

@Bean
Queue queue() {
    return new ActiveMQQueue("remotingQueue");
}

以前の記事からすでに知っているように、one of the main concepts of Spring Remoting is the Service Exporter, the component that collects the invocation requests from some source、この場合はApacheMQキュー─そしてサービス実装で目的のメソッドを呼び出します。

JMSを操作するために、JmsInvokerServiceExporterを定義します。

@Bean
JmsInvokerServiceExporter exporter(CabBookingService implementation) {
    JmsInvokerServiceExporter exporter = new JmsInvokerServiceExporter();
    exporter.setServiceInterface(CabBookingService.class);
    exporter.setService(implementation);
    return exporter;
}

最後に、メッセージを消費する責任を持つリスナーを定義する必要があります。 listener acts as a bridge between ApacheMQ and the*JmsInvokerServiceExporter*,は、キューで使用可能な呼び出しメッセージをリッスンし、呼び出しをサービスエクスポーターに転送し、結果をシリアル化して戻します。

@Bean SimpleMessageListenerContainer listener(
  ConnectionFactory factory,
  JmsInvokerServiceExporter exporter) {

    SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
    container.setConnectionFactory(factory);
    container.setDestinationName("remotingQueue");
    container.setConcurrentConsumers(1);
    container.setMessageListener(exporter);
    return container;
}

4.2. 設定

application.propertiesファイルを設定して、Spring Bootがいくつかの基本的なオブジェクト(たとえば、リスナーが必要とするConnectionFactory)を構成できるようにすることを忘れないでください。 さまざまなパラメータの値は、主に方法に依存します

さまざまなパラメータの値は、主にApacheMQのインストール方法によって異なります。次の例は、これらの例を実行するのと同じマシンで実行されるDockerコンテナの適切な構成です。

spring.activemq.broker-url=tcp://localhost:61616
spring.activemq.packages.trusted=org.springframework.remoting.support,java.lang,com.example.api

spring.activemq.broker-urlパラメータはAMQポートへの参照です。 代わりに、spring.activemq.packages.trusted parameterについてより深い説明が必要です。 バージョン5.12.2以降、ActiveMQはデフォルトでタイプのメッセージを拒否します

バージョン5.12.2以降、ActiveMQは、一部のコンテキストでセキュリティ攻撃の潜在的なベクトルと見なされるため、シリアル化されたJavaオブジェクトの交換に使用されるタイプObjectMessageのメッセージをデフォルトで拒否します。

とにかく、指定されたパッケージでシリアル化されたオブジェクトを受け入れるようにAMQに指示することは可能です。 org.springframework.remoting.supportは、リモートメソッドの呼び出しとその結果を表すメインメッセージを含むパッケージです。 その包み

パッケージcom.example.apiには、サービスのパラメーターと結果が含まれています。 タクシー予約の結果を表すオブジェクトがStringを参照するため、java.langが追加されます。したがって、これもシリアル化する必要があります。

5. クライアントアプリケーション

5.1. リモートサービスを呼び出す

それでは、クライアントに取り組みましょう。 繰り返しますが、呼び出しメッセージが書き込まれるキューを定義する必要があります。 クライアントとサーバーの両方が同じ名前を使用していることを再確認する必要があります。

@Bean
Queue queue() {
    return new ActiveMQQueue("remotingQueue");
}

次に、エクスポーターをセットアップする必要があります。

@Bean
FactoryBean invoker(ConnectionFactory factory, Queue queue) {
    JmsInvokerProxyFactoryBean factoryBean = new JmsInvokerProxyFactoryBean();
    factoryBean.setConnectionFactory(factory);
    factoryBean.setServiceInterface(CabBookingService.class);
    factoryBean.setQueue(queue);
    return factoryBean;
}

これで、リモートサービスをローカルBeanとして宣言されているかのように使用できます。

CabBookingService service = context.getBean(CabBookingService.class);
out.println(service.bookRide("13 Seagate Blvd, Key Largo, FL 33037"));

5.2. 例を実行する

また、クライアントアプリケーションの場合、アプリケーションの.propertiesファイルの値を適切に選択する必要があります。 一般的な設定では、これらはサーバー側で使用されるものと正確に一致します。

これは、Apache AMQを介したリモート呼び出しを示すのに十分なはずです。 それでは、最初にApacheMQを起動し、次にサーバーアプリケーションを起動し、最後にリモートサービスを呼び出すクライアントアプリケーションを起動します。

6. 結論

このクイックチュートリアルでは、Spring Remotingを使用してJMSシステムの上にRPCAMQとして提供する方法を説明しました。

Spring Remotingは、基になるチャネルに関係なく、非同期呼び出しを簡単に設定する方法を迅速に実証し続けます。

いつものように、ソースover on GitHubが見つかります。