前言
公司部署的Redis是使用的Cluster集群的方式,这种集群方式,每个节点都负责进行数据读写操作,每个节点之间会进行通信,更加高效的提供Redis的吞吐量。关于这种方式的更多介绍,可以阅读下面的文章 :
https://www.cnblogs.com/williamjie/p/11132211.html
我们系统中想实现一个发布订阅的模式,用来异步处理一些数据,所以搭一个demo来测试是否可用。
-
加入如下maven依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.9.0</version> </dependency>
-
创建两个消息监听类,分别用来监听不同的channel
import org.springframework.stereotype.Component; @Component public class BaoAnRedisMsgReceiver { public void onMessage(String msg) { System.out.println("深圳."+new String(msg)); } }
import org.springframework.stereotype.Component; @Component public class LongGangRedisMsgReceiver { public void onMessage(String msg) { System.out.println("深圳."+new String(msg)); } }
-
在yml文件中加入Redis的相关配置信息
redis: host: 127.0.0.1:7000,127.0.0.1:7001,127.0.0.1:7002,127.0.0.1:7003,127.0.0.1:7004,127.0.0.1:7005 password: timeout: 6000 # 连接超时时长(毫秒) jedis: pool: max-active: 1000 # 连接池最大连接数(使用负值表示没有限制) max-wait: -1 # 连接池最大阻塞等待时间(使用负值表示没有限制) max-idle: 10 # 连接池中的最大空闲连接 min-idle: 5 # 连接池中的最小空闲连接
-
Redis消息订阅配置类
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisClusterConfiguration;
import org.springframework.data.redis.connection.RedisNode;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisPoolConfig;
import java.util.HashSet;
import java.util.Set;
@Configuration
@ConditionalOnClass({JedisCluster.class})
public class RedisAutoConfiguration {
@Value("${redis.host}")
private String host;
@Value("${redis.password}")
private String password;
@Value("${redis.timeout}")
private int connectionTimeout;
@Value("${redis.jedis.pool.max-active}")
private int maxTotal;
@Value("${redis.jedis.pool.min-idle}")
private int minIdle;
@Value("${redis.jedis.pool.max-idle}")
private int maxIdle;
@Value("${redis.jedis.pool.max-wait}")
private int maxWaitMillis;
@Bean(name = "myRedisClusterConfiguration")
public RedisClusterConfiguration jedisCluster(){
RedisClusterConfiguration redisClusterConfiguration = new RedisClusterConfiguration();
String [] hosts = host.split(",");
Set<RedisNode> nodeList = new HashSet<RedisNode>();
for (String hostAndPort : hosts){
String [] hostOrPort = hostAndPort.split(":");
nodeList.add(new RedisNode(hostOrPort[0],Integer.parseInt(hostOrPort[1])));
}
redisClusterConfiguration.setClusterNodes(nodeList);
redisClusterConfiguration.setMaxRedirects(maxTotal);
return redisClusterConfiguration;
}
@Bean(name = "myJedisPoolConfig")
public JedisPoolConfig jedisPoolConfig(){
JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setMaxIdle(this.maxIdle);
poolConfig.setMinIdle(this.minIdle);
poolConfig.setTestOnCreate(true);
poolConfig.setTestOnBorrow(true);
poolConfig.setTestOnReturn(true);
poolConfig.setTestWhileIdle(true);
return poolConfig;
}
@Bean(name = "MyJedisConnectionFactory")
public JedisConnectionFactory getJedisConnectionFactory(@Qualifier("myRedisClusterConfiguration") RedisClusterConfiguration redisClusterConfiguration,
@Qualifier("myJedisPoolConfig") JedisPoolConfig jedisPoolConfig){
JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(redisClusterConfiguration, jedisPoolConfig);
// 判断密码是否存在,存在设置值
if (password != null) {
jedisConnectionFactory.setPassword(password);
}
return jedisConnectionFactory;
}
@Bean(name = "myRedisTemplates")
public RedisTemplate redisTemplate(@Qualifier("MyJedisConnectionFactory") JedisConnectionFactory jedisConnectionFactory){
StringRedisTemplate myRedisTemplate = new StringRedisTemplate();
myRedisTemplate.setConnectionFactory(jedisConnectionFactory);
return myRedisTemplate;
}
}
-
Redis消息订阅配置类
import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.cache.annotation.EnableCaching; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.listener.PatternTopic; import org.springframework.data.redis.listener.RedisMessageListenerContainer; import org.springframework.data.redis.listener.adapter.MessageListenerAdapter; @Configuration @EnableCaching public class RedisCacheConfig { @Bean RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory, @Qualifier("listenerAdapter1") MessageListenerAdapter listenerAdapter1, @Qualifier("listenerAdapter2") MessageListenerAdapter listenerAdapter2) { RedisMessageListenerContainer container = new RedisMessageListenerContainer(); container.setConnectionFactory(connectionFactory); // 可以添加多个 messageListener,配置不同的交换机 container.addMessageListener(listenerAdapter1, new PatternTopic("longGang")); container.addMessageListener(listenerAdapter2, new PatternTopic("luoHu")); return container; } @Bean(name = "listenerAdapter1") MessageListenerAdapter listenerAdapter(BaoAnRedisMsgReceiver receiver) { System.out.println("消息适配器1"); return new MessageListenerAdapter(receiver, "onMessage"); } @Bean(name = "listenerAdapter2") MessageListenerAdapter listenerAdapter2(LongGangRedisMsgReceiver receiver) { System.out.println("消息适配器2"); return new MessageListenerAdapter(receiver, "onMessage"); } }
-
写一个测试的Controller
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; @RequestMapping("/redis") @Controller public class RedisController { @Autowired StringRedisTemplate redisTemplate; /** * 发布消息 * * @param id * @return */ @RequestMapping("/sendMessage/{location}") public String sendMessage(@PathVariable String location) { if("longGang".equals(location)) { for(int i = 1; i <= 5; i++) { redisTemplate.convertAndSend("longGang", "龙岗是个好地方:"+i); } }else if("LuoHu".equals(location)){ for(int i = 1; i <= 5; i++) { redisTemplate.convertAndSend("LuoHu", "罗湖是个好地方:"+i); } } return ""; } }
-
启动项目,在浏览器上输入发布的请求路径 http://localhost:8080/redis/sendMessage/longGang,查看后台接收到的信息:
深圳.龙岗是个好地方:1 深圳.龙岗是个好地方:2 深圳.龙岗是个好地方:3 深圳.龙岗是个好地方:4 深圳.龙岗是个好地方:5