本文源码:GitHub·点这里 || GitEE·点这里

一、Redis集群简介

1、RedisCluster概念

Redis的分布式解决方案,在3.0版本后推出的方案,有效地解决了Redis分布式的需求,当一个服务宕机可以快速的切换到另外一个服务。redis cluster主要是针对海量数据+高并发+高可用的场景。

二、与SpringBoot2.0整合

1、核心依赖

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>${spring-boot.version}</version>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>${redis-client.version}</version>
</dependency>

2、核心配置

spring:
# Redis 集群
redis:
sentinel:
# sentinel 配置
master: mymaster
nodes: 192.168.0.127:26379
maxTotal: 60
minIdle: 10
maxWaitMillis: 10000
testWhileIdle: true
testOnBorrow: true
testOnReturn: false
timeBetweenEvictionRunsMillis: 10000

3、参数渲染类

@ConfigurationProperties(prefix = "spring.redis.sentinel")
public class RedisParam {
private String nodes ;
private String master ;
private Integer maxTotal ;
private Integer minIdle ;
private Integer maxWaitMillis ;
private Integer timeBetweenEvictionRunsMillis ;
private boolean testWhileIdle ;
private boolean testOnBorrow ;
private boolean testOnReturn ;
// 省略GET和SET方法
}

4、集群配置文件

@Configuration
@EnableConfigurationProperties(RedisParam.class)
public class RedisPool {
@Resource
private RedisParam redisParam ;
@Bean("jedisSentinelPool")
public JedisSentinelPool getRedisPool (){
Set<String> sentinels = new HashSet<>();
sentinels.addAll(Arrays.asList(redisParam.getNodes().split(",")));
GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
poolConfig.setMaxTotal(redisParam.getMaxTotal());
poolConfig.setMinIdle(redisParam.getMinIdle());
poolConfig.setMaxWaitMillis(redisParam.getMaxWaitMillis());
poolConfig.setTestWhileIdle(redisParam.isTestWhileIdle());
poolConfig.setTestOnBorrow(redisParam.isTestOnBorrow());
poolConfig.setTestOnReturn(redisParam.isTestOnReturn());
poolConfig.setTimeBetweenEvictionRunsMillis(redisParam.getTimeBetweenEvictionRunsMillis());
JedisSentinelPool redisPool = new JedisSentinelPool(redisParam.getMaster(), sentinels, poolConfig);
return redisPool;
}
@Bean
SpringUtil springUtil() {
return new SpringUtil();
}
@Bean
RedisListener redisListener() {
return new RedisListener();
}
}

5、配置Redis模板类

@Configuration
public class RedisConfig {
@Bean
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory factory) {
StringRedisTemplate stringRedisTemplate = new StringRedisTemplate();
stringRedisTemplate.setConnectionFactory(factory);
return stringRedisTemplate;
}
}

三、模拟队列场景案例

生产者消费者模式:客户端监听消息队列,消息达到,消费者马上消费,如果消息队列里面没有消息,那么消费者就继续监听。基于Redis的LPUSH(BLPUSH)把消息入队,用 RPOP(BRPOP)获取消息的模式。

1、加锁解锁工具

@Component
public class RedisLock {
private static String keyPrefix = "RedisLock:";
@Resource
private JedisSentinelPool jedisSentinelPool;
public boolean addLock(String key, long expire) {
Jedis jedis = null;
try {
jedis = jedisSentinelPool.getResource();
/*
* nxxx的值只能取NX或者XX,如果取NX,则只有当key不存在是才进行set,如果取XX,则只有当key已经存在时才进行set
* expx的值只能取EX或者PX,代表数据过期时间的单位,EX代表秒,PX代表毫秒。
*/
String value = jedis.set(keyPrefix + key, "1", "nx", "ex", expire);
return value != null;
} catch (Exception e){
e.printStackTrace();
}finally {
if (jedis != null) jedis.close();
}
return false;
}
public void removeLock(String key) {
Jedis jedis = null;
try {
jedis = jedisSentinelPool.getResource();
jedis.del(keyPrefix + key);
} finally {
if (jedis != null) jedis.close();
}
}
}

2、消息消费

1)封装接口

public interface RedisHandler  {
/**
* 队列名称
*/
String queueName(); /**
* 队列消息内容
*/
String consume (String msgBody);
}

2)接口实现

@Component
public class LogAListen implements RedisHandler {
private static final Logger LOG = LoggerFactory.getLogger(LogAListen.class) ;
@Resource
private RedisLock redisLock;
@Override
public String queueName() {
return "LogA-key";
}
@Override
public String consume(String msgBody) {
// 加锁,防止消息重复投递
String lockKey = "lock-order-uuid-A";
boolean lock = false;
try {
lock = redisLock.addLock(lockKey, 60);
if (!lock) {
return "success";
}
LOG.info("LogA-key == >>" + msgBody);
} catch (Exception e){
e.printStackTrace();
} finally {
if (lock) {
redisLock.removeLock(lockKey);
}
}
return "success";
}
}

3、消息监听器

public class RedisListener implements InitializingBean {
/**
* Redis 集群
*/
@Resource
private JedisSentinelPool jedisSentinelPool;
private List<RedisHandler> handlers = null;
private ExecutorService product = null;
private ExecutorService consumer = null;
/**
* 初始化配置
*/
@Override
public void afterPropertiesSet() {
handlers = SpringUtil.getBeans(RedisHandler.class) ;
product = new ThreadPoolExecutor(10,15,60 * 3,
TimeUnit.SECONDS,new SynchronousQueue<>());
consumer = new ThreadPoolExecutor(10,15,60 * 3,
TimeUnit.SECONDS,new SynchronousQueue<>());
for (RedisHandler redisHandler : handlers){
product.execute(() -> {
redisTask(redisHandler);
});
}
}
/**
* 队列监听
*/
public void redisTask (RedisHandler redisHandler){
Jedis jedis = null ;
while (true){
try {
jedis = jedisSentinelPool.getResource() ;
List<String> msgBodyList = jedis.brpop(0, redisHandler.queueName());
if (msgBodyList != null && msgBodyList.size()>0){
consumer.execute(() -> {
redisHandler.consume(msgBodyList.get(1)) ;
});
}
} catch (Exception e){
e.printStackTrace();
} finally {
if (jedis != null) jedis.close();
}
}
}
}

4、消息生产者

@Service
public class RedisServiceImpl implements RedisService {
@Resource
private JedisSentinelPool jedisSentinelPool;
@Override
public void saveQueue(String queueKey, String msgBody) {
Jedis jedis = null;
try {
jedis = jedisSentinelPool.getResource();
jedis.lpush(queueKey,msgBody) ;
} catch (Exception e){
e.printStackTrace();
} finally {
if (jedis != null) jedis.close();
}
}
}

5、场景测试接口

@RestController
public class RedisController {
@Resource
private RedisService redisService ;
/**
* 队列推消息
*/
@RequestMapping("/saveQueue")
public String saveQueue (){
MsgBody msgBody = new MsgBody() ;
msgBody.setName("LogAModel");
msgBody.setDesc("描述");
msgBody.setCreateTime(new Date());
redisService.saveQueue("LogA-key", JSONObject.toJSONString(msgBody));
return "success" ;
}
}

四、源代码地址

GitHub地址:知了一笑
https://github.com/cicadasmile/middle-ware-parent
码云地址:知了一笑
https://gitee.com/cicadasmile/middle-ware-parent

SpringBoot2.0 整合 Redis集群 ,实现消息队列场景的更多相关文章

  1. (七)整合 Redis集群 ,实现消息队列场景

    整合 Redis集群 ,实现消息队列场景 1.Redis集群简介 1.1 RedisCluster概念 2.SpringBoot整合Redis集群 2.1 核心依赖 2.2 核心配置 2.3 参数渲染 ...

  2. Springboot2.0访问Redis集群

    Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作高性能的key-value数据库.缓存和消息中间件,掌握它是程序员的必备技能,下面是一个springboot访问redis的 ...

  3. springboot2.x 整合redis集群的几种方式

    一.不指定redis连接池 #系统默认连接池 yml配置文件: spring: redis: cluster: nodes: - 192.168.1.236:7001 - 192.168.1.236: ...

  4. Springboot2.x集成Redis集群模式

    Springboot2.x集成Redis集群模式 说明 Redis集群模式是Redis高可用方案的一种实现方式,通过集群模式可以实现Redis数据多处存储,以及自动的故障转移.如果想了解更多集群模式的 ...

  5. SpringBoot整合Redis集群

    一.环境搭建 Redis集群环境搭建:https://www.cnblogs.com/zwcry/p/9174233.html 二.Spring整合Redis集群 1.pom.xml <proj ...

  6. Spring Boot2.0之 整合Redis集群

    项目目录结构: pom: <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http:// ...

  7. 05.haproxy+mysql负载均衡 整合 redis集群+ssm

    本篇重点讲解haproxy+mysql负载均衡,搭建完成后与之前搭建的redis+ssm进行整合 (注:这里用到了两台mysql数据库,分别安装两台虚拟机上,已经成功实现主主复制,如果有需要,请查看我 ...

  8. centos7.0 安装redis集群

    生产环境下redis基本上都是用的集群,毕竟单机版随时都可能挂掉,风险太大.这里我就来搭建一个基本的redis集群,功能够用但是还需要完善,当然如果有钱可以去阿里云买云数据库Redis版的,那个还是很 ...

  9. Redis(七)-- SpringMVC整合Redis集群

    1.pom.xml <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www ...

随机推荐

  1. django基础之day09,Forms组件在程序中做了哪些事? 校验数据、渲染标签、展示信息

    ******************************* Forms组件 *************************************************** Forms组件在 ...

  2. TypeScript引入moment.js报错“无法找到moment模块”及解决方法

    npm i moment下载moment完成后,在ts文件中引入 import * as moment from "moment"; 结果疯狂报错,未找到moment模块. 一开始 ...

  3. 【iOS bug记录】UICollectionviewCell刷新变得这么莫名其妙?

    项目是一个即时聊天的社交软件,聊天流采用的是UICollectionView,随着进度的完善,发现一个特别的bug,UICollectionviewCell的复用,并没有直接insert进去,而是出现 ...

  4. 使用百度大脑iOCR,快速自定义机票行程单模板识别

    1. 功能介绍百度已经推出了iOCR财会票据识别,针对财会报销场景提出的专项解决方案,可对各类财务票据.报销单.银行回单.对账单进行自动分类及结构化识别,并支持用户为固定版式的新票据/单据自定义结构化 ...

  5. Mysql—mysqladmin 命令详解

    mysqladmin是一个执行管理操作的客户端程序.它可以用来检查服务器的配置和当前状态.创建和删除数据库等. mysqladmin工具的使用格式:mysqladmin [option] comman ...

  6. centos基本信息和ssh

    CentOs系统基本配置,包括修改主机名,创建用户并授权,ssh免密登录 1 永久修改主机名 sudo vim /etc/hostname 把原主机名xxx改为master(在从主机上则改为相应的sl ...

  7. 关于svn外网访问的问题-搭建成功

    昨天聊到了svn外网问题.今天,无限查资料,虽然眼累了一些,不过最终实现.还是开心了一下! 背景:本机设置svn服务器,搭建代码库并开设外网 供不再同一地点的他人来访问 上图: 1.svn服务器端 搭 ...

  8. 13-Node.js学习笔记-MongoDB

    数据库相关概念 在一个数据库软件最终可以包含多个数据仓库,在每个数据仓库中可以包含多个数据集合,每个数据集合中可以包含多条文档(具体的数据) database: 数据库,mongoDB数据库软件中可以 ...

  9. IoT缺德相关

    https://github.com/nebgnahz/awesome-iot-hacks <揭秘家用路由器0day漏洞挖掘技术> Embedded Device Security: Pw ...

  10. 使用SC命令操作(安装、开启、配置、关闭、删除)Windows下的服务

    目录 一.直接使用cmd命令行操作windows服务 二.使用bat批处理-操作windows服务 一.直接使用cmd命令行操作windows服务 1.安装服务 sc create 服务名 binPa ...