在Spring Cloud微服务架构中,基于Redisson实现分布式调度任务的选主和心跳监听,可以通过以下完整方案实现。该方案结合了Redisson的分布式锁和发布/订阅功能,确保高可靠性和实时性:


一、整体架构设计

graph TD
A[微服务实例1] -->|竞争锁| B(Redisson)
C[微服务实例2] -->|竞争锁| B
D[微服务实例3] -->|竞争锁| B
B -->|心跳事件| E[Redis Pub/Sub]
E --> A
E --> C
E --> D

二、核心实现步骤

1. 添加依赖

<!-- Redisson Starter -->
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
<version>3.23.2</version>
</dependency>

2. 选主服务实现

import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.concurrent.TimeUnit; @Service
public class LeaderElectionService { private static final String LEADER_LOCK_KEY = "scheduler:leader:lock";
private static final String HEARTBEAT_CHANNEL = "scheduler:heartbeat"; @Autowired
private RedissonClient redisson; private volatile boolean isLeader = false;
private RLock leaderLock;
private Thread heartbeatThread; @PostConstruct
public void init() {
leaderLock = redisson.getLock(LEADER_LOCK_KEY);
startElection();
startHeartbeatListener();
} private void startElection() {
// 尝试获取领导权(非阻塞式)
new Thread(() -> {
while (!Thread.currentThread().isInterrupted()) {
try {
// 尝试获取锁,锁过期时间30秒
boolean acquired = leaderLock.tryLock(0, 30, TimeUnit.SECONDS);
if (acquired) {
isLeader = true;
System.out.println("当前节点当选为Leader");
startHeartbeatTask(); // 启动心跳任务
break;
}
Thread.sleep(5000); // 每5秒重试一次
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}).start();
} private void startHeartbeatTask() {
heartbeatThread = new Thread(() -> {
while (isLeader && !Thread.currentThread().isInterrupted()) {
try {
// 1. 续期锁(看门狗机制会自动处理)
// 2. 发布心跳
redisson.getTopic(HEARTBEAT_CHANNEL)
.publish(System.currentTimeMillis()); Thread.sleep(10000); // 每10秒发送一次心跳
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
});
heartbeatThread.start();
} private void startHeartbeatListener() {
// 监听Leader心跳
redisson.getTopic(HEARTBEAT_CHANNEL)
.addListener(Long.class, (channel, heartbeatTime) -> {
System.out.println("收到Leader心跳: " + heartbeatTime);
// 可在此更新最后一次心跳时间
});
} @PreDestroy
public void shutdown() {
if (isLeader && leaderLock.isHeldByCurrentThread()) {
leaderLock.unlock();
isLeader = false;
if (heartbeatThread != null) {
heartbeatThread.interrupt();
}
}
} public boolean isLeader() {
return isLeader;
}
}

3. 健康检查增强

@Service
public class HealthCheckService { @Autowired
private RedissonClient redisson; private volatile long lastHeartbeatTime = 0; @PostConstruct
public void init() {
// 定时检查Leader状态
Executors.newSingleThreadScheduledExecutor()
.scheduleAtFixedRate(this::checkLeaderStatus, 0, 5, TimeUnit.SECONDS);
} private void checkLeaderStatus() {
Long currentTime = redisson.getBucket("scheduler:leader:heartbeat").get();
if (currentTime != null) {
lastHeartbeatTime = currentTime;
} // 超过30秒未收到心跳认为Leader失效
if (System.currentTimeMillis() - lastHeartbeatTime > 30000) {
System.out.println("Leader可能已宕机,触发重新选举");
// 可在此触发主动抢锁逻辑
}
}
}

三、关键优化点

1. 多级故障检测

检测方式 触发条件 恢复动作
Redisson看门狗超时 锁续期失败(默认30秒) 自动释放锁,其他节点可竞争
主动心跳超时 自定义阈值(如30秒) 强制释放锁并重新选举
Redis连接断开 ConnectionState.LOST 暂停选举直到连接恢复

2. 选举性能优化配置

# application.yml
redisson:
lock:
watchdog-timeout: 30000 # 看门狗超时时间(ms)
threads: 16 # 事件处理线程数
netty-threads: 32 # Netty工作线程数

3. 脑裂防护方案

// 使用Redisson的MultiLock实现多Redis节点锁
RLock lock1 = redissonClient1.getLock(LEADER_LOCK_KEY);
RLock lock2 = redissonClient2.getLock(LEADER_LOCK_KEY);
RLock multiLock = redisson.getMultiLock(lock1, lock2); boolean acquired = multiLock.tryLock(0, 30, TimeUnit.SECONDS);

四、生产环境部署建议

1. Redis架构选择

部署模式 适用场景 建议配置
哨兵模式 高可用要求高 3哨兵+3Redis实例
Cluster模式 大数据量+高性能 至少6节点(3主3从)
单节点 仅开发测试 不推荐生产使用

2. 监控指标

// 暴露Redisson指标(配合Spring Boot Actuator)
@Bean
public RedissonMetricsBinder redissonMetrics(RedissonClient redisson) {
return new RedissonMetricsBinder(redisson);
}

监控关键指标:

  • redisson.executor.active_threads:活跃线程数
  • redisson.pubsub.subscriptions:订阅数量
  • redisson.connections.active:活跃连接数

3. 灾备方案

  • 双活数据中心:通过RedissonClient配置多区域端点
    Config config = new Config();
    config.useClusterServers()
    .addNodeAddress("redis://dc1-node1:6379")
    .addNodeAddress("redis://dc2-node1:6379");
  • 降级策略:本地缓存最后已知状态
    @Bean
    @Primary
    public LeaderService fallbackLeaderService() {
    return new FallbackLeaderService(redisLeaderService, localCache);
    }

五、与Spring Cloud集成

1. 调度任务控制

@Scheduled(fixedRate = 5000)
public void scheduledTask() {
if (leaderElectionService.isLeader()) {
// 只有Leader执行的逻辑
processBatchData();
}
}

2. 动态配置更新

@RefreshScope
@RestController
@RequestMapping("/leader")
public class LeaderController { @Value("${election.timeout:30000}")
private long electionTimeout; @Autowired
private LeaderElectionService electionService; @PostMapping("/timeout")
public void updateTimeout(@RequestParam long timeout) {
// 动态调整选举超时
electionService.setElectionTimeout(timeout);
}
}

六、方案优势总结

  1. 亚秒级故障检测:通过Redis Pub/Sub实现实时通知
  2. 自动故障转移:Redisson看门狗机制保障锁释放
  3. 弹性扩展:支持动态增减微服务实例
  4. 最小依赖:仅需Redis集群,无需额外组件
  5. 与Spring生态无缝集成:完美配合@Scheduled等组件

基于Redission实现分布式调度任务选主的更多相关文章

  1. ETCD分布式锁实现选主机制(Golang实现)

    ETCD分布式锁实现选主机制(Golang) 为什么要写这篇文章 做架构的时候,涉及到系统的一个功能,有一个服务必须在指定的节点执行,并且需要有个节点来做任务分发,想了半天,那就搞个主节点做这事呗,所 ...

  2. Etcd 使用场景:通过分布式锁思路实现自动选主

    分布式锁?选主? 分布式锁可以保证当有多台实例同时竞争一把锁时,只有一个人会成功,其他的都是失败.诸如共享资源修改.幂等.频控等场景都可以通过分布式锁来实现. 还有一种场景,也可以通过分布式锁来实现, ...

  3. kazoo python zookeeper 选主

    本文讲述基于zookeeper选主与故障切换的方法.我们的例子使用的是python. 使用的库是kazoo,安装方式 pip install kazoo  应用场景: 多个实例部署,但不是" ...

  4. 基于Quartz编写一个可复用的分布式调度任务管理WebUI组件

    前提 创业小团队,无论选择任何方案,都优先考虑节省成本.关于分布式定时调度框架,成熟的候选方案有XXL-JOB.Easy Scheduler.Light Task Scheduler和Elastic ...

  5. 简述 zookeeper 基于 Zab 协议实现选主及事务提交

    Zab 协议:zookeeper 基于 Paxos 协议的改进协议 zookeeper atomic broadcast 原子广播协议. zookeeper 基于 Zab 协议实现选主及事务提交. 一 ...

  6. 基于scrapy-redis的分布式爬虫

    一.介绍 1.原生的scrapy框架 原生的scrapy框架是实现不了分布式的,其原因有: 1. 因为多台机器上部署的scrapy会各自拥有各自的调度器,这样就使得多台机器无法分配start_urls ...

  7. 聊聊Zookeeper应用场景、架构设计、选主机制

    Zookeeper作为一个分布式协调系统提供了一项基本服务:分布式锁服务,分布式锁是分布式协调技术实现的核心内容.像配置管理.任务分发.组服务.分布式消息队列.分布式通知/协调等,这些应用实际上都是基 ...

  8. 源码分析 RocketMQ DLedger 多副本之 Leader 选主

    目录 1.DLedger关于选主的核心类图 1.1 DLedgerConfig 1.2 MemberState 1.3 raft协议相关 1.4 DLedgerRpcService 1.5 DLedg ...

  9. [转帖]单集群10万节点 走进腾讯云分布式调度系统VStation

    单集群10万节点 走进腾讯云分布式调度系统VStation https://www.sohu.com/a/227223696_355140 2018-04-04 08:18 云计算并非无中生有的概念, ...

  10. [转帖]Greenplum: 基于PostgreSQL的分布式数据库内核揭秘(下篇)

    Greenplum: 基于PostgreSQL的分布式数据库内核揭秘(下篇) http://www.postgres.cn/v2/news/viewone/1/454 原作者:姚延栋 创作时间:201 ...

随机推荐

  1. Superset 下钻与交叉筛选

    以下内容来自外网:https://github.com/apache/superset/issues/6774 具体查看外网,我目前还没有琢磨,如果你有了思路请再下方留言 下面这个网址也有个交叉筛选: ...

  2. 开源数据库生态遇新变数,天翼云TeleDB提供企业数据管理更优解!

    近日,知名开源大规模并行处理 (MPP) 数据库Greenplum的源代码在其官方GitHub页面突然消失,引发了用户和开发者的广泛关注, PostgreSQL生态系统或将产生新变数.开源软件在面对商 ...

  3. 天翼云VPC支持专线健康检查介绍

    本文分享自天翼云开发者社区<天翼云VPC支持专线健康检查介绍>,作者:汪****波 天翼云支持本地数据中心IDC(Internet Data Center)通过冗余专线连接到天翼云云上专有 ...

  4. nacos(一): 下载、运行与鉴权配置

    1.下载 nacao的官网地址是https://nacos.io/ 当前稳定版本是2.5.0,可以在官网下载,也可以在github上下载.其中,官网提供的下载地址是: https://download ...

  5. Q:Linux下处理^M字符

    Linux下处理^M字符,很多时候windows环境中编辑过的文件,在Linux下经常会出现^M字符,可以通过以下方式处理该字符. 方法一:vim命令打开文件,然后在vim命令模式下输入以下内容: 1 ...

  6. 微信小程序单击事件与长按事件冲突的解决办法

    众所周知,在小程序中,长按事件一松手是会触发单击事件的,而在我们的实际需求中,往往是需要单击事件和长按事件并存的. 然而,小程序却又好像想到了这种情况似的,给了我们一个触摸开始,一个触摸结束 也就是, ...

  7. QT5笔记: 32. QPainter 基本绘制

  8. Memcached深度剖析:解锁高性能分布式内存缓存的秘密

    引言 在当今快节奏的互联网世界中,应用程序的响应速度往往是用户体验的关键.为了提升性能,减轻数据库的压力,Memcached作为一种高性能的分布式内存对象缓存系统,被广泛应用于加速动态Web应用程序. ...

  9. 机器学习 | 强化学习(2) | 动态规划求解(Planning by Dynamic Programming)

    动态规划求解(Planning by Dynamic Programming) 动态规划概论 动态(Dynamic):序列性又或是时序性的问题部分 规划(Programming):最优化一个程序(Pr ...

  10. Selenium 测试介绍

    本文会从以下下几个方面介绍Selenium,相信大家阅读后会对Selenium有一个全新的认识.  为什么是Selenium  初探Selenium  Selenium组成  Selenium ...