背景
在未引入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("

这篇博客介绍了在没有引入消息中间件如RocketMQ、Kafka时,如何利用Redis5的Stream特性封装一个消息工具包。内容包括消息体定义、生产者与消费者封装、Redis配置连接工具的创建,以及如何实际使用这些工具进行消息的生产和消费。重点讨论了消费者的竞争消费和广播消费模式。
最低0.47元/天 解锁文章
1257

被折叠的 条评论
为什么被折叠?



