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;

}

}

相关推荐
java1234_小锋24 分钟前
Redis 宣布正式接入 AI
数据库·人工智能·redis
行百里er33 分钟前
Redis 持久化——RDB 快照 vs AOF 日志
redis·后端
本人手速666+37 分钟前
企微开发API如何设计客户冻结状态?WeComApi 在删除、投诉和异常客户场景中的自动化边界
运维·分布式·自动化·企业微信·企微外部群开发·wecomapi·企业微信二次开发
程序猿乐锅2 小时前
一文讲透缓存穿透、击穿和雪崩
java·redis·spring·缓存·mybatis
灯澜忆梦2 小时前
【RabbitMQ #4】 | Work 任务模型
分布式·rabbitmq
程序猿乐锅2 小时前
【黑马点评 | 第七篇】Redis 分布式锁的两种实现
java·数据库·redis·分布式·spring·缓存
千里码aicood4 小时前
基于Hadoop的机票价格波动分析系统的设计与实现
大数据·hadoop·分布式
程序猿乐锅4 小时前
【黑马点评 | 第九篇】秒杀优化-异步实现
java·spring boot·redis·后端·spring·中间件·mybatis
旋生万物8 小时前
Redis 缓存雪崩?不是 TTL 一样,是过期相位同步塌陷(附打散脚本)
redis·缓存·aigc·螺旋生成论·螺旋相位
今年下半年8 小时前
记录一次IBMS物联网项目的架构设计及技术栈应用
物联网·websocket·网络协议·tcp/ip·微服务·udp·kafka