redis5 stream消息机制java封装实现

这篇博客介绍了在没有引入消息中间件如RocketMQ、Kafka时,如何利用Redis5的Stream特性封装一个消息工具包。内容包括消息体定义、生产者与消费者封装、Redis配置连接工具的创建,以及如何实际使用这些工具进行消息的生产和消费。重点讨论了消费者的竞争消费和广播消费模式。
摘要由CSDN通过智能技术生成

背景

在未引入rocketMq,kafka等消息中间件的情况下,如何用redis实现消息机制,就此封装了一个redis消息工具包。


一、前期准备

需要引入二方包

      <dependency>
        <groupId>redis.clients</groupId>
        <artifactId>jedis</artifactId>
        <version>3.6.3</version>
      </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.12.0</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.79</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-redis</artifactId>
            <version>2.6.0</version>
        </dependency>
    </dependencies>

二、消息工具包中的代码

1.定义消息体等基本对象

TkMessage 消息体

public class TkMessage extends AbstractEntry {
    /**
     * 组,topic
     */
    private GroupTopicEnum groupTopic;
    /**
     * 消息标签
     */
    private String tag;
    /**
     * 自定义key,用于去重
     */
    private String key;
    /**
     * 消息体
     */
    private String content;

    public GroupTopicEnum getGroupTopic() {
        return groupTopic;
    }

    public void setGroupTopic(GroupTopicEnum groupTopic) {
        this.groupTopic = groupTopic;
    }

    public String getTag() {
        return tag;
    }

    public void setTag(String tag) {
        this.tag = tag;
    }

    public String getKey() {
        return key;
    }

    public void setKey(String key) {
        this.key = key;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public static Builder create() {
        return new Builder();
    }

    public static class Builder {
        /**
         * 组,topic
         */
        private GroupTopicEnum groupTopic;
        /**
         * 消息标签
         */
        private String tag;
        /**
         * 自定义key,用于去重
         */
        private String key;
        /**
         * 消息体
         */
        private String content;

        public TkMessage build() {
            TkMessage message = new TkMessage();
            message.setGroupTopic(this.groupTopic);
            message.setTag(this.tag);
            message.setKey(this.key);
            message.setContent(this.content);
            return message;
        }

        public Builder setGroupTopic(GroupTopicEnum groupTopic) {
            this.groupTopic = groupTopic;
            return this;
        }

        public Builder setTag(String tag) {
            this.tag = tag;
            return this;
        }

        public Builder setKey(String key) {
            this.key = key;
            return this;
        }

        public Builder setContent(String content) {
            this.content = content;
            return this;
        }

        public GroupTopicEnum getGroupTopic() {
            return groupTopic;
        }

        public String getTag() {
            return tag;
        }

        public String getKey() {
            return key;
        }

        public String getContent() {
            return content;
        }
    }
}

AbstractEntry

public class AbstractEntry implements Serializable {
    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
    }
}

GroupTopicEnum

public class GroupTopicEnum extends AbstractEntry {
    /**
     * 组
     */
    private String group;
    /**
     * TOPIC
     */
    private String topic;

    public GroupTopicEnum() {
    }

    public GroupTopicEnum(String group, String topic) {
        this.group = group;
        this.topic = topic;
    }

    public String getGroup() {
        return group;
    }

    public void setGroup(String group) {
        this.group = group;
    }

    public String getTopic() {
        return topic;
    }

    public void setTopic(String topic) {
        this.topic = topic;
    }

    public boolean equals(GroupTopicEnum obj) {
        boolean r = super.equals(obj);
        if (!r) {
            r = this.group.equals(obj.getGroup()) && this.topic.equals(obj.getTopic());
        }
        return r;
    }
}

2、消息生产者封装

MessageProducer

package io.shulie.jmeter.tool.redis.message;

import io.shulie.jmeter.tool.redis.RedisConfig;
import io.shulie.jmeter.tool.redis.domain.TkMessage;
import io.shulie.jmeter.tool.redis.util.JsonUtil;
import io.shulie.jmeter.tool.redis.util.MessageUtil;
import io.shulie.jmeter.tool.redis.util.RedisUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.stream.*;
import org.springframework.data.redis.core.StringRedisTemplate;

import java.util.*;


/**
 * @Author: liyuanba
 * @Date: 2022/1/24 4:54 下午
 */
public class MessageProducer {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    private static final Map<Object, MessageProducer> producerMap = new HashMap<>();
    private StringRedisTemplate stringRedisTemplate;

    public static MessageProducer getInstance(RedisConfig redisConfig) {
        if (null == redisConfig) {
            return null;
        }
        MessageProducer producer = producerMap.get(redisConfig);
        if (null == producer) {
            producer = new MessageProducer();
            producer.init(redisConfig);
            producerMap.put(redisConfig, producer);
        }
        return producer;
    }

    public static MessageProducer getInstance(RedisConnectionFactory factory) {
        if (null == factory) {
            return null;
        }
        MessageProducer producer = producerMap.get(factory);
        if (null == producer) {
            producer = new MessageProducer();
            producer.init(factory);
            producerMap.put(factory, producer);
        }
        return producer;
    }

    public static MessageProducer getInstance(StringRedisTemplate stringRedisTemplate) {
        if (null == stringRedisTemplate) {
            return null;
        }
        MessageProducer producer = producerMap.get(stringRedisTemplate);
        if (null == producer) {
            producer = new MessageProducer();
            producer.setStringRedisTemplate(stringRedisTemplate);
            producerMap.put(stringRedisTemplate, producer);
        }
        return producer;
    }

    public boolean send(TkMessage message) throws Exception {
        if (null == message) {
            return false;
        }
        if (null == message.getGroupTopic()) {
            throw new Exception("message groupTopicTag is null!");
        }
        String streamKey = MessageUtil.buildRedisMessageStreamKey(message.getGroupTopic());

        // 创建消息记录, 以及指定stream
        StringRecord stringRecord = StreamRecords.string(Collections.singletonMap("value", JsonUtil.toJson(message))).withStreamKey(streamKey);
        // 将消息添加至消息队列中
        RecordId rec
  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值