Redis 实现高可用延迟队列


前言:

  用过的延迟任务处理队列(RocketMQ、KafKa、Redisson等),对于一些要求比较高的场景是无法运用于生产环境的,一旦机器宕机或者应用重启会导致队列消息丢失,从而造成无法挽回的损失。

Redisson

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

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

示例:

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



    org.redisson
    redisson
    3.12.1

  创建消息类:

**
 * 消息类
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class Message implements Serializable {

    /**
     * 消息ID
     */
    private  long messageId;

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

 定义延迟队列:

/**
*延迟处理队列设计
**/
@Slf4J
public class MessageDelayQueue {

    public static void main(String[] args) throws Exception {
        Config config = new Config();
        config.useSingleServer().setAddress("redis://127.0.0.1:6379").setPassword("123123").setDatabase(5);
        RedissonClient redissonClient = Redisson.create(config);
        /**
         * 目标队列
         */
        RBlockingQueue messageQuene = redissonClient.getBlockingQueue("messageDelayQuene");
        /**
         * 定时任务将到期的元素转移到目标队列
         */
        RDelayedQueue delayedRQueue
                = redissonClient.getDelayedQueue(messageQuene);

        /**
         * 延时信息入队列
         */
        delayedRQueue.offer(new Message(20200113), 3, TimeUnit.SECONDS);
        delayedRQueue.offer(new Message(20200114), 5, TimeUnit.SECONDS);
        delayedRQueue.offer(new Message(20200115), 10, TimeUnit.SECONDS);
        while (true){
            /**
             * poll 消息
             */
            Message msg = messageQuene.take();
            log.info("messageID:{}过期失效",msg .getMessageId());
            /**
             * 处理相关业务逻辑:
             */
        }
    }
}

高可用配置:

 1.主从

/**
 * 主从部署方式
 */
Config config = new Config();
config.useMasterSlaveServers()
        //设置redis主节点
        .setMasterAddress("redis://192.168.1.12:6379")
        //设置redis从节点
        .addSlaveAddress("redis://192.168.1.13:6379", "redis://192.168.1.14:6379");
RedissonClient redisson = Redisson.create(config);

 2.集群

**
 * 集群部署方式
 * cluster方式至少6个节点
 * 3主3从,3主做sharding,3从用来保证主宕机后可以高可用
 */
Config config = new Config();
config.useClusterServers()
        .setScanInterval(2000)//集群状态扫描间隔时间,单位是毫秒
        .addNodeAddress("redis://192.168.1.12:6379")
        .addNodeAddress("redis://192.168.1.13:6379")
        .addNodeAddress("redis://192.168.1.14:6379")
        .addNodeAddress("redis://192.168.1.15:6379")
        .addNodeAddress("redis://192.168.1.16:6379")
        .addNodeAddress("redis://192.168.1.17:6379");
RedissonClient redissonClient = Redisson.create(config);

 3.哨兵 

/**
 * 哨兵部署方式
 * sentinel是采用 Paxos拜占庭协议,一般sentinel至少保证3个节点
 */
Config config = new Config();
config.useSentinelServers()
        .setMasterName("my-sentinel-name")
        .addSentinelAddress("redis://192.168.1.12:6379")
        .addSentinelAddress("redis://192.168.1.13:6379")
        .addSentinelAddress("redis://192.168.1.14:6379");
RedissonClient redisson = Redisson.create(config);

 4.云节点

 

/**
 * 云托管部署方式
 * 这种方式主要解决redis提供商为云服务的提供商的redis连接
 * 比如亚马逊云、微软云
 */
Config config = new Config();
config.useReplicatedServers()
        //主节点变化扫描间隔时间
        .setScanInterval(2000)
        .addNodeAddress("redis://192.168.1.12:6379")
        .addNodeAddress("redis://192.168.1.13:6379")
        .addNodeAddress("redis://192.168.1.14:6379");
RedissonClient redisson = Redisson.create(config);

 


 

你可能感兴趣的:(Java,Redis)