当前位置: 首页 > news >正文

网站建设费税收分类外部门户网站首页

网站建设费税收分类,外部门户网站首页,安徽移动互联网开发,网页设计网站怎么做在 Java 分布式系统开发中,消息队列的应用已十分普遍。但随着业务规模扩大,消息的重复消费、意外消失、顺序错乱等问题逐渐成为系统稳定性的隐患。本文将从 Java 开发者的视角,深入分析这三大问题的产生原因、业务后果,并结合具体…

        在 Java 分布式系统开发中,消息队列的应用已十分普遍。但随着业务规模扩大,消息的重复消费、意外消失、顺序错乱等问题逐渐成为系统稳定性的隐患。本文将从 Java 开发者的视角,深入分析这三大问题的产生原因、业务后果,并结合具体代码示例给出可落地的解决方案。​
消息重复消费是 Java 开发中最易遇到的问题。例如,使用 Spring Kafka 消费支付消息时,若处理逻辑未做防护,可能导致用户账户被重复扣款,这在金融场景中是致命的。​
产生原因通常有以下几点
生产者重试配置不当:例如:生产者使用RetryTemplate时,若未设置合理的重试条件,网络波动时会重复发送消息。​
消费者 ACK 机制误用:例如:Spring Kafka 默认ack-mode=BATCH,若消费者处理消息后未及时提交 offset,重启后会重复消费批次内消息。​
分布式事务补偿:例如:在 Seata 等分布式事务框架中,回滚后触发的消息重发可能导致重复。​
在不同场景下,带来的后果也十分严重,如在金融领域会导致出现重复扣款、重复转账的问题,从而引发资损和用户投诉。​在库存管理系统中会导致重复扣减库存,从而出现超卖或负库存。为了解决这个     

        通常采用多种方法解决,如:

        (1)幂等性设计

        (2全局 ID+Redis 去重

@Service
public class OrderConsumer {@Autowiredprivate StringRedisTemplate redisTemplate;@Autowiredprivate OrderService orderService;@KafkaListener(topics = "order_pay")public void handlePayMessage(ConsumerRecord<String, String> record) {String messageId = record.headers().lastHeader("messageId").value().toString();// 利用Redis的SETNX判断是否已处理Boolean isFirstHandle = redisTemplate.opsForValue().setIfAbsent("msg:processed:" + messageId, "1", 24, TimeUnit.HOURS);if (Boolean.TRUE.equals(isFirstHandle)) {// 首次处理:执行业务逻辑orderService.processPayment(record.value());} else {// 重复消息:直接返回log.info("重复消息,messageId:{}", messageId);}}
}

        (3)数据库唯一约束

@Transactional
public void processPayment(String orderJson) {OrderDTO order = JSON.parseObject(orderJson, OrderDTO.class);// 插入时若messageId重复,会抛出DuplicateKeyExceptionorderMapper.insert(new OrderPO().setOrderId(order.getOrderId()).setMessageId(order.getMessageId()).setStatus("PAID"));
}


消息消失指消息未被消费却永久丢失,例如用户下单消息消失会导致订单 “幽灵下单”,用户已付款但系统无记录。​
产生原因通常有以下几点
生产者未开启确认机制:如Kafka 生产者未设置acks=all,消息未写入分区副本即返回成功。​
Spring 容器关闭导致丢失:消费者在@PreDestroy阶段被强制关闭,未处理的消息被丢弃。​
中间件配置疏漏:如RabbitMQ 队列未设置durable=true,重启后队列消失;Kafka 未设置log.retention.hours,消息提前过期。​
其也会导致许多严重的后果,如:
交易链路断裂:支付成功但订单状态未更新,用户投诉。​
数据同步失败:跨系统数据未同步,导致库存、会员信息不一致。​
任务调度失效:定时任务触发消息丢失,导致任务漏执行。​
通常采用如下的解决方案:全链路可靠性保障​
1. 生产者确认机制(

@Configuration​
public class KafkaProducerConfig {​@Bean​public ProducerFactory<String, String> producerFactory() {​Map<String, Object> config = new HashMap<>();​config.put(ProducerConfig.ACKS_CONFIG, "all"); // 等待所有副本确认​config.put(ProducerConfig.RETRIES_CONFIG, 3); // 重试3次​config.put(ProducerConfig.ENABLE_IDEMPOTENCE_CONFIG, true); // 开启幂等性生产​return new DefaultKafkaProducerFactory<>(config);​}​
​@Bean​public KafkaTemplate<String, String> kafkaTemplate() {​KafkaTemplate<String, String> template = new KafkaTemplate<>(producerFactory());​// 发送结果回调​template.setProducerListener(new ProducerListener<>() {​@Override​public void onError(ProducerRecord<String, String> record, Exception exception) {​log.error("消息发送失败,topic:{}, msg:{}", record.topic(), record.value(), exception);​// 失败后可存入本地消息表,定时重试​}​});​sdareturn template;​}​
}​



2. 消费者手动确认

​
@Configuration​
public class KafkaConsumerConfig {​@Bean​public ConsumerFactory<String, String> consumerFactory() {​Map<String, Object> config = new HashMap<>();​config.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, false); // 关闭自动提交​return new DefaultKafkaConsumerFactory<>(config);​}​
​@Bean​public ConcurrentKafkaListenerContainerFactory<String, String> kafkaListenerContainerFactory() {​ConcurrentKafkaListenerContainerFactory<String, String> factory = new ConcurrentKafkaListenerContainerFactory<>();​factory.setConsumerFactory(consumerFactory());​factory.getContainerProperties().setAckMode(ContainerProperties.AckMode.MANUAL_IMMEDIATE); // 手动确认​return factory;​}​
}​
​
// 消费者代码​
@KafkaListener(topics = "order_create")​
public void handleCreateMessage(ConsumerRecord<String, String> record, Acknowledgment ack) {​try {​orderService.createOrder(record.value());​ack.acknowledge(); // 处理成功:手动提交offset​} catch (Exception e) {​log.error("处理失败,暂不确认", e);​// 可将消息转发到死信队列​}​
}​


消息顺序性指消息处理顺序与发送顺序一致。例如,订单的 “创建→支付→发货” 消息若顺序错乱,会导致 “未支付就发货” 的逻辑错误。​产生原因通常有以下几点:
多线程消费:Spring Kafka 的concurrency>1时,多个线程并行处理同一分区消息。​
分区路由错误:Kafka 生产者未指定partitioner.class,导致同一订单的消息被分配到不同分区。​
重试机制打乱顺序:失败消息进入重试队列后,后续消息先被处理。​
其可能会导致许多后果,如:
状态机异常:订单从 “待支付” 直接跳至 “已发货”,状态流转断裂。​
数据计算错误:账户先扣款后充值,导致余额计算错误。​
日志时序混乱:分布式追踪日志顺序错乱,难以排查问题。​
通常开发人员采用以下方案解决
1. 单分区 + 单线程消费
2. 按业务 ID 路由分区​
通过订单 ID 哈希到固定分区,确保同一订单的消息在同一分区:​

public class OrderPartitioner implements Partitioner {​@Override​public int partition(String topic, Object key, byte[] keyBytes, Object value, byte[] valueBytes, Cluster cluster) {​// 订单ID作为key,哈希后取模分区数​String orderId = (String) key;​List<PartitionInfo> partitions = cluster.partitionsForTopic(topic);​return Math.abs(orderId.hashCode()) % partitions.size();​}​
}​



http://www.dtcms.com/a/448262.html

相关文章:

  • 住建城乡建设部网站证件查询filetype doc 网站建设
  • 部署php网站wordpress本地手机无法访问
  • 电商网站构建网站建设方案优化
  • 浏览器网站入口dede58织梦模板
  • div网站模板网站建设迁移方案
  • 温州大凯工艺品有限公司英文网站优秀企业网页设计
  • 一键建站模板引流推广话术文案
  • 网站专题报道页面怎么做的网站开发找哪个
  • 做一个搜索引擎网站要多少钱软文
  • 北京市朝阳区网站制作江苏缘生源建设工程有限公司网站
  • 网站平台开发报价表怎么做wordpress olve
  • 网站模板 整站源码做网站域名选择
  • 自己做的网站怎么接入微信wordpress清楚所有评论
  • dz旅游网站模板网站认证是什么
  • 网站模板的修改双辽做网站
  • 网站建设方面论文产品营销方案
  • 如何用个人电脑做网站中铁建设集团有限公司电话
  • 优礼品网站模板不准别人网站做反链
  • 如何建一个手机网站现在清算组备案在哪个网站做
  • 网站留言短信提醒wordpress检测登录ip
  • 溧阳做网站哪家好wordpress返利主题
  • 中铁建设集团华北分公司网站seo每天一贴博客
  • 知名网站网页设计特色怎么做网站图片链接
  • 做个企业网站h5网站制作网站开发
  • 企业培训 电子商务网站建设 图片做网站的公司一般怎么培训销售
  • 网站建设有哪些需求巨量数据官网
  • 网站的建设技术有哪些内容广东网站建站系统哪家好
  • 企业网站 批量备案商城建设网站制作
  • 谷歌做新媒体运营的网站网站内部链接如何进行优化建设
  • 网站图标素材图片网站建设项目经理招聘