前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >推荐一款基于Redis的高可用延迟队列

推荐一款基于Redis的高可用延迟队列

作者头像
小柒2012
发布2020-02-18 21:46:45
1.5K0
发布2020-02-18 21:46:45
举报
文章被收录于专栏:IT笔记IT笔记

前言

之前给大家推荐的几款延迟任务处理队列,对于一些要求比较高的场景是无法运用于生产环境的,一旦机器宕机或者应用重启会导致队列消息丢失,从而造成无法挽回的损失。今天给大家分享一款高可用延迟队列 Redisson

简介

Redisson 在基于 NIONetty 框架上,充分利用了 Redis 键值数据库提供的一系列优势,在 Java 实用工具包中常用接口的基础上,为使用者提供了一系列具有分布式特性的常用工具类。使得原本作为协调单机多线程并发程序的工具包获得了协调分布式多机多线程并发系统的能力,大大降低了设计和研发大规模分布式系统的难度。同时结合各富特色的分布式服务,更进一步简化了分布式环境中程序相互之间的协作。

代码案例

框架支持多种 redis 集成部署方式,包括单节点,主从模式,集群模式,哨兵模式等等。

项目 pom.xml 引入:

代码语言:javascript
复制
<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson</artifactId>
    <version>3.12.1</version>
</dependency>

定义红包信息实体类,必须实现序列并定义空构造方法:

代码语言:javascript
复制
/**
 * 红包信息
 */
public class RedPacketMessage implements Serializable {

    /**
     * 红包 ID
     */
    private  long redPacketId;

    /**
     * 创建时间戳
     */
    private  long timestamp;

    public RedPacketMessage() {

    }

    public RedPacketMessage(long redPacketId) {
        this.redPacketId = redPacketId;
        this.timestamp = System.currentTimeMillis();
    }

    public long getRedPacketId() {
        return redPacketId;
    }

    public long getTimestamp() {
        return timestamp;
    }

}

代码案例:

代码语言:javascript
复制
/**
 * 红包过期失效 高可用延迟队列
 */
public class RedPacketDelayQueue {

    private static final Logger LOGGER = LoggerFactory.getLogger(RedPacketDelayQueue.class);

    public static void main(String[] args) throws Exception {
        Config config = new Config();
        config.useSingleServer().setAddress("redis://127.0.0.1:6379").setPassword("123456").setDatabase(2);
        RedissonClient redissonClient = Redisson.create(config);
        /**
         * 红包目标队列
         */
        RBlockingQueue<RedPacketMessage> blockingRedPacketQueue
                = redissonClient.getBlockingQueue("redPacketDelayQueue");
        /**
         * 定时任务将到期的元素转移到目标队列
         */
        RDelayedQueue<RedPacketMessage> delayedRedPacketQueue
                = redissonClient.getDelayedQueue(blockingRedPacketQueue);

        /**
         * 延时信息入队列
         */
        delayedRedPacketQueue.offer(new RedPacketMessage(20200113), 3, TimeUnit.SECONDS);
        delayedRedPacketQueue.offer(new RedPacketMessage(20200114), 5, TimeUnit.SECONDS);
        delayedRedPacketQueue.offer(new RedPacketMessage(20200115), 10, TimeUnit.SECONDS);
        while (true){
            /**
             * 取出失效红包
             */
            RedPacketMessage redPacket = blockingRedPacketQueue.take();
            LOGGER.info("红包ID:{}过期失效",redPacket.getRedPacketId());
            /**
             * 处理相关业务逻辑:记录相关信息并退还剩余红包金额
             */
        }
    }
}

高可用

主从部署方式:

代码语言:javascript
复制
/**
 * 主从部署方式
 */
Config config = new Config();
config.useMasterSlaveServers()
        //设置redis主节点
        .setMasterAddress("redis://192.168.1.120:6379")
        //设置redis从节点
        .addSlaveAddress("redis://192.168.1.130:6379", "redis://192.168.1.140:6379");
RedissonClient redisson = Redisson.create(config);

集群部署方式:

代码语言:javascript
复制
/**
 * 集群部署方式
 * cluster方式至少6个节点
 * 3主3从,3主做sharding,3从用来保证主宕机后可以高可用
 */
Config config = new Config();
config.useClusterServers()
        .setScanInterval(2000)//集群状态扫描间隔时间,单位是毫秒
        .addNodeAddress("redis://192.168.1.120:6379")
        .addNodeAddress("redis://192.168.1.130:6379")
        .addNodeAddress("redis://192.168.1.140:6379")
        .addNodeAddress("redis://192.168.1.150:6379")
        .addNodeAddress("redis://192.168.1.160:6379")
        .addNodeAddress("redis://192.168.1.170:6379");
RedissonClient redissonClient = Redisson.create(config);

哨兵部署方式:

代码语言:javascript
复制
/**
 * 哨兵部署方式
 * sentinel是采用 Paxos拜占庭协议,一般sentinel至少3个节点
 */
Config config = new Config();
config.useSentinelServers()
        .setMasterName("my-sentinel-name")
        .addSentinelAddress("redis://192.168.1.120:6379")
        .addSentinelAddress("redis://192.168.1.130:6379")
        .addSentinelAddress("redis://192.168.1.140:6379");
RedissonClient redisson = Redisson.create(config);

云托管部署方式:

代码语言:javascript
复制
/**
 * 云托管部署方式
 * 这种方式主要解决redis提供商为云服务的提供商的redis连接
 * 比如亚马逊云、微软云
 */
config.useReplicatedServers()
        //主节点变化扫描间隔时间
        .setScanInterval(2000)
        .addNodeAddress("redis://192.168.1.120:6379")
        .addNodeAddress("redis://192.168.1.130:6379")
        .addNodeAddress("redis://192.168.1.140:6379");
RedissonClient redisson = Redisson.create(config);

小结

无论是JDK内置的延迟队列还是基于时间轮算法的队列,都无法保证生产系统的高可用性,而Redisson很好的解决了这个问题。

源码

https://gitee.com/52itstyle/spring-boot-seckill

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-02-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 简介
  • 代码案例
  • 高可用
  • 小结
  • 源码
相关产品与服务
云数据库 Redis
腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档