主頁 > 後端開發 > 【訊息佇列 005】RocketMQ概要

【訊息佇列 005】RocketMQ概要

2020-10-05 16:21:43 後端開發

文章目錄

  • 一、前言
  • 二、 RocketMQ簡介
    • 2.1 RocketMQ是阿里的開源訊息中間件,現為Apache頂級開源專案
    • 2.2 RocketMQ處理高并發做了兩件事情
    • 2.3 RocketMQ:優點 + 缺點 + 業務用途(可以作為一個面試問題)
    • 2.4 RocketMQ專案結構
  • 三、RocketMQ面試知識
    • 3.1 Rocket的分布式架構(高并發、高效率、高可用的保證)
    • 3.2 詳細四個部分
      • 3.2.1 第一,NameServer
      • 3.2.2 第二,Producer
      • 3.2.3 第三,Broker
      • 3.2.4 第四,Consumer
  • 四、RocketMQ訊息領域模型
  • 五、其他問題
  • 六、面試金手指
  • 七、小結

一、前言

二、 RocketMQ簡介

2.1 RocketMQ是阿里的開源訊息中間件,現為Apache頂級開源專案

RocketMQ是一個純Java、分布式、佇列模型的開源訊息中間件,前身是MetaQ,是阿里參考Kafka特點研發的一個佇列模型的訊息中間件(RocketMQ是阿里開源其自研的第三代分布式訊息中間件),后開源給apache基金會成為了apache的頂級開源專案,具有高性能、高可靠、高實時、分布式特點,

RocketMQ英文直譯:Rocket火箭、MQ message queue 訊息佇列
Apache基金會中的342個專案中,暫時還只有Kylin、CarbonData、Eagle 、Dubbo和 RocketMQ 共計五個中國技術人主導的專案,我們比較熟悉的是Dubbo和RocketMQ,都是阿里的,難怪國內這么多公司舔阿里、
RocketMQ可以實用于電商領域,金融領域,大資料領域,這些領域正好是阿里的專長,

阿里巴巴內部圍繞著RocketMQ內核打造了三款產品,分別是MetaQ、Notify和Aliware MQ,這三者分別采用了不同的模型,
MetaQ主要使用了拉模型,解決了順序訊息和海量堆積問題;
Notify主要使用了推模型,解決了事務訊息;
而云產品Aliware MQ則是提供了商業化的版本,

2.2 RocketMQ處理高并發做了兩件事情

說到高并發,就是雙11洗禮,為了在高并發下保護資料庫,RocketMQ團隊重點做了兩件事情,優化慢請求與統一存盤引擎,

(1)優化慢請求:這里主要是解決在海量高并發場景下降低慢請求對整個集群帶來的抖動,毛刺問題,這是一個極具挑戰的技識訓,團隊同學經過長達1個多月的跟進調優,從雙十一的復盤情況來看,99.996%的延遲落在了10ms以內,而99.6%的延遲在1ms以內,優化主要集中在RocketMQ存盤層演算法優化、JVM與作業系統調優,更多的細節大家可以參考《萬億級資料洪峰下的分布式訊息引擎》,

(2)統一存盤引擎:主要解決的訊息引擎的高可用,成本問題,在多代訊息引擎共存的前提下,我們對Notify的存盤模塊進行了全面移植與替換,

RocketMQ天生為金融互聯網領域而生,追求高可用、高并發、低延遲,是一個阿里巴巴由內而外成功孕育的典范,RocketMQ在阿里集團也被廣泛應用在訂單,交易,充值,流計算,訊息推送,日志流式處理,binglog分發等場景,

2.3 RocketMQ:優點 + 缺點 + 業務用途(可以作為一個面試問題)

RocketMQ優點:
單機吞吐量:十萬級
可用性:非常高,分布式架構
訊息可靠性:經過引數優化配置,訊息可以做到0丟失
功能支持:MQ功能較為完善,還是分布式的,擴展性好
支持10億級別的訊息堆積,不會因為堆積導致性能下降
原始碼是java,我們可以自己閱讀原始碼,定制自己公司的MQ,可以掌控
天生為金融互聯網領域而生,對于可靠性要求很高的場景,尤其是電商里面的訂單扣款,以及業務削峰,在大量交易涌入時,后端可能無法及時處理的情況
RoketMQ在穩定性上可能更值得信賴,這些業務場景在阿里雙11已經經歷了多次考驗,如果你的業務有上述并發場景,建議可以選擇RocketMQ

RocketMQ缺點:
支持的客戶端語言不多,目前是java及c++,其中c++不成熟
社區活躍度不是特別活躍那種
沒有在 mq 核心中去實作JMS等介面,有些系統要遷移需要修改大量代碼

RocketMQ的業務用途(重點):
發布/訂閱訊息傳遞模型
財務級交易訊息
各種跨語言客戶端,例如Java,C / C ++,Python,Go
可插拔的傳輸協議,例如TCP,SSL,AIO
內置的訊息跟蹤功能,還支持開放式跟蹤
多功能的大資料和流生態系統集成
按時間或偏移量追溯訊息
可靠的FIFO和嚴格的有序訊息傳遞在同一佇列中
高效的推拉消費模型
單個佇列中的百萬級訊息累積容量
多種訊息傳遞協議,例如JMS和OpenMessaging
靈活的分布式橫向擴展部署架構
快如閃電的批量訊息交換系統
各種訊息過濾器機制,例如SQL和Tag
用于隔離測驗和云隔離群集的Docker映像
功能豐富的管理儀表板,用于配置,指標和監視
認證與授權

2.4 RocketMQ專案結構

RocketMQ專案結構
GitHub地址:https://github.com/apache/rocketmq
RocketMQ核心模塊(下載原始碼,idea打開):
rocketmq-broker:接受生產者發來的訊息并存盤(通過呼叫rocketmq-store),消費者從這里取得訊息,
rocketmq-client:提供發送、接受訊息的客戶端API,
rocketmq-namesrv:NameServer,類似于Zookeeper,這里保存著訊息的TopicName,佇列等運行時的元資訊,
rocketmq-common:通用的一些類,方法,資料結構等,
rocketmq-remoting:基于Netty4的client/server + fastjson序列化 + 自定義二進制協議,
rocketmq-store:訊息、索引存盤等,
rocketmq-filtersrv:訊息過濾器Server,需要注意的是,要實作這種過濾,需要上傳代碼到MQ!(一般而言,我們利用Tag足以滿足大部分的過濾需求,如果更靈活更復雜的過濾需求,可以考慮filtersrv組件),
rocketmq-tools:命令列工具,

三、RocketMQ面試知識

3.1 Rocket的分布式架構(高并發、高效率、高可用的保證)

他主要有四大核心組成部分:NameServer、Broker、Producer以及Consumer四部分,

在這里插入圖片描述

RocketMQ的四個部分(NameServer、Broker、Producer以及Consumer)都是采用分布式集群,這是他高并發(吞吐量大),高可用的原因之一,集群的模式有多種,包括多master 模式、多master多slave異步復制模式、多 master多slave同步雙寫模式,

這個模式很像Kafka,因為就是阿里參考Kafka特點研發的一個佇列模型的訊息中間件,

3.2 詳細四個部分

3.2.1 第一,NameServer

NameServer定義:主要負責對于源資料的管理,包括了對于Topic和路由資訊的管理,

NameServer的地位:NameServer在RocketMQ中是注冊中心,Zookeeper在Dubbo也是注冊中心
NameServer是一個功能齊全的服務器,從功能上看,類似Dubbo中的Zookeeper,但NameServer與Zookeeper相比更輕量,主要是因為每個NameServer節點互相之間是獨立的,沒有任何資訊互動,

NameServer心跳
NameServer壓力不會太大,平時主要開銷是在維持心跳和提供Topic-Broker的關系資料,但是,每個Broker向NameServer發心跳時, 會帶上當前自己負責的所有Topic資訊,如果一個Broker中的Topic個數太多(萬級別),會導致一次心跳中,就Topic的資料就幾十M,網路情況差的話, 網路傳輸失敗,心跳失敗,導致NameServer誤認為Broker心跳失敗,

NameServer 是無狀態的,可以橫向擴展,成為一個注冊中心集群
NameServer 被設計成幾乎無狀態的,可以橫向擴展,節點之間相互之間無通信,通過部署多臺機器來標記自己是一個偽集群,

每個 Broker 在啟動的時候會到 NameServer 注冊
每個 Broker 在啟動的時候會到 NameServer 注冊,然后,各個Broker將資訊注冊到NameServer,然后Producer和Consumer就可以來NameServer取Broker的資訊了,即每個 Producer 在發送訊息前會根據 Topic 到 NameServer 獲取到 Broker 的路由資訊,每個Consumer 也會定時獲取 Topic 的路由資訊,

NameServer作為RocketMQ的注冊中心,在互動邏輯上,和Dubbo中注冊中心的角色,幾乎一模一樣,

3.2.2 第二,Producer

Producer定義:訊息生產者,負責產生訊息,一般由業務系統負責產生訊息,

Producer分布式部署
Producer由用戶進行分布式部署,訊息由Producer通過多種負載均衡模式發送到Broker集群,發送低延時,支持快速失敗,

Producer擁有了三種方式發送訊息:同步發送、異步發送和單向發送

同步雙向發送定義:同步發送指訊息發送方Producer發出資料后,一定要收到接收方發回回應之后才發下一個資料包,
同步雙向發送特點:可靠性最好,耗時最長,注重可靠性高,適合發重要資訊,
同步雙向發送用途:用于重要通知訊息,例如重要通知郵件、營銷短信,

異步雙向發送定義:異步發送指訊息發送方Producer發出資料后,不等接收方發回回應,接著發送下個資料包,
異步雙向發送特點:可靠性稍差,耗時較長,
異步雙向發送用途:用于可能鏈路耗時較長而對回應時間敏感的業務場景,例如用戶視頻上傳后,訊息佇列發送訊息,通知啟動轉碼服務,

單向發送定義:單向發送是指只負責發送訊息而不等待服務器回應且沒有回呼函式觸發,單向,發送方自己發自己的,不管接收方,
單向發送特點:可靠性最差,但是耗時最短,注重耗時短,
單向發送用途:適用于某些耗時非常短但對可靠性要求并不高的場景,例如日志收集,

3.2.3 第三,Broker

Broker定義:訊息中轉角色,負責存盤訊息,轉發訊息,

Broker是具體提供業務的服務器,單個Broker節點與所有的NameServer節點保持長連接及心跳,并會定時將Topic資訊注冊到NameServer,順帶一提底層的通信和連接都是基于Netty實作的((1)netty基于NIO,網路通信高效率(2)阿里的兩種開源中間件,Dubbo和RocketMQ的結構相同,都需要網路通信,網路通信都是netty),

Broker負責訊息存盤,以Topic為緯度支持輕量級的佇列,單機可以支撐上萬佇列規模,支持訊息推拉模型,官網上有資料顯示:具有上億級訊息堆積能力,同時可嚴格保證訊息的有序性,

3.2.4 第四,Consumer

Consumer定義:訊息消費者,負責消費訊息,一般是后臺系統負責異步消費,

Consumer也由用戶部署,支持PUSH和PULL兩種型別的消費模式,支持集群消費和廣播訊息,提供實時的訊息訂閱機制,
Pull:拉取型消費者(Pull Consumer)主動從訊息服務器拉取資訊,只要批量拉取到訊息,用戶應用就會啟動消費程序,所以 Pull 稱為主動消費型,
Push:推送型消費者(Push Consumer)封裝了訊息的拉取、消費進度和其他的內部維護作業,將訊息到達時執行的回呼介面留給用戶應用程式來實作,所以 Push 稱為被動消費型別,但從實作上看還是從訊息服務器中拉取訊息,不同于 Pull 的是 Push 首先要注冊消費監聽器,當監聽器處觸發后才開始消費訊息,

四、RocketMQ訊息領域模型

在這里插入圖片描述

第一,Message 訊息
Message本質:就是訊息,就是要傳輸的資訊,
Message與Topic關系:一條訊息必須有一個主題(Topic),主題可以看做是你的信件要郵寄的地址,
Message與Tag的關系:一條訊息也可以擁有一個可選的標簽(Tag)和額處的鍵值對,它們可以用于設定一個業務 Key 并在 Broker 上查找此訊息以便在開發期間查找問題,

第二,Topic 主題
Topic定義:Topic 可以看做訊息的分類,它是訊息的第一級型別,比如一個電商系統可以分為:交易訊息、物流訊息等,
Topic與Message的關系:一條訊息必須有一個 Topic ,
Topic與Producer的關系:一個 Topic 可以有0個、1個、多個生產者向其發送訊息,一個生產者也可以同時向不同的 Topic 發送訊息,
Topic與Consumer的關系:一個 Topic 也可以被 0個、1個、多個消費者訂閱,

第三,Group 分組
Group定義:分為ProducerGroup,ConsumerGroup,代表某一類的生產者和消費者,一般來說同一個服務可以作為Group,同一個Group一般來說發送和消費的訊息都是一樣的
Group與Topic的關系:一個組可以訂閱多個Topic,

第四,Queue 佇列 和 Message Queue 訊息佇列
4.1 Queue 佇列
Queue定義:在Kafka中叫Partition,每個Queue內部是有序的,在RocketMQ中分為讀和寫兩種佇列,一般來說讀寫佇列數量一致,如果不一致就會出現很多問題,
4.2 Message Queue 訊息佇列
Message Queue(訊息佇列),主題被劃分為一個或多個子主題,即子主題就是訊息佇列,
訊息佇列和Topic的關系:一個 Topic 下可以設定多個訊息佇列,發送訊息時執行該訊息的 Topic ,RocketMQ 會輪詢該 Topic 下的所有佇列將訊息發出去,
訊息佇列是訊息的物理管理單位:一個Topic下可以有多個Queue,Queue的引入使得訊息的存盤可以分布式集群化,具有了水平擴展能力,

第五,Offset 偏移量
在RocketMQ 中,所有訊息佇列都是持久化,長度無限的資料結構,所謂長度無限是指佇列中的每個存盤單元都是定長,訪問其中的存盤單元使用Offset 來訪問,Offset 為 java long 型別,64 位,理論上在 100年內不會溢位,所以認為是長度無限,
也可以認為 Message Queue 是一個長度無限的陣列,Offset 就是下標,

第六,Tag 標簽
Tag定義:Tag 可以看作子分類/子主題,它是訊息的第二級型別,用于為用戶提供額外的靈活性,使用標簽,同一業務模塊不同目的的訊息就可以用相同 Topic 而不同的 Tag 來標識,比如交易訊息又可以分為:交易創建訊息、交易完成訊息等,
Tag意義:標簽有助于保持您的代碼干凈和連貫,并且還可以為 RocketMQ 提供的查詢系統提供幫助,
Tag與Message的關系:一條訊息可以沒有 Tag ,

第七,訊息消費模式
訊息消費模式有兩種:Clustering(集群消費)和Broadcasting(廣播消費),
第一,集群消費模式:默認情況下就是集群消費,該模式下一個消費者集群共同消費一個主題的多個佇列,一個佇列只會被一個消費者消費,如果某個消費者掛掉,分組內其它消費者會接替掛掉的消費者繼續消費,
第二,廣播消費模式:廣播消費訊息會發給消費者組中的每一個消費者進行消費,

第八,Message Order
Message Order(訊息順序)有兩種:Orderly(順序消費)和Concurrently(并行消費),
第一,順序消費:順序消費表示訊息消費的順序同生產者為每個訊息佇列發送的順序一致,所以如果正在處理全域順序是強制性的場景,需要確保使用的主題只有一個訊息佇列,
第二,并行消費:并行消費不再保證訊息順序,消費的最大并行數量受每個消費者客戶端指定的執行緒池限制,

五、其他問題

面試問題:如何保證 訊息的可用性 ?刷盤 + 主從同步
訊息可用性1-記憶體中的訊息持久化到磁盤(同步刷盤+異步刷盤):當我們選擇好了集群模式之后,那么我們需要關心的就是怎么去存盤和復制這個資料,只有講broker記憶體中的訊息持久化到磁盤,才能保證broker宕機,訊息不丟失,RocketMQ對訊息的持久化到磁盤,提供了同步和異步的策略來滿足我們的,
情況1:選擇同步刷盤,如果刷盤超時會給回傳 刷盤超時 FLUSH_DISK_TIMEOUT,
情況2:選擇異步刷盤,如果是異步刷盤不會回傳刷盤成功與否的任何資訊,
所以,選擇同步刷盤可以盡最大程度保證刷盤的時候訊息不會丟失,
訊息可用性2-主從partition復制(同步復制+異步復制):RocketMQ的主從同步提供了同步復制和異步復制兩種模式,當然選擇同步復制可以提升可用性,但是訊息的發送RT時間會下降10%左右,
RockteMQ刷盤
RocketMQ刷盤的最終實作都是使用NIO中的 MappedByteBuffer.force() 將映射區的資料寫入到磁盤,
如果是同步刷盤,在Broker把訊息寫到CommitLog映射區后,就會等待寫入完成,
如果是異步刷盤,只是喚醒對應的執行緒,不保證執行的時機,

RocketMQ混合型存盤結構 + Kafka獨立型存盤結構
RocketMQ采用的是混合型的存盤結構,定義:為Broker單個實體下所有的佇列共用一個日志資料檔案(即為CommitLog)來存盤,缺點:會存在較多的隨機讀操作,因此讀的效率偏低,同時消費訊息需要依賴ConsumeQueue,構建該邏輯消費佇列需要一定開銷,
而Kafka采用的是獨立型的存盤結構,定義:每個佇列一個檔案,

RocketMQ的生產者如何保證訊息順序發送?
生產者消費者一般需要保證順序訊息的話,可能就是一個業務場景下的,比如訂單的創建、支付、發貨、識訓,
那這些東西是不是一個訂單號呢?一個訂單的肯定是一個訂單號的說,那簡單了呀,
一個topic下有多個佇列,為了保證發送有序,RocketMQ提供了MessageQueueSelector佇列選擇機制,他有三種實作:
SelectMessageQueueByHash
SelectMessageQueueByMachineRoom
SelectMessageQueueByRandom
SelectMessageQueueByHash:使用Hash取模法,讓同一個訂單發送到同一個佇列中,再使用同步發送,只有同個訂單的創建訊息發送成功,再發送支付訊息,這樣,我們保證了發送有序,
RocketMQ的topic內的佇列機制,可以保證存盤滿足FIFO(First Input First Output 簡單說就是指先進先出),剩下的只需要消費者順序消費即可,
RocketMQ僅保證順序發送,順序消費由消費者業務保證!!!(解釋:一個訂單你發送的時候放到一個佇列里面去,你同一個的訂單號Hash一下是不是還是一樣的結果,那肯定是一個消費者消費,那順序是不是就保證了?)
真正的順序消費不同的中間件都有自己的不同實作我這里就舉個例子,大家思路理解下,

考點:RocketMQ支持的分布式事務
步驟1:Producer發送半訊息給Broker(對應下圖的中的 1 2 3 4)
是指暫不能被Consumer消費的訊息,Producer 已經把訊息成功發送到了 Broker 端,但此訊息被標記為暫不能投遞狀態,處于該種狀態下的訊息稱為半訊息,需要 Producer對訊息的二次確認后,Consumer才能去消費它,
在《分布式事務》單獨專欄中講,
步驟2:訊息回查,Broker詢問Producer(對應下圖的中 5 6 7 8)
由于網路閃段,生產者應用重啟等原因,導致 Producer 端一直沒有對 Half Message(半訊息) 進行 二次確認,這是Brock服務器會定時掃描長期處于半訊息的訊息,會主動詢問 Producer端 該訊息的最終狀態(Commit或者Rollback),該訊息即為 訊息回查,
未使用訊息回查的流程 1 2 3 4 8
已使用訊息回查的流程 1 2 3 4 5 6 7 8
在這里插入圖片描述
對于上圖解釋 1-8
1、A服務先發送個Half Message給Brock端,訊息中攜帶 B服務 即將要+100元的資訊,
2、服務端發送回應,半訊息接收成功,
3、執行本地事務(會有三種情況1、執行成功,2、執行失敗,3、網路等原因導致沒有回應)
4、服務A根據本地事務,發送 commit/rollback 給broker,轉到8.
5、如果因為網路等原因遲遲沒有回傳失敗還是成功,那么會執行RocketMQ的回呼介面,來進行事務的回查,
6、服務A檢查本地事務;
7、服務A根據本地事務,發送 commit/rollback 給broker,轉到8.
8、如果本地事務成功,那么Product像Brock服務器發送Commit,這樣B服務就可以消費該message;如果本地事務失敗,那么Product像Brock服務器發送Rollback,那么就會直接洗掉上面這條半訊息,

考點:訊息過濾
第一,Broker端訊息過濾  
定義:在Broker中,按照Consumer的要求做過濾;
優點:減輕網路傳輸負擔,減少了對于Consumer無用訊息的網路傳輸;
缺點:增加Broker的負擔,實作相對復雜,
第二,Consumer端訊息過濾
定義:Consumer端,程式員完全自定義實作過濾規則來過濾;
優點:減輕Broker的負擔,
缺點:增加網路傳輸負擔,很多無用的訊息要傳輸到Consumer端,

考點:Broker的Buffer問題(RocketMQ,讀寫磁盤代替記憶體buffer)
定義:Broker的Buffer通常指的是Broker中一個佇列的記憶體緩沖Buffer大小,這個Buffer通常大小有限,
RocketMQ,讀寫磁盤代替記憶體buffer:注意,RocketMQ同其他MQ有非常顯著的區別,RocketMQ沒有記憶體Buffer概念,RocketMQ的佇列都是持久化磁盤,從這方面說,RocketMQ的記憶體Buffer抽象成一個無限長度的佇列(理由:磁盤可以不斷存入),不管有多少資料進來都能裝得下,這個無限是有前提的,Broker會定期洗掉過期的資料,例如Broker只保存3天的訊息,那么這個Buffer雖然長度無限,但是3天前的資料會被從隊尾洗掉,

為什么RocketMQ沒有記憶體Buffer?
回答:不需要,RocketMQ的佇列都是持久化磁盤,不需要的時候讀盤,為了防止磁盤爆滿,資料定期清除,

考點:你知道訊息佇列的 “回溯消費/重復消費” 嗎?
定義:回溯消費是指Consumer已經消費成功的訊息,由于業務上的需求需要重新消費,要支持此功能,Broker在向Consumer投遞成功訊息后,訊息仍然需要保留,并且重新消費一般是按照時間維度,隔一段時間后回溯消費/重復消費,RocketMQ支持按照時間回溯消費,時間維度精確到毫秒,可以向前回溯,也可以向后回溯,
實踐
例如由于Consumer系統故障,恢復后需要重新消費1小時前的資料,那么Broker要提供一種機制,可以按照時間維度來回退消費進度,

考點:訊息堆積
訊息中間件三個功能:異步、解耦、流量控制,訊息堆積主要是涉及流量控制功能,流量控制就是擋住前端的資料洪峰,保證后端系統的穩定性,這就要求訊息中間件具有一定的訊息堆積能力,訊息堆積分以下兩種情況:
1、訊息堆積在broker的記憶體緩沖Buffer,一旦超過記憶體緩沖Buffer,可以根據一定的丟棄策略來丟棄訊息,如CORBA Notification規范中描述,適合能容忍丟棄訊息的業務,這種情況訊息的堆積能力主要在于記憶體Buffer大小,而且訊息堆積后,性能下降不會太大,因為記憶體中資料多少對于對外提供的訪問能力影響有限
2、訊息堆積到持久化存盤系統中,例如DB,KV存盤,檔案記錄形式,當訊息不能在記憶體Cache命中時,要不可避免的訪問磁盤,會產生大量讀IO,讀IO的吞吐量直接決定了訊息堆積后的訪問能力,
所以,評估訊息堆積能力主要有以下四點:
(1)記憶體中,訊息能堆積多少條,多少位元組?即訊息的堆積容量,
(2)訊息堆積后,發訊息的吞吐量大小,是否會受堆積影響?訊息堆積在記憶體中吞吐量不受影響,訊息堆積在磁盤持久化(db kv存盤 檔案記錄存盤),吞吐量受影響,
(3)訊息堆積后,正常消費的Consumer是否會受影響?
(4)訊息堆積后,訪問堆積在磁盤的訊息時,吞吐量有多大?

考點:定時訊息
定義:定時訊息是指訊息發到Broker后,不能立刻被Consumer消費,要到特定的時間點或者等待特定的時間后才能被消費,
RocketMQ支持定時訊息,但是不支持任意時間精度,支持特定的level,例如定時5s,10s,1m等,

問題:為什么不支持任意時間精度?
回答:如果要支持任意的時間精度,在Broker層面,必須要做訊息排序,如果再涉及到持久化,那么訊息排序要不可避免的產生巨大性能開銷,

問題:對于下單,多執行緒場景下,第一個執行緒還沒走完,第二個現在進來,也判斷沒處理過那不就兩個都繼續加了么?
回答:資料庫層面,訂單號+業務場景,組成一個唯一主鍵,你插入資料庫只能成功第一個,后續的都會報錯的,報違反唯一主鍵的錯誤,
為什么不直接就不判斷就等他插入的時候報錯,丟掉后續的就好了?
理由:報錯有很多種,你哪里知道不是資料庫掛了的錯?或者別的運行時例外?
不過你如果可以做到拋特定的例外也可以,反正我們要減少資料庫的報錯,如果并發大,像我現在負責的系統都是10W+QPS,那日志會打滿瘋狂報警的,

六、面試金手指

七、小結

RocketMQ概要,完成了,

天天打碼,天天進步!!!

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/157477.html

標籤:python

上一篇:Java-集群開篇

下一篇:[讀書筆記][從Paxos到Zookeeper分布式一致性原理與實踐] 1. 分布式系統原理和理論

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more