window.location.href如何多次请求_RabbitMQ如何保证幂等性?
冪等性是分布式系統設計中的一個重要概念,是在做系統或者接口設計時要著重考慮的問題,尤其像支付寶、銀行、互聯網金融等涉及錢的系統,既要高效,數據也要準確,絕對不能出現多扣款,多打款等問題,冪等性的設計就顯得更為重要了。
本文我們就先來解釋一下什么是冪等性?然后再看一下在MQ中怎么保證冪等性?01PART什么是冪等?冪等性的實質是:對于一個資源,不管你請求一次還是請求多次,對該資源本身造成的影響應該是相同的,不能因為重復的請求而對該資源重復造成影響。注意關注的是請求操作對資源本身造成的影響,而不是請求資源返回的結果。如select * from t_user where id>10這條語句,假如在一次查詢后數據庫進行了insert或update操作,那么第二次再查時返回的結果可能與第一次不同,但這個操作是冪等性的,因為我們說過關注的是對資源本身的影響,不是返回的結果,雖然兩次查詢的返回結果不同,但select不管執行多少次,對數據庫中的數據資源本身都不會產生任何影響。
冪等性包括:① 一次或多次請求,對資源均不會造成影響,比如select操作;② 第一次請求對資源產生了影響,后面再發出多個相同的請求,與發出單個請求具有相同的效果,不會重復對資源產生影響。比如支付寶轉賬,手抖重復提交了2次,第一次扣款成功,余額減少100元,第二次就不能再重復扣款了。③ 需要說明的是網絡超時、服務宕機等問題,不是冪等的范圍。
冪等性是系統服務對外的一種承諾。比如我寫了一個接口,我承諾我的接口是符合冪等性的,就是說外部的多次調用對我系統造成的影響都是相同的,不會因為多次調用而對系統重復造成影響。聲明為冪等的服務認為調用失敗是常態,并且允許在調用失敗后重試。
02PARTRabbitMQ的冪等性那我們回到RabbitMQ中,RabbitMQ中的冪等性又是什么意思呢?我們先來看看在RabbitMQ中,哪些情況可能導致非冪等?
① consumer接收到消息處理完成后,在給Broker返回ack途中網絡中斷,Broker未收到確認信息,根據RabbitMQ的重試補償機制,則會把這條消息再重發給其他的消費者或等網絡重連后再發送給該消費者,造成了消息的重復消費。② 在開啟生產者confirm模式下,生產者已經把消息發送到Broker,但在Broker回傳ack確認時網絡中斷,生產者也會重新發送剛才的消息,造成Broker收到了重復的消息,最終將兩條重復的消息發送到消費端,造成了消息的重復消費。通過以上兩種場景我們看出,其實MQ的冪等性保障應該在消費端,要保證MQ的冪等性,就要保證消費者不會重復消費相同的消息?!?如何避免消息的重復消費問題?全局唯一ID + Redis生產者在發送消息時,為每條消息設置一個全局唯一的messageId,消費者拿到消息后,使用setnx命令,將messageId作為key放到redis中:setnx(messageId,1),若返回1,說明之前沒有消費過,正常消費;若返回0,說明這條消息之前已消費過,拋棄。※ setnx命令的含義,若給定的key不存在,執行set操作,返回1,若給定的Key已存在,不做任何操作,返回0。
> 生產者代碼
public void sendMessageIde() { MessageProperties properties = new MessageProperties(); properties.setMessageId(UUID.randomUUID().toString()); Message message = new Message("Hello RabbitMQ".getBytes(), properties); rabbitTemplate.convertAndSend("durable-exchange", "rabbit.long.yuan", message);}> 消費者代碼
@RabbitListener(queues = "durable-queue")@RabbitHandlerpublic void processIde(Message message, Channel channel) throws IOException { if (stringRedisTemplate.opsForValue().setIfAbsent(message.getMessageProperties().getMessageId(),"1")){ // 業務操作... System.out.println("消費消息:"+ new String(message.getBody(), "UTF-8")); // 手動確認 channel.basicAck(message.getMessageProperties().getDeliveryTag(), false); }}以上就是在RabbitMQ中保障冪等性的一個簡單demo,冪等性在系統接口設計中尤為重要,尤其在金融、互聯網系統,在做系統設計時需要著重考慮。
總結
以上是生活随笔為你收集整理的window.location.href如何多次请求_RabbitMQ如何保证幂等性?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python适合找哪方面工作_学习pyt
- 下一篇: soc设计方法与实现第三版pdf_资深R