Redis でメッセージング

このガイドでは、Spring Data Redis を使用して Redis で送信されたメッセージをパブリッシュおよびサブスクライブするプロセスを順を追って説明します。

構築するもの

StringRedisTemplate を使用して文字列メッセージを公開し、MessageListenerAdapter を使用してメッセージの POJO サブスクライブを行うアプリケーションを構築します。

Spring Data Redis をメッセージの公開手段として使用するのは奇妙に聞こえるかもしれませんが、ご存知のように、Redis は NoSQL データストアだけでなくメッセージングシステムも提供します。

必要なもの

このガイドを完了する方法

ほとんどの Spring 入門ガイドと同様に、最初から始めて各ステップを完了することも、このリポジトリ [GitHub] (英語) のコードを確認してソリューションに直接進むこともできます。

ローカル環境で最終結果を確認するには、次のいずれかを実行します。

Redis サーバーの設定

メッセージングアプリケーションを構築する前に、メッセージの送受信を処理するサーバーをセットアップする必要があります。このガイドでは、Spring Boot Docker Compose サポートを使用することを前提としています。このアプローチの前提条件は、開発マシンに Docker デスクトップ (英語) などの Docker 環境が利用可能であることです。次の操作を実行する依存関係 spring-boot-docker-compose を追加します。

  • 作業ディレクトリで compose.yml やその他の一般的な compose ファイル名を検索します

  • 検出された compose.yml を使用して docker compose up を呼び出します

  • サポートされているコンテナーごとにサービス接続 Bean を作成する

  • アプリケーションのシャットダウン時に docker compose stop を呼び出します

Docker Compose サポートを使用するには、このガイドに従うだけです。取り込んだ依存関係に基づいて、Spring Boot は正しい compose.yml ファイルを見つけ、アプリケーションの実行時に Docker コンテナーを起動します。

Spring Boot Docker Compose サポートを使用する代わりに、Redis サーバーを自分で実行することを選択した場合は、いくつかのオプションがあります。- サーバーをダウンロードする (英語) を使用して手動で実行する - Mac を使用する場合は、Homebrew でインストールする - docker compose up を使用して compose.yaml ファイルを手動で実行する

これらの代替アプローチのいずれかを選択する場合は、Maven または Gradle ビルドファイルから spring-boot-docker-compose 依存関係を削除する必要があります。また、アプリケーション構築の準備セクションで詳しく説明されているように、application.properties ファイルに構成を追加する必要があります。前述のように、このガイドでは、Spring Boot で Docker Compose サポートを使用することを前提としているため、この時点では application.properties に追加の変更は必要ありません。

Spring Initializr から開始

IDE を使用する場合はプロジェクト作成ウィザードを使用します。IDE を使用せずにコマンドラインなどで開発する場合は、この事前に初期化されたプロジェクトからプロジェクトを ZIP ファイルとしてダウンロードできます。このプロジェクトは、このチュートリアルの例に合うように構成されています。

プロジェクトを手動で初期化するには:

  1. IDE のメニューまたはブラウザーから Spring Initializr を開きます。アプリケーションに必要なすべての依存関係を取り込み、ほとんどのセットアップを行います。

  2. Gradle または Maven のいずれかと、使用する言語を選択します。このガイドは、Java を選択したことを前提としています。

  3. 依存関係をクリックし、Spring Data RedisDocker Compose サポートを選択します。

  4. 生成をクリックします。

  5. 結果として得られる ZIP ファイルをダウンロードします。これは、選択した内容で構成されたアプリケーションのアーカイブです。

EclipseIntelliJ のような IDE は新規プロジェクト作成ウィザードから Spring Initializr の機能が使用できるため、手動での ZIP ファイルのダウンロードやインポートは不要です。

Redis メッセージレシーバーを作成する

メッセージングベースのアプリケーションには、メッセージパブリッシャーとメッセージングレシーバーがあります。メッセージ受信者を作成するには、次の例(src/main/java/com/example/messagingredis/Receiver.java から)に示すように、メッセージに応答するメソッドを使用して受信者を実装します。

package com.example.messagingredis;

import java.util.concurrent.atomic.AtomicInteger;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Receiver {
    private static final Logger LOGGER = LoggerFactory.getLogger(Receiver.class);

    private AtomicInteger counter = new AtomicInteger();

    public void receiveMessage(String message) {
        LOGGER.info("Received <" + message + ">");
        counter.incrementAndGet();
    }

    public int getCount() {
        return counter.get();
    }
}

Receiver は、メッセージを受信する方法を定義する POJO です。Receiver をメッセージリスナとして登録する場合、メッセージ処理メソッドに任意の名前を付けることができます。

デモンストレーションのために、受信者は受信したメッセージをカウントしています。これにより、メッセージを受信したときにシグナルを送信できます。

リスナーを登録してメッセージを送信する

Spring Data Redis は、Redis でメッセージを送受信するために必要なすべてのコンポーネントを提供します。具体的には、以下を構成する必要があります。

  • 接続ファクトリ

  • メッセージリスナーコンテナー

  • Redis テンプレート

Redis テンプレートを使用してメッセージを送信し、Receiver をメッセージリスナーコンテナーに登録して、メッセージを受信します。接続ファクトリは、テンプレートとメッセージリスナーコンテナーの両方を駆動し、Redis サーバーに接続できるようにします。

この例では、Spring Boot のデフォルト RedisConnectionFactory を使用します。これは、Lettuce [GitHub] (英語) Redis ライブラリに基づいた LettuceConnectionFactory のインスタンスです。次の例(src/main/java/com/example/messagingredis/MessagingRedisApplication.java から)が示すように、接続ファクトリはメッセージリスナーコンテナーと Redis テンプレートの両方に挿入されます。

package com.example.messagingredis;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.listener.PatternTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.listener.adapter.MessageListenerAdapter;

@SpringBootApplication
public class MessagingRedisApplication {

	private static final Logger LOGGER = LoggerFactory.getLogger(MessagingRedisApplication.class);

	@Bean
	RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory,
			MessageListenerAdapter listenerAdapter) {

		RedisMessageListenerContainer container = new RedisMessageListenerContainer();
		container.setConnectionFactory(connectionFactory);
		container.addMessageListener(listenerAdapter, new PatternTopic("chat"));

		return container;
	}

	@Bean
	MessageListenerAdapter listenerAdapter(Receiver receiver) {
		return new MessageListenerAdapter(receiver, "receiveMessage");
	}

	@Bean
	Receiver receiver() {
		return new Receiver();
	}

	@Bean
	StringRedisTemplate template(RedisConnectionFactory connectionFactory) {
		return new StringRedisTemplate(connectionFactory);
	}

	public static void main(String[] args) throws InterruptedException {

		ApplicationContext ctx = SpringApplication.run(MessagingRedisApplication.class, args);

		StringRedisTemplate template = ctx.getBean(StringRedisTemplate.class);
		Receiver receiver = ctx.getBean(Receiver.class);

		while (receiver.getCount() == 0) {

			LOGGER.info("Sending message...");
			template.convertAndSend("chat", "Hello from Redis!");
			Thread.sleep(500L);
		}

		System.exit(0);
	}
}

listenerAdapter メソッドで定義された Bean は、container で定義されたメッセージリスナーコンテナーにメッセージリスナーとして登録され、chat トピックでメッセージをリッスンします。Receiver クラスは POJO であるため、MessageListener インターフェース(addMessageListener() で必要)を実装するメッセージリスナーアダプターにラップする必要があります。また、メッセージリスナアダプターは、メッセージが到着したときに Receiver で receiveMessage() メソッドを呼び出すように構成されています。

接続ファクトリとメッセージリスナコンテナー Bean は、メッセージをリッスンするために必要なすべてです。メッセージを送信するには、Redis テンプレートも必要です。ここでは、StringRedisTemplate として構成された Bean であり、RedisTemplate の実装であり、Redis の一般的な使用に焦点を当てています。キーと値の両方が String インスタンスです。

main() メソッドは、Spring アプリケーションコンテキストを作成することにより、すべてを開始します。次に、アプリケーションコンテキストがメッセージリスナコンテナーを起動し、メッセージリスナコンテナー Bean がメッセージのリッスンを開始します。main() メソッドは、アプリケーションコンテキストから StringRedisTemplate Bean を取得し、それを使用して chat トピックで Hello from Redis! メッセージを送信します。最後に、Spring アプリケーションコンテキストを閉じて、アプリケーションを終了します。

アプリケーションの実行

メインメソッドは IDE から実行できます。ソリューションリポジトリからプロジェクトをクローンした場合、IDE は compose.yaml ファイルを間違った場所で探す可能性があることに注意してください。正しい場所を探すように IDE を構成するか、コマンドラインを使用してアプリケーションを実行することができます。./gradlew bootRun コマンドと ./mvnw spring-boot:run コマンドはアプリケーションを起動し、compose.yaml ファイルを自動的に見つけます。

次のような出力が表示されます:

yyyy-mm-ddT07:08:48.646-04:00  INFO 18338 --- [main] c.e.m.MessagingRedisApplication: Sending message...
yyyy-mm-ddT07:08:48.663-04:00  INFO 18338 --- [container-1] com.example.messagingredis.Receiver      : Received <Hello from Redis!>

アプリケーション構築の準備

Spring Boot Docker Compose のサポートなしでコードを実行するには、ローカルで実行されている Redis のバージョンが必要です。これを行うには、Docker Compose を使用できますが、最初に compose.yaml ファイルに 2 つの変更を加える必要があります。まず、compose.yaml の ports エントリを '6379:6379' に変更します。次に、container_name を追加します。

compose.yaml は次のようになります。

services:
  redis:
    container_name: 'guide-redis'
    image: 'redis:latest'
    ports:
      - '6379:6379'

これで、docker compose up を実行して Redis サーバーを起動できます。これで、リクエストを受け入れる準備が整った外部 Redis サーバーができました。アプリケーションを再実行すると、外部 Redis サーバーを使用して同じ出力を確認できます。

デフォルト値は compose.yaml の Redis サーバー構成と一致するため、application.properties ファイルでの構成は必要ありません。具体的には、プロパティ spring.data.redis.host と spring.data.redis.port はそれぞれ localhost と 6379 にデフォルト設定されます。Redis への接続の詳細については、Spring Boot ドキュメントを参照してください。

アプリケーションの構築

このセクションでは、このガイドを実行するさまざまな方法について説明します。

アプリケーションの実行方法に関係なく、出力は同じになります。

アプリケーションを実行するには、アプリケーションを実行可能ファイル jar としてパッケージ化できます。./mvnw clean package コマンドは、アプリケーションを実行可能ファイル jar にコンパイルします。その後、java -jar target/messaging-redis-0.0.1-SNAPSHOT.jar コマンドを使用して jar を実行できます。

あるいは、Docker 環境が利用可能な場合は、buildpacks を使用して、Maven または Gradle プラグインから直接 Docker イメージを作成できます。Cloud Native Buildpacks を使用すると、どこでも実行できる Docker 互換イメージを作成できます。Spring Boot には、Maven と Gradle の両方に対する buildpack のサポートが直接含まれています。つまり、コマンドを 1 つ入力するだけで、ローカルで実行されている Docker デーモンに適切なイメージをすばやく取り込むことができます。Cloud Native Buildpacks を使用して Docker イメージを作成するには、./mvnw spring-boot:build-image コマンドを実行します。Docker 環境が有効になっている場合は、docker run --network container:guide-redis docker.io/library/messaging-redis:0.0.1-SNAPSHOT コマンドを使用してアプリケーションを実行できます。

--network フラグは、外部コンテナーが使用している既存のネットワークにガイドコンテナーを接続するように Docker に指示します。詳細については、Docker ドキュメント (英語) を参照してください。

要約

おめでとう! Spring および Redis を使用したパブリッシュ / サブスクライブアプリケーションを開発しました。

関連事項

次のガイドも役立つかもしれません:

新しいガイドを作成したり、既存のガイドに貢献したいですか? 投稿ガイドラインを参照してください [GitHub] (英語)

すべてのガイドは、コード用の ASLv2 ライセンス、およびドキュメント用の Attribution、NoDerivatives creative commons ライセンス (英語) でリリースされています。

コードを入手する