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;

}

}

相关推荐
时鲟、时倾1 小时前
docker部署kafka
docker·容器·kafka
兮动人1 小时前
PrettyZoo:优雅易用的 ZooKeeper 可视化管理工具
分布式·zookeeper·云原生·prettyzoo
MuYiLuck1 小时前
redis持久化与集群
java·数据库·redis
回家路上绕了弯2 小时前
五分钟内重复登录 QQ 号定位:数据结构选型与高效实现方案
分布式·后端
埃泽漫笔2 小时前
Redis性能优化避坑指南
redis
升鲜宝供应链及收银系统源代码服务2 小时前
升鲜宝生鲜配送供应链管理系统--- 《多语言商品查询优化方案(Redis + 翻译表 + 模糊匹配)》
java·数据库·redis·bootstrap·供应链系统·生鲜配送·生鲜配送源代码
JH30732 小时前
Redis 中被忽视的“键过期策略”与内存回收机制
数据库·redis·缓存
Microsoft Word2 小时前
Redis常见面试题
数据库·redis·缓存
bing.shao2 小时前
mongodb与redis在聊天场景中的选择
数据库·redis·mongodb
dudke2 小时前
c#实现redis的调用与基础类
数据库·redis·缓存