亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

首頁(yè) Java Java面試題 【面試】如何保障訊息100%投遞成功?如何保證訊息冪等性?

【面試】如何保障訊息100%投遞成功?如何保證訊息冪等性?

Jul 26, 2023 pm 02:58 PM
面試


【面試】如何保障訊息100%投遞成功?如何保證訊息冪等性?

一、前言

我們小夥伴應(yīng)該都聽說(shuō)夠訊息中間件MQ,如:RabbitMQ,RocketMQ,Kafka等。引入中間件的好處可以起到抗高並發(fā),削峰,業(yè)務(wù)解耦的作用。

【面試】如何保障訊息100%投遞成功?如何保證訊息冪等性?

如上圖:

(1)訂單服務(wù)投遞訊息給MQ中介軟體(2)物流服務(wù)監(jiān)聽MQ中介軟體,從而進(jìn)行消費(fèi)

我們這篇文章討論一下,如何保障訂單服務(wù)把訊息成功投遞給MQ中間件,以RabbitMQ舉例。

二、分析問(wèn)題

小夥伴們對(duì)此會(huì)有些疑問(wèn),訂單服務(wù)發(fā)起訊息服務(wù),回傳成功不就成功了嗎?如下面的偽代碼:

【面試】如何保障訊息100%投遞成功?如何保證訊息冪等性?

上面程式碼中,一般發(fā)送訊息就是這麼寫的,朋友們覺(jué)得有什麼問(wèn)題嗎?

下邊說(shuō)一個(gè)場(chǎng)景,如果MQ伺服器突然宕機(jī)了會(huì)出現(xiàn)什麼狀況?是不是我們訂單服務(wù)寄過(guò)去的訊息全部沒(méi)有了嗎?是的,一般MQ中間件為了提高系統(tǒng)的吞吐量會(huì)把訊息保存在記憶體中,如果不作其他處理,MQ伺服器一旦宕機(jī),訊息就會(huì)全部遺失。這個(gè)是業(yè)務(wù)不允許的,造成很大的影響。

三、持久化

有經(jīng)驗(yàn)的小夥伴會(huì)說(shuō),我知道一個(gè)方法就是把訊息持久化,RabbitMQ中發(fā)送訊息的時(shí)候會(huì)有個(gè)durable參數(shù)可以設(shè)置,設(shè)定為true,就會(huì)持久化。

【面試】如何保障訊息100%投遞成功?如何保證訊息冪等性?

這樣的話MQ伺服器即使宕機(jī),重啟後磁碟檔案中有訊息的存儲(chǔ),這樣就不會(huì)遺失了吧。是的這樣就一定機(jī)率的保障了訊息不遺失。

但還會(huì)有個(gè)場(chǎng)景,就是訊息剛剛儲(chǔ)存到MQ記憶體中,但還沒(méi)來(lái)得及更新到磁碟檔案中,突然宕機(jī)了。 (我靠,這個(gè)時(shí)間這麼短,也會(huì)出現(xiàn),機(jī)率太低了吧),這個(gè)場(chǎng)景在持續(xù)的大量訊息投遞的過(guò)程中,會(huì)很常見(jiàn)。

那怎麼辦?我們要如何作才能保障一定會(huì)持久化到磁碟上面呢?

四、confirm機(jī)制

上面問(wèn)題出現(xiàn)在,沒(méi)有人告訴我們持久化是否成功。還好很多MQ有回呼通知的特性,RabbitMQ就有confirm機(jī)制來(lái)通知我們是否持久化成功?

【面試】如何保障訊息100%投遞成功?如何保證訊息冪等性?

confirm機(jī)制的原理:

(1)訊息生產(chǎn)者把訊息傳送給MQ,如果接收成功,MQ會(huì)回傳一個(gè)ack訊息給生產(chǎn)者;

(2)如果訊息接收不成功,MQ會(huì)回傳一個(gè)nack訊息給生產(chǎn)者;

【面試】如何保障訊息100%投遞成功?如何保證訊息冪等性?

上面的偽代碼,有兩個(gè)處理訊息方式,就是ack回調(diào)和nack回調(diào)。

這樣是不是就可以保障100%訊息不遺失了呢?

我們來(lái)看看confirm的機(jī)制,試想一下,如果我們生產(chǎn)者每發(fā)一則訊息,都要MQ持久化到磁碟中,然後再發(fā)起ack或nack的回呼。這樣的話是不是我們MQ的吞吐量很不高,因?yàn)槊看味家延嵪⒊志没酱诺小懭氪诺@個(gè)動(dòng)作是很慢的。這個(gè)在高並發(fā)場(chǎng)景下是不能夠接受的,吞吐量太低了。

所以MQ持久化磁碟真實(shí)的實(shí)現(xiàn),是透過(guò)非同步呼叫處理的,他是有一定的機(jī)制,如:等到有幾千個(gè)訊息的時(shí)候,會(huì)一次性的刷盤到磁碟上面。而不是每來(lái)一則訊息,就刷盤一次。

所以comfirm機(jī)制其實(shí)是一個(gè)非同步監(jiān)聽的機(jī)制,是為了確保系統(tǒng)的高吞吐量,這樣就導(dǎo)致了還是不能夠100%保障訊息不遺失,因?yàn)榧词辜由狭薱onfirm機(jī)制,訊息在MQ記憶體中還沒(méi)刷盤到磁碟就宕機(jī)了,還是沒(méi)辦法處理。

說(shuō)了這麼多,還是沒(méi)辦法確保,那該怎麼辦呢? ? ?

五、訊息提前持久化 定時(shí)任務(wù)

#其實(shí)本質(zhì)的原因是無(wú)法確定是否持久化?那我們是不是可以自己讓消息持久化呢?答案是可以的,我們的方案再一步的演化。

【面試】如何保障訊息100%投遞成功?如何保證訊息冪等性?

上圖流程:

(1)訂單服務(wù)生產(chǎn)者再投遞訊息之前,先把訊息持久化到Redis或DB中,建議Redis ,高性能。訊息的狀態(tài)為發(fā)送中。

(2)confirm機(jī)制監(jiān)聽訊息是否發(fā)送成功?如ack成功訊息,刪除Redis中此訊息。

(3)如果nack不成功的訊息,這個(gè)可以根據(jù)自身的業(yè)務(wù)選擇是否重發(fā)此訊息。也可以刪除此訊息,由自己的業(yè)務(wù)決定。

(4)這邊加了個(gè)定時(shí)任務(wù),來(lái)拉取隔一定時(shí)間了,訊息狀態(tài)還是為發(fā)送中的,這個(gè)狀態(tài)就表明,訂單服務(wù)是沒(méi)有收到ack成功訊息。

(5)定時(shí)任務(wù)會(huì)作補(bǔ)償性的投遞訊息。這時(shí)候如果MQ回呼ack成功接收了,再把Redis中這個(gè)訊息刪除。

這樣的機(jī)制其實(shí)就是補(bǔ)償機(jī)制,我不管MQ有沒(méi)有真正的接收到,只要我的Redis中的訊息狀態(tài)也是為【發(fā)送中】,就表示此訊息沒(méi)有正確成功投遞。再啟動(dòng)定時(shí)任務(wù)去監(jiān)控,發(fā)起補(bǔ)償投遞。

當(dāng)然定時(shí)任務(wù)那邊我們還可以加上一個(gè)補(bǔ)償?shù)拇螖?shù),如果大於3次,還是沒(méi)有收到ack訊息,那就直接把訊息的狀態(tài)設(shè)定為【失敗】,由人工去排查到底是為什麼?

這樣的話方案就比較完美了,保障了100%的訊息不遺失(當(dāng)然不包含磁碟也壞了,可以做主從方案)。

不過(guò)這樣的方案,就會(huì)有可能發(fā)送多次相同的訊息,很有可能MQ已經(jīng)收到了訊息,就是ack訊息回呼時(shí)出現(xiàn)網(wǎng)路故障,沒(méi)有讓生產(chǎn)者收到。

那就要要求消費(fèi)者一定在消費(fèi)的時(shí)候保障冪等性!

六、冪等意義

我們先了解什麼叫冪等?在分散式應(yīng)用中,冪等是非常重要的,也就是相同條件下對(duì)一個(gè)業(yè)務(wù)的操作,不管操作多少次,結(jié)果都是一樣。

6.1、為什麼要有冪等這種場(chǎng)景?

為什麼要有冪等這種場(chǎng)景?因?yàn)樵诖笮偷南到y(tǒng)中,都是分散式部署,如:訂單業(yè)務(wù) 和 庫(kù)存業(yè)務(wù)有可能都是獨(dú)立部署的,都是單獨(dú)的服務(wù)。用戶下訂單,會(huì)呼叫到訂單服務(wù)和庫(kù)存服務(wù)。

【面試】如何保障訊息100%投遞成功?如何保證訊息冪等性?

因?yàn)榉稚⑹讲渴?,很有可能在呼叫?kù)存服務(wù)時(shí),因?yàn)榫W(wǎng)路等原因,訂單服務(wù)呼叫失敗,但其實(shí)庫(kù)存服務(wù)已經(jīng)處理完成,只是返回給訂單服務(wù)處理結(jié)果時(shí)出現(xiàn)了異常。這時(shí)候一般系統(tǒng)會(huì)作補(bǔ)償方案,也就是訂單服務(wù)再此放起庫(kù)存服務(wù)的調(diào)用,庫(kù)存減1。

【面試】如何保障訊息100%投遞成功?如何保證訊息冪等性?

這樣就出現(xiàn)了問(wèn)題,其實(shí)上一次呼叫已經(jīng)減了1,只是訂單服務(wù)沒(méi)有收到處理結(jié)果。現(xiàn)在又呼叫一次,又要減1,這樣就不符合業(yè)務(wù)了,多扣了。

冪等這個(gè)概念就是,不管庫(kù)存服務(wù)在相同條件下呼叫幾次,處理結(jié)果都一樣。這樣才能保證補(bǔ)償方案的可行性。

6.2、樂(lè)觀鎖定方案

借鏡資料庫(kù)的樂(lè)觀鎖定機(jī)制,如:

【面試】如何保障訊息100%投遞成功?如何保證訊息冪等性?

根據(jù)version版本,也就是在操作庫(kù)存前先取得目前商品的version版本號(hào),然後操作的時(shí)候帶上此version號(hào)。我們梳理下,我們第一次操作庫(kù)存時(shí),得到version為1,調(diào)用庫(kù)存服務(wù)version變成了2;但返回給訂單服務(wù)出現(xiàn)了問(wèn)題,訂單服務(wù)又一次發(fā)起調(diào)用庫(kù)存服務(wù),當(dāng)訂單服務(wù)傳如的version還是1,再執(zhí)行上面的sql語(yǔ)句時(shí),就不會(huì)執(zhí)行;因?yàn)関ersion已經(jīng)變成2了,where條件就不成立。這樣就保證了不管呼叫幾次,只會(huì)真正的處理一次。

6.3、唯一ID 指紋碼

#原理就是利用資料庫(kù)主鍵去重,在業(yè)務(wù)完成後插入主鍵標(biāo)識(shí)

【面試】如何保障訊息100%投遞成功?如何保證訊息冪等性?
  • #唯一ID就是業(yè)務(wù)表的唯一的主鍵,如商品ID

  • 指紋碼就是為了區(qū)別每次正常操作的碼,每次操作時(shí)產(chǎn)生指紋碼;可以用時(shí)間戳 業(yè)務(wù)編號(hào)的方式。

上面的sql語(yǔ)句:

  • #傳回如果為0 表示沒(méi)有操作過(guò),那麼業(yè)務(wù)操作後就可以insert into t_check(唯一ID 指紋碼)

  • #返回如果大於0 表示操作過(guò),就直接回傳

##好處:實(shí)作簡(jiǎn)單

壞處:高並發(fā)下資料庫(kù)瓶頸

解決方案:根據(jù)ID進(jìn)行分庫(kù)分錶進(jìn)行演算法路由
##### ####6.4、Redis原子操作#########利用redis的原子操作,做個(gè)操作完成的標(biāo)記。這個(gè)性能就比較好。但會(huì)遇到一些問(wèn)題。 ######第一:我們是否需要把業(yè)務(wù)結(jié)果進(jìn)行資料落庫(kù),如果落庫(kù),關(guān)鍵解決的問(wèn)題時(shí)資料庫(kù)和redis操作如何做到原子性? #########這個(gè)意思是庫(kù)存減1了,但redis進(jìn)行操作完成標(biāo)記時(shí),失敗了怎麼辦?也就是一定要保證落庫(kù)和redis 要嘛一起成功,要嘛一起失敗#########第二:如果不進(jìn)行落庫(kù),那麼都儲(chǔ)存到快取中,如何設(shè)定定時(shí)同步策略? #########這個(gè)意思是庫(kù)存減1,不落庫(kù),直接先操作redis操作完成標(biāo)記,然後由另外的同步服務(wù)進(jìn)行庫(kù)存落庫(kù),這個(gè)就是增加了系統(tǒng)複雜性,而且同步策略如何設(shè)定#########

以上是【面試】如何保障訊息100%投遞成功?如何保證訊息冪等性?的詳細(xì)內(nèi)容。更多資訊請(qǐng)關(guān)注PHP中文網(wǎng)其他相關(guān)文章!

本網(wǎng)站聲明
本文內(nèi)容由網(wǎng)友自願(yuàn)投稿,版權(quán)歸原作者所有。本站不承擔(dān)相應(yīng)的法律責(zé)任。如發(fā)現(xiàn)涉嫌抄襲或侵權(quán)的內(nèi)容,請(qǐng)聯(lián)絡(luò)admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費(fèi)脫衣圖片

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅(qū)動(dòng)的應(yīng)用程序,用於創(chuàng)建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費(fèi)的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費(fèi)的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強(qiáng)大的PHP整合開發(fā)環(huán)境

Dreamweaver CS6

Dreamweaver CS6

視覺(jué)化網(wǎng)頁(yè)開發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

神級(jí)程式碼編輯軟體(SublimeText3)

熱門話題

Laravel 教程
1597
29
PHP教程
1488
72
聊聊如何選擇一個(gè)最好的Node.js Docker映像? 聊聊如何選擇一個(gè)最好的Node.js Docker映像? Dec 13, 2022 pm 08:00 PM

選擇一個(gè)Node的Docker映像看起來(lái)像是小事,但是映像的大小和潛在漏洞可能會(huì)對(duì)你的CI/CD流程和安全造成重大的影響。那我們要如何選擇一個(gè)最好Node.js Docker映像呢?

如何解決跨域?常見(jiàn)解決方案淺析 如何解決跨域?常見(jiàn)解決方案淺析 Apr 25, 2023 pm 07:57 PM

跨域是開發(fā)中常會(huì)遇到的場(chǎng)景,也是面試中常會(huì)討論的問(wèn)題。掌握常見(jiàn)的跨域解決方案及其背後的原理,不僅可以提高我們的開發(fā)效率,還能在面試中表現(xiàn)的更加

一文理解JavaScript中的單例模式 一文理解JavaScript中的單例模式 Apr 25, 2023 pm 07:53 PM

JS 單例模式是常用的設(shè)計(jì)模式,它可以保證一個(gè)類別只有一個(gè)實(shí)例。這種模式主要用於管理全域變量,避免命名衝突和重複加載,同時(shí)也可以減少記憶體佔(zhàn)用,提高程式碼的可維護(hù)性和可擴(kuò)展性。

golang框架面試題集錦 golang框架面試題集錦 Jun 02, 2024 pm 09:37 PM

Go框架是一組擴(kuò)充Go內(nèi)建程式庫(kù)的元件,提供預(yù)製功能(例如網(wǎng)路開發(fā)和資料庫(kù)操作)。受歡迎的Go框架包括Gin(Web開發(fā))、GORM(資料庫(kù)操作)和RESTful(API管理)。中間件是HTTP請(qǐng)求處理鏈中的攔截器模式,用於在不修改處理程序的情況下新增身份驗(yàn)證或請(qǐng)求日誌記錄等功能。 Session管理透過(guò)儲(chǔ)存使用者資料來(lái)保持會(huì)話狀態(tài),可以使用gorilla/sessions管理session。

Java JPA 面試題精選:檢視你的持久化框架掌握程度 Java JPA 面試題精選:檢視你的持久化框架掌握程度 Feb 19, 2024 pm 09:12 PM

什麼是JPA?它與JDBC有什麼不同? JPA(JavaPersistenceapi)是一個(gè)用於物件關(guān)係映射(ORM)的標(biāo)準(zhǔn)接口,它允許Java開發(fā)者使用熟悉的Java物件來(lái)操作資料庫(kù),而無(wú)需編寫直接針對(duì)資料庫(kù)的sql查詢。而JDBC(JavaDatabaseConnectivity)是Java用來(lái)連接資料庫(kù)的標(biāo)準(zhǔn)API,它需要開發(fā)者使用SQL語(yǔ)句來(lái)操作資料庫(kù)。 JPA將JDBC封裝起來(lái),為物件-關(guān)聯(lián)映射提供了更方便、更高層級(jí)的API,簡(jiǎn)化了資料存取操作。在JPA中,什麼是實(shí)體(Entity)?實(shí)體

JavaScript怎麼判斷資料型別? 8 種方式分享 JavaScript怎麼判斷資料型別? 8 種方式分享 Feb 16, 2023 pm 02:48 PM

JavaScript怎麼判斷資料型別?這篇文章跟大家分享JS 判斷資料類型的 8 種方式,有效幫助工作和麵試,面試官看了微微一笑。

聊聊Node中的url模組和querystring模組 聊聊Node中的url模組和querystring模組 Feb 23, 2023 pm 07:39 PM

url模組和querystring模組是非常重要的兩個(gè)URL處理模組。在做node服務(wù)端的開發(fā)時(shí)會(huì)常用到。

100道常見(jiàn)PHP面試題(附解析),增強(qiáng)你的知識(shí)儲(chǔ)備! 100道常見(jiàn)PHP面試題(附解析),增強(qiáng)你的知識(shí)儲(chǔ)備! May 11, 2022 am 10:45 AM

本篇文章為大家整理分享100道常見(jiàn)PHP面試題(附答案分享),帶你整理基礎(chǔ)知識(shí),增強(qiáng)你的PHP知識(shí)儲(chǔ)備。有一定的參考價(jià)值,有需要的朋友可以參考一下,希望對(duì)大家有幫助。

See all articles