The most user-friendly and subscribe to publish the code Redis combat

Introduction to publish subscribe

In addition to using the List function to achieve a simple message queue outside, Redis also provides a mechanism for publishing news subscription. In this mechanism, the publisher released a message to the specified channel (channel) message, which subscribers can receive the message the specified channel, with a channel can have multiple messages subscribers, as shown below:

Here Insert Picture Description

Redis command also provides some support for this mechanism, then we explain in detail these commands.

Subscribe to publish relevant command

In Redis, the publish-subscribe-related commands are:

  1. make an announcement
  2. Subscriptions
  3. unsubscribe
  4. In accordance with the mode subscription
  5. According to unsubscribe mode
  6. Query subscription information

make an announcement

Command announced that publishthe syntax is:

publish 频道名称 消息

For example, want to channel: one-more-study: demo channel with an announcement. "I am One More Study.", The command is as follows:

> publish channel:one-more-study:demo "I am One More Study."
(integer) 0

Returns the result of the number of subscribers, the subscribers embodiment does not, the result is returned to zero.

Subscribe to news

Subscribe command message is subscribe, subscribers can subscribe to one or more channels, the syntax is:

subscribe 频道名称 [频道名称 ...]

For example, subscribe to a channel: one-more-study: demo channel, the command is as follows:

> subscribe channel:one-more-study:demo
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "channel:one-more-study:demo"
3) (integer) 1

Return result there are three, respectively: the return type of the value (subscription success), subscribe to the channel name, channel number has been subscribed. When a subscriber receives a message, it will show:

1) "message"
2) "channel:one-more-study:demo"
3) "I am One More Study."

3 is also a result, each represents: the type (information) return value, channel name, source, and message content.

Subscribers newly opened, is unable to receive the message before the history of the channel, because of the persistence Redis did not make the news release.

unsubscribe

Unsubscribe command unsubscribe, you can cancel your subscription to one or more channels, the syntax is:

unsubscribe [频道名称 [频道名称 ...]]

For example, unsubscribe channel: one-more-study: demo channel, the command is as follows:

> unsubscribe channel:one-more-study:demo
1) "unsubscribe"
2) "channel:one-more-study:demo"
3) (integer) 0

Return result there are three, respectively: the return type of the value (unsubscribe success), cancel the subscription channel name, channel number has been subscribed.

Press the Mode subscription message

Press the Mode command subscribe message is psubscribe, subscribe to one or more channels that match a given pattern, the syntax is:

psubscribe 模式 [模式 ...]

* Each mode as a sign, such as channel * matches all channels beginning with channel command is as follows:

> psubscribe channel:*
Reading messages... (press Ctrl-C to quit)
1) "psubscribe"
2) "channel*"
3) (integer) 1

Return result there are three, respectively: the return type of the value (press mode subscription is successful), the subscription model number has been subscribed mode. When a subscriber receives a message, it will show:

1) "pmessage"
2) "channel*"
3) "channel:one-more-study:demo"
4) "I am One More Study."

4 have returned results, respectively: the type (information) return value, pattern matching message, channel name, source, and message content.

Press the Mode unsubscribe

Press the Mode unsubscribe command punsubscribe, you can cancel your subscription to one or more patterns, the syntax is:

punsubscribe [模式 [模式 ...]]

* Each mode as a sign, such as channel: * matches all channels beginning with channel command is as follows:

1> punsubscribe channel:*
1) "punsubscribe"
2) "channel:*"
3) (integer) 0

Return result there are three, respectively: the number of the return type of the value (according to model unsubscribe success), cancel the subscription model, it has a subscription model.

Query subscription information

View active channel

Active channel means having at least one subscriber channel, the syntax is:

pubsub channels [模式]

such as:

> pubsub channels
1) "channel:one-more-study:test"
2) "channel:one-more-study:demo"
3) "channel:demo"
> pubsub channels *demo
1) "channel:one-more-study:demo"
2) "channel:demo"
> pubsub channels *one-more-study*
1) "channel:one-more-study:test"
2) "channel:one-more-study:demo"
View Channel subscriptions
pubsub numsub [频道名称 ...]

such as:

> pubsub numsub channel:one-more-study:demo
1) "channel:one-more-study:demo"
2) (integer) 1
View mode subscriptions
> pubsub numpat
(integer) 1

Code combat

Handle and a spout lip off, we use the Java language to write a simple publish-subscribe example.

Jedis cluster example

Jedis are Redis official recommended Java development tools connection, we use the Jedis write a simple cluster example.

package onemore.study;

import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisPoolConfig;

import java.util.HashSet;
import java.util.Set;

/**
 * Jedis集群
 *
 * @author 万猫学社
 */
public enum Cluster {
    INSTANCE;

    //为了简单,把IP和端口直接写在这里,实际开发中写在配置文件会更好。
    private final String hostAndPorts = "192.168.0.60:6379;192.168.0.61:6379;192.168.0.62:6379";
    private JedisCluster jedisCluster;

    Cluster() {
        JedisPoolConfig poolConfig = new JedisPoolConfig();

        //最大连接数
        poolConfig.setMaxTotal(20);
        //最大空闲数
        poolConfig.setMaxIdle(10);
        //最小空闲数
        poolConfig.setMinIdle(2);

        //从jedis连接池获取连接时,校验并返回可用的连接
        poolConfig.setTestOnBorrow(true);
        //把连接放回jedis连接池时,校验并返回可用的连接
        poolConfig.setTestOnReturn(true);

        Set<HostAndPort> nodes = new HashSet<>();
        String[] hosts = hostAndPorts.split(";");
        for (String hostport : hosts) {
            String[] ipport = hostport.split(":");
            String ip = ipport[0];
            int port = Integer.parseInt(ipport[1]);
            nodes.add(new HostAndPort(ip, port));
        }
        jedisCluster = new JedisCluster(nodes, 1000, poolConfig);
    }

    public JedisCluster getJedisCluster() {
        return jedisCluster;
    }
}

Posted by example

package onemore.study;

import redis.clients.jedis.JedisCluster;

/**
 * 发布者
 *
 * @author 万猫学社
 */
public class Publisher implements Runnable {
    private final String CHANNEL_NAME = "channel:one-more-study:demo";
    private final String QUIT_COMMAND = "quit";

    @Override
    public void run() {
        JedisCluster jedisCluster = Cluster.INSTANCE.getJedisCluster();
        for (int i = 1; i <= 3; i++) {
            String message = "第" + i + "消息";
            System.out.println(Thread.currentThread().getName() + " 发布:" + message);
            jedisCluster.publish(CHANNEL_NAME, message);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("------------------");
        }
        jedisCluster.publish(CHANNEL_NAME, QUIT_COMMAND);
    }
}

Subscribers example

package onemore.study;

import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisPubSub;

/**
 * 订阅者
 *
 * @author 万猫学社
 */
public class Subscriber implements Runnable {
    private final String CHANNEL_NAME = "channel:one-more-study:demo";
    private final String QUIT_COMMAND = "quit";

    private final JedisPubSub jedisPubSub = new JedisPubSub() {
        @Override
        public void onMessage(String channel, String message) {
            System.out.println(Thread.currentThread().getName() + " 接收:" + message);
            if (QUIT_COMMAND.equals(message)) {
                unsubscribe(CHANNEL_NAME);
            }
        }
    };

    @Override
    public void run() {
        JedisCluster jedisCluster = Cluster.INSTANCE.getJedisCluster();
        jedisCluster.subscribe(jedisPubSub, CHANNEL_NAME);
    }
}

Comprehensive example

package onemore.study;

public class App {
    public static void main(String[] args) throws InterruptedException {
        //创建3个订阅者
        new Thread(new Subscriber()).start();
        new Thread(new Subscriber()).start();
        new Thread(new Subscriber()).start();
        Thread.sleep(1000);

        //创建发布者
        new Thread(new Publisher()).start();
    }
}

Results are as follows:

Thread-6 发布:第1消息
Thread-0 接收:第1消息
Thread-1 接收:第1消息
Thread-2 接收:第1消息
------------------
Thread-6 发布:第2消息
Thread-0 接收:第2消息
Thread-1 接收:第2消息
Thread-2 接收:第2消息
------------------
Thread-6 发布:第3消息
Thread-0 接收:第3消息
Thread-2 接收:第3消息
Thread-1 接收:第3消息
------------------
Thread-0 接收:quit
Thread-1 接收:quit
Thread-2 接收:quit
Published 53 original articles · won praise 1316 · Views 200,000 +

Guess you like

Origin blog.csdn.net/heihaozi/article/details/105155596