iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >SpringBoot2如何整合Redis哨兵集群 实现消息队列场景
  • 691
分享到

SpringBoot2如何整合Redis哨兵集群 实现消息队列场景

2023-06-02 12:06:04 691人浏览 独家记忆
摘要

这篇文章主要介绍了SpringBoot2如何整合Redis哨兵集群 实现消息队列场景,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。一、Redis集群简介1、RedisClus

这篇文章主要介绍了SpringBoot2如何整合Redis哨兵集群 实现消息队列场景,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。

一、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模板类

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

三、模拟队列场景案例

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

1、加解锁工具

@Componentpublic 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();                        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)接口实现

@Componentpublic 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 {        @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、消息生产者

@Servicepublic 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、场景测试接口

@RestControllerpublic 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" ;    }}

感谢你能够认真阅读完这篇文章,希望小编分享的“SpringBoot2如何整合Redis哨兵集群 实现消息队列场景”这篇文章对大家有帮助,同时也希望大家多多支持编程网,关注编程网精选频道,更多相关知识等着你来学习!

--结束END--

本文标题: SpringBoot2如何整合Redis哨兵集群 实现消息队列场景

本文链接: https://www.lsjlt.com/news/230075.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作