心跳续约机制
2025/7/10小于 1 分钟
心跳续约机制
服务/实例 注册
分别调用服务的注册接口
@Override
public Long create(GroupDetailSaveReqVO reqVO) {
String key = reqVO.getGroupKey();
if (StrUtil.isBlank(key)) {
throw new RuntimeException("请选择所属网关实例");
}
Long groupId = gatewayGroupMapper.getIdByKey(key);
if (groupId == null) {
throw new RuntimeException("网关实例不存在");
}
Long id = gatewayGroupDetailMapper.getIdByAddr(reqVO.getAddress());
if (id != null) {
return id;
}
GatewayGroupDetailDO gatewayGroupDetailDO = new GatewayGroupDetailDO();
gatewayGroupDetailDO.setId(uniqueIdUtil.nextId());
gatewayGroupDetailDO.setGroupId(groupId);
gatewayGroupDetailDO.setDetailName(reqVO.getName());
gatewayGroupDetailDO.setDetailAddress(reqVO.getAddress());
gatewayGroupDetailDO.setDetailWeight(reqVO.getWeight());
gatewayGroupDetailDO.setStatus(StatusEnum.DISABLE.getValue());
gatewayGroupDetailMapper.insert(gatewayGroupDetailDO);
return gatewayGroupDetailDO.getId();
}
@Override
public Boolean register(ServerDetailRegisterReqVO reqVO) {
Integer count = gatewayServerDetailMapper.registerIfAbsent(reqVO.getServerAddress());
if (count > 0) {
return true;
}
GatewayServerDetailDO detailDO = new GatewayServerDetailDO();
detailDO.setId(uniqueIdUtil.nextId());
detailDO.setServerId(reqVO.getServerId());
detailDO.setServerAddress(reqVO.getServerAddress());
detailDO.setStatus(StatusEnum.ENABLE.getValue());
try {
gatewayServerDetailMapper.insert(detailDO);
} catch (Exception e) {
throw new RuntimeException("注册创建失败");
}
return true;
}
维持心跳
@Override
public Boolean keepAlive(HeartBeatReqVO reqVO) {
String server = reqVO.getServer();
Map<Object, Object> entries = redisTemplate.opsForHash()
.entries("heartbeat:server:" + server + ":" + reqVO.getAddr());
if (entries.isEmpty()) {
HashMap<String, Object> map = new HashMap<>();
map.put("lastTime", LocalDateTime.now());
map.put("startTime", LocalDateTime.now());
map.put("url", reqVO.getAddr());
map.put("weight", 1);
redisTemplate.opsForHash().putAll("heartbeat:server:" + server + ":" + reqVO.getAddr(), map);
redisTemplate.expire("heartbeat:server:" + server + ":" + reqVO.getAddr(), 30, TimeUnit.SECONDS);
return true;
}
redisTemplate.opsForHash().put("heartbeat:server:" + server + ":" + reqVO.getAddr(), "lastTime", LocalDateTime.now());
redisTemplate.expire("heartbeat:server:" + server + ":" + reqVO.getAddr(), 30, TimeUnit.SECONDS);
return true;
}
定时任务
配置Redis
@Slf4j
@Component
@RequiredArgsConstructor
public class RedisPubUtil {
private final RedisTemplate<String, String> redisTemplate;
public void publish(String channel, String message) {
redisTemplate.convertAndSend(channel, message);
}
}
定时发送心跳信息
@Component
public class HeartBeatScheduled {
@Resource
private RedisPubUtil redisPubUtil;
@Scheduled(cron = "0/15 * * * * ?")
public void heartBeat() {
redisPubUtil.publish("heartBeat", "来自网关中心的心跳请求");
}
}