Kafka+redis分布式锁结合使用心得总结

#kafka部分

@KafkaListener(topics = "#{'{vsmart_alert_detection_tms_send_message_topic}'.split(',')}", groupId = "{vsmart.alert.detection.consumer.group}")

public void vsmartAlertDetectionTmsSendMessage(ConsumerRecord<?, ?> record, Acknowledgment ack, @Header(KafkaHeaders.RECEIVED_TOPIC) String topic) {

doSendMessage(record,ack);

}

private void doSendMessage(ConsumerRecord<?, ?> record, Acknowledgment ack) {

Optional message = Optional.ofNullable(record.value());

String key = record.topic() + "-" + record.partition() + "-offset:" + record.offset();

if (RedisUtils.isExistsKey(key)) {

ack.acknowledge();

return;

}

try {

if (message.isPresent() && (record.timestamp() > (System.currentTimeMillis() - kafkaConsumerDelayTime))) {

JSONObject msg = JSONObject.parseObject(record.value().toString());

msg.put(VSMART_KAFKA_MSG_POSITION_INFO, key);

//具体操作

}

}catch (Exception e){

}finally {

ack.acknowledge();

}

}

#redis部分

public Boolean handler(JSONObject msg) {

//解析

Boolean isOk = jsonToDetectionInfos(msg);

if (!isOk) {

return false;

}

//加锁 associatedKey()

String lockKey = associatedKey();

if (StrUtil.isEmpty(lockKey)) {

return false;

}

RLock lock = SpringUtils.getBean(RedissonClient.class).getLock(lockKey);

//锁的时间 根据业务需要进行调整

try {

boolean flag_2 = lock.tryLock(10, 300, TimeUnit.SECONDS);

if (flag_2) {

//加锁后执行前判断是否已经处理过kafka中相同位置的信息了

if (ObjectUtil.isNotNull(msg) &&

ObjectUtil.isNotNull(msg.get(VSMART_KAFKA_MSG_POSITION_INFO)) &&

RedisUtils.isExistsKey(msg.getString(VSMART_KAFKA_MSG_POSITION_INFO))) {

return false;

}

//具体业务操作

//...

return true;

} else {

detectionRuleBo.getLogText().append(StrUtil.format("{}-获取锁失败;", detectionRuleBo.getName())).append("<br>");

return false;

}

} catch (Exception e) {

} finally {

///释放锁

if (null != lock && lock.isHeldByCurrentThread()) {

if (ObjectUtil.isNotNull(msg) &&

ObjectUtil.isNotNull(msg.get(VSMART_KAFKA_MSG_POSITION_INFO))) {

RedisUtils.setCacheStrExpire(msg.getString(VSMART_KAFKA_MSG_POSITION_INFO), msg.getString(VSMART_KAFKA_MSG_POSITION_INFO), 60 * 60);

}

//解锁

lock.unlock();

}

return true;

}

}

相关推荐
kruptos6 小时前
分布式系统怎么“选主“?Raft 共识一次讲清
开发语言·分布式·php·共识算法
小智老师PMP8 小时前
2026深度解析|PMP第八版与NPDP核心侧重点本质区别(管理类证书怎么选)
开发语言·分布式·算法·职场和发展·产品经理
会周易的程序员10 小时前
5Draft(五帝)测试报告
服务器·c++·分布式·raft·共识算法·共识·算力服务器
驾驭人生14 小时前
Hangfire.Redis.StackExchange 已归档停更!生产任务卡死、重复执行、网络抖动问题解决方案
数据库·redis·缓存
想要打 Acm 的小周同学呀16 小时前
Kafka消息队列出现挤压如何解决?
分布式·kafka
吃饱了得干活18 小时前
Redis 不是死脑筋,它是一套“会进化”的存储系统
redis·后端
盟道科技18 小时前
小程序电商订单超时自动取消的三种实现方案:定时扫描、Redis 过期监听、延迟消息对比与生产落地
数据库·redis·小程序
夕除19 小时前
redis--011
redis
stark张宇20 小时前
分布式事务最全图解(6种方案):从强一致的2PC到最终对账,彻底搞懂数据一致性
分布式·后端
会周易的程序员20 小时前
5Draft使用说明书
服务器·c++·分布式·raft·共识