Redis
 Computer >> コンピューター >  >> プログラミング >> Redis

JedisライブラリでRedisのPub/Subシステムを実装する方法【Javaサンプルコード付き】

このチュートリアルでは、Java向けクライアントライブラリ「Jedis」を使用して、RedisのPub/Sub(パブリッシュ/サブスクライブ)システムを実装する方法を解説します。

Jedisライブラリとは

Jedisは、Redisデータストア用のJavaクライアントライブラリです。軽量で非常に扱いやすく、Redis 2.8.x、3.x.x以降のバージョンと完全な互換性があります。シンプルなAPI设计で、Redisの各種コマンドを直感的に操作できるのが特徴です。

RedisのPub/Subシステムとは

Redisは、Publish/Subscribe(パブリッシュ/サブスクライブ)型のメッセージングパラダイムを実装しています。このモデルでは、メッセージの送信者(パブリッシャー)は、特定の受信者(サブスクライバー)へ直接メッセージを送るようには設計されていません。送信者は特定の「チャネル」に対してメッセージを発行(パブリッシュ)するだけで、そのメッセージが誰に届くのか、そもそも受け取る相手が存在するのかを意識しません。

一方、受信者は1つ以上のチャネルを購読(サブスクライブ)することで関心を登録し、該当するチャネルに発行されたメッセージだけを受け取ります。受信者側も、どの送信者がメッセージを送ったのかを知る必要はありません。この仕組みにより、送信者と受信者は完全に分離(疎結合)され、柔軟でスケーラブルなメッセージングが実現します。

プロジェクトのセットアップ

お好みのIDEでシンプルなMavenプロジェクトを作成し、pom.xmlファイルに以下の依存関係を追加してください。

<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.0.1</version>
</dependency>

最新バージョンのJedisライブラリについては、Maven Central Repositoryで確認できます。

Redisのインストール

動作確認には、最新版のRedisが必要です。インストール手順の詳細は、Redis公式ドキュメントをご参照ください。

Jedis接続の作成

JavaコードからRedisに接続するには、Jedisクラス(redis.clients.jedis.Jedis)のオブジェクトを作成します。

Jedis jedis = new Jedis();

ローカルマシン上でデフォルトポート(6379)を使用してRedisサービスを起動している場合は、デフォルトコンストラクタでそのまま接続できます。それ以外の場合は、正しいホスト名とポート番号をコンストラクタの引数として渡してください。

チャネルへの購読(Subscribe)

まず、「ChannelSubscribe」というクラスを作成します。このクラスは、クライアントを作成してチャネルC1とC2を購読します。他のクライアントがチャネルC1またはC2にメッセージをパブリッシュすると、このクライアントがそのメッセージを受信します。

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPubSub;

public class ChannelSubscribe {

public static void main(String[] args) {

Jedis jedis = null;

try {

/* Creating Jedis object for connecting with redis server */
jedis = new Jedis();

/* Creating JedisPubSub object for subscribing with channels */
JedisPubSub jedisPubSub = new JedisPubSub() {

@Override
public void onMessage(String channel, String message) {
System.out.println("Channel " + channel + " has sent a message : " + message );
if(channel.equals("C1")) {
/* Unsubscribe from channel C1 after first message is received. */
unsubscribe(channel);
}
}

@Override
public void onSubscribe(String channel, int subscribedChannels) {
System.out.println("Client is Subscribed to channel : "+ channel);
System.out.println("Client is Subscribed to "+ subscribedChannels + " no. of channels");
}

@Override
public void onUnsubscribe(String channel, int subscribedChannels) {
System.out.println("Client is Unsubscribed from channel : "+ channel);
System.out.println("Client is Subscribed to "+ subscribedChannels + " no. of channels");
}

};

/* Subscribing to channel C1 and C2 */
jedis.subscribe(jedisPubSub, "C1", "C2");

} catch(Exception ex) {

System.out.println("Exception : " + ex.getMessage());

} finally {

if(jedis != null) {
jedis.close();
}
}
}
}

実行結果

「ChannelSubscribe」クラスを実行すると、以下のような出力が得られます。

JedisライブラリでRedisのPub/Subシステムを実装する方法【Javaサンプルコード付き】

チャネルへのパブリッシュ(Publish)

次に、「ChannelPublish」というクラスを作成します。このクラスはJedis接続経由でRedisサーバーに接続し、チャネルC1とC2にそれぞれ2件ずつメッセージをパブリッシュします。

import redis.clients.jedis.Jedis;

public class ChannelPublish {

public static void main(String[] args) {

Jedis jedis = null;

try {
/* Creating Jedis object for connecting with redis server */
jedis = new Jedis();

/* Publishing message to channel C1 */
jedis.publish("C1", "First message to channel C1");

/* Publishing message to channel C2 */
jedis.publish("C2", "First message to channel C2");

/* Publishing message to channel C1 */
jedis.publish("C1", "Second message to channel C1");

/* Publishing message to channel C2 */
jedis.publish("C2", "Second message to channel C2");

} catch(Exception ex) {

System.out.println("Exception : " + ex.getMessage());
} finally {

if(jedis != null) {
jedis.close();
}
}
}
}

実行結果

「ChannelPublish」クラスを実行すると、ChannelSubscribe側のコンソールには以下のように出力されます。

JedisライブラリでRedisのPub/Subシステムを実装する方法【Javaサンプルコード付き】

パターンへの購読(PSubscribe)

続いて、「PatternSubscribe」というクラスを作成します。このクラスは、glob形式のパターン「C*」と「D?」を購読するクライアントを作成します。パターン購読を利用すると、名前が一致する複数のチャネルをまとめて購読できます。

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPubSub;

public class PatternSubscribe {

public static void main(String[] args) {

Jedis jedis = null;

try {

/* Creating Jedis object for connecting with redis server */
jedis = new Jedis();

/* Creating JedisPubSub object for subscribing with channels */
JedisPubSub jedisPubSub = new JedisPubSub() {

@Override
public void onPMessage(String pattern, String channel, String message) {
System.out.println("Channel " +channel+ " has sent a message : " +message+ " on pattern " + pattern);
if(pattern.equals("C*")) {
/* Unsubscribe from pattern C* after first message is received. */
punsubscribe(pattern);
}
}

@Override
public void onPSubscribe(String pattern, int subscribedChannels) {
System.out.println("Client is Subscribed to pattern : "+ pattern);
System.out.println("Client is Subscribed to "+ subscribedChannels + " no. of patterns");
}

@Override
public void onPUnsubscribe(String pattern, int subscribedChannels) {
System.out.println("Client is Unsubscribed from pattern : "+ pattern);
System.out.println("Client is Subscribed to "+ subscribedChannels + " no. of patterns");
}

};

/* Subscribing to channel C1 and C2 */
jedis.psubscribe(jedisPubSub, "C*", "D?");

} catch(Exception ex) {

System.out.println("Exception : " + ex.getMessage());

} finally {

if(jedis != null) {
jedis.close();
}

}
}

}

実行結果

「PatternSubscribe」クラスを実行すると、以下のような出力が得られます。

JedisライブラリでRedisのPub/Subシステムを実装する方法【Javaサンプルコード付き】

パターンに一致するチャネルへのパブリッシュ

最後に、「PatternPublish」というクラスを作成します。このクラスはJedis接続経由でRedisサーバーに接続し、チャネルC13、D2、C134、D3にメッセージをパブリッシュします。

import redis.clients.jedis.Jedis;

public class PatternPublish {

public static void main(String[] args) {

Jedis jedis = null;

try {
/* Creating Jedis object for connecting with redis server */
jedis = new Jedis();

/* Publishing message to channel C13 */
jedis.publish("C13", "Message to channel C13");

/* Publishing message to channel D2 */
jedis.publish("D2", "Message to channel D2");

/* Publishing message to channel C134 */
jedis.publish("C134", "Message to channel C134");

/* Publishing message to channel D3 */
jedis.publish("D3", "Message to channel D3");

} catch(Exception ex) {

System.out.println("Exception : " + ex.getMessage());

} finally {

if(jedis != null) {
jedis.close();
}

}
}

}

実行結果

「PatternPublish」クラスを実行すると、PatternSubscribe側のコンソールには以下のように出力されます。

JedisライブラリでRedisのPub/Subシステムを実装する方法【Javaサンプルコード付き】

参考資料

  1. Redis公式ドキュメント:PUBSUBコマンド

以上が、Jedisライブラリを使用してRedisのPub/Subシステムを実装する方法の解説でした。この記事が役に立った場合は、ぜひコメント欄でご感想をお寄せいただき、他の方にもシェアしていただけると嬉しいです。

  1. Redis PUBLISHコマンドの使い方 – Pub/Subでメッセージを公開する方法を解説

    このチュートリアルでは、redis-cliを使ってRedisのメッセージブローカーシステムにメッセージを公開(パブリッシュ)する方法について解説します。 PUBLISHコマンドとは PUBLISHコマンドは、Redisのメッセージブローカーにおいて、指定したチャンネルへメッセージを配信するために使用されます。コマンドを実行すると、そのメッセージを受信したサブスクライバー(購読者)の数が戻り値として返されます。 Pub/Subモデルでは、パブリッシャーとサブスクライバーが直接やり取りするのではなく、チャンネルを介して疎結合な通信を行うため、リアルタイム通知やチャットアプリケーション、イベント駆動

  2. Redis SUBSCRIBEコマンド徹底解説 – Pub/Subで複数チャネルを同時に購読する方法

    本チュートリアルでは、redis-cliを使ってRedisのメッセージブローカー(Pub/Sub)システム上で、複数のチャネルを同時にサブスクライブ(購読)する方法を詳しく解説します。 SUBSCRIBEコマンドとは SUBSCRIBEコマンドは、クライアントをRedisメッセージブローカーシステム内の1つ以上の指定チャネルに登録するためのコマンドです。クライアントがSUBSCRIBEコマンドを実行すると「サブスクライブ状態」に入り、登録済みのチャネルを待ち受けます。他のクライアントが該当チャネルに対してPUBLISHコマンドでメッセージを発行すると、Redisはそのメッセージをすべての購読