主頁 > 前端設計 > 【訊息佇列 005】RocketMQ概要

【訊息佇列 005】RocketMQ概要

2020-10-05 22:36:58 前端設計

文章目錄

  • 一、前言
  • 二、 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/qianduan/158153.html

標籤:其他

上一篇: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)

熱門瀏覽
  • vue移動端上拉加載

    可能做得過于簡單或者比較low,請各位大佬留情,一起探討技術 ......

    uj5u.com 2020-09-10 04:38:07 more
  • 優美網站首頁,頂部多層導航

    一個個人用的瀏覽器首頁,可以把一下常用的網站放在這里,平常打開會比較方便。 第一步,HTML代碼 <script src=https://www.cnblogs.com/szharf/p/"js/jquery-3.4.1.min.js"></script> <div id="navigate"> <ul> <li class="labels labels_1"> ......

    uj5u.com 2020-09-10 04:38:47 more
  • 頁面為要加<!DOCTYPE html>

    最近因為寫一個js函式,需要用到$(window).height(); 由于手寫demo的時候,過于自信,其實對前端方面的認識也不夠體系,用文本檔案直接敲出來的html代碼,第一行沒有加上<!DOCTYPE html> 導致了$(window).height();的結果直接是整個document的高 ......

    uj5u.com 2020-09-10 04:38:52 more
  • WordPress網站程式手動升級要做好資料備份

    WordPress博客網站程式在進行升級前,必須要做好網站資料的備份,這個問題良家佐言是遇見過的;在剛開始接觸WordPress博客程式的時候,因為升級問題和博客網站的修改的一些嘗試,良家佐言是吃盡了苦頭。因為購買的是西部數碼的空間和域名,每當佐言把自己的WordPress博客網站搞到一塌糊涂的時候 ......

    uj5u.com 2020-09-10 04:39:30 more
  • WordPress程式不能升級為5.4.2版本的原因

    WordPress是一款個人博客系統,受到英文博客愛好者和中文博客愛好者的追捧,并逐步演化成一款內容管理系統軟體;它是使用PHP語言和MySQL資料庫開發的,用戶可以在支持PHP和MySQL資料庫的服務器上使用自己的博客。每一次WordPress程式的更新,就會牽動無數WordPress愛好者的心, ......

    uj5u.com 2020-09-10 04:39:49 more
  • 使用CSS3的偽元素進行首字母下沉和首行改變樣式

    網頁中常見的一種效果,首字改變樣式或者首行改變樣式,效果如下圖。 代碼: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, ......

    uj5u.com 2020-09-10 04:40:09 more
  • 關于a標簽的講解

    什么是a標簽? <a> 標簽定義超鏈接,用于從一個頁面鏈接到另一個頁面。 <a> 元素最重要的屬性是 href 屬性,它指定鏈接的目標。 a標簽的語法格式:<a href=https://www.cnblogs.com/summerxbc/p/"指定要跳轉的目標界面的鏈接">需要展示給用戶看見的內容</a> a標簽 在所有瀏覽器中,鏈接的默認外觀如下: 未被訪問的鏈接帶 ......

    uj5u.com 2020-09-10 04:40:11 more
  • 前端輪播圖

    在需要輪播的頁面是引入swiper.min.js和swiper.min.css swiper.min.js地址: 鏈接:https://pan.baidu.com/s/15Uh516YHa4CV3X-RyjEIWw 提取碼:4aks swiper.min.css地址 鏈接:https://pan.b ......

    uj5u.com 2020-09-10 04:40:13 more
  • 如何設定html中的背景圖片(全屏顯示,且不拉伸)

    1 <style>2 body{background-image:url(https://uploadbeta.com/api/pictures/random/?key=BingEverydayWallpaperPicture); 3 background-size:cover;background ......

    uj5u.com 2020-09-10 04:40:16 more
  • Java學習——HTML詳解(上)

    HTML詳解 初識HTML Hyper Text Markup Language(超文本標記語言) 1 <!--DOCTYPE:告訴瀏覽器我們要使用什么規范--> 2 <!DOCTYPE html> 3 <html lang="en"> 4 <head> 5 <!--meta 描述性的標簽,描述一些 ......

    uj5u.com 2020-09-10 04:40:33 more
最新发布
  • 我的第一個NPM包:panghu-planebattle-esm(胖虎飛機大戰)使用說明

    好家伙,我的包終于開發完啦 歡迎使用胖虎的飛機大戰包!! 為你的主頁添加色彩 這是一個有趣的網頁小游戲包,使用canvas和js開發 使用ES6模塊化開發 效果圖如下: (覺得圖片太sb的可以自己改) 代碼已開源!! Git: https://gitee.com/tang-and-han-dynas ......

    uj5u.com 2023-04-20 07:59:23 more
  • 生產事故-走近科學之消失的JWT

    入職多年,面對生產環境,盡管都是小心翼翼,慎之又慎,還是難免捅出簍子。輕則滿頭大汗,面紅耳赤。重則系統停擺,損失資金。每一個生產事故的背后,都是寶貴的經驗和教訓,都是專案成員的血淚史。為了更好地防范和遏制今后的各類事故,特開此專題,長期更新和記錄大大小小的各類事故。有些是親身經歷,有些是經人耳傳口授 ......

    uj5u.com 2023-04-18 07:55:04 more
  • 記錄--Canvas實作打飛字游戲

    這里給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 打開游戲界面,看到一個畫面簡潔、卻又富有挑戰性的游戲。螢屏上,有一個白色的矩形框,里面不斷下落著各種單詞,而我需要迅速地輸入這些單詞。如果我輸入的單詞與螢屏上的單詞匹配,那么我就可以獲得得分;如果我輸入的單詞錯誤或者時間過長,那么我就會輸 ......

    uj5u.com 2023-04-04 08:35:30 more
  • 了解 HTTP 看這一篇就夠

    在學習網路之前,了解它的歷史能夠幫助我們明白為何它會發展為如今這個樣子,引發探究網路的興趣。下面的這張圖片就展示了“互聯網”誕生至今的發展歷程。 ......

    uj5u.com 2023-03-16 11:00:15 more
  • 藍牙-低功耗中心設備

    //11.開啟藍牙配接器 openBluetoothAdapter //21.開始搜索藍牙設備 startBluetoothDevicesDiscovery //31.開啟監聽搜索藍牙設備 onBluetoothDeviceFound //30.停止監聽搜索藍牙設備 offBluetoothDevi ......

    uj5u.com 2023-03-15 09:06:45 more
  • canvas畫板(滑鼠和觸摸)

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>canves</title> <style> #canvas { cursor:url(../images/pen.png),crosshair; } #canvasdiv{ bo ......

    uj5u.com 2023-02-15 08:56:31 more
  • 手機端H5 實作自定義拍照界面

    手機端 H5 實作自定義拍照界面也可以使用 MediaDevices API 和 <video> 標簽來實作,和在桌面端做法基本一致。 首先,使用 MediaDevices.getUserMedia() 方法獲取攝像頭媒體流,并將其傳遞給 <video> 標簽進行渲染。 接著,使用 HTML 的 < ......

    uj5u.com 2023-01-12 07:58:22 more
  • 記錄--短視頻滑動播放在 H5 下的實作

    這里給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 短視頻已經無數不在了,但是主體還是使用 app 來承載的。本文講述 H5 如何實作 app 的視頻滑動體驗。 無聲勝有聲,一圖頂百辯,且看下圖: 網址鏈接(需在微信或者手Q中瀏覽) 從上圖可以看到,我們主要實作的功能也是本文要講解的有: ......

    uj5u.com 2023-01-04 07:29:05 more
  • 一文讀懂 HTTP/1 HTTP/2 HTTP/3

    從 1989 年萬維網(www)誕生,HTTP(HyperText Transfer Protocol)經歷了眾多版本迭代,WebSocket 也在期間萌芽。1991 年 HTTP0.9 被發明。1996 年出現了 HTTP1.0。2015 年 HTTP2 正式發布。2020 年 HTTP3 或能正... ......

    uj5u.com 2022-12-24 06:56:02 more
  • 【HTML基礎篇002】HTML之form表單超詳解

    ??一、form表單是什么

    ??二、form表單的屬性

    ??三、input中的各種Type屬性值

    ??四、標簽 ......

    uj5u.com 2022-12-18 07:17:06 more