国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

新手也能看懂,消息隊列其實很簡單

Clect / 695人閱讀

摘要:通過以上分析我們可以得出消息隊列具有很好的削峰作用的功能即通過異步處理,將短時間高并發(fā)產(chǎn)生的事務(wù)消息存儲在消息隊列中,從而削平高峰期的并發(fā)事務(wù)。

該文已加入開源項目:JavaGuide(一份涵蓋大部分Java程序員所需要掌握的核心知識的文檔類項目,Star 數(shù)接近 16k)。地址:https://github.com/Snailclimb...

本文內(nèi)容思維導(dǎo)圖:

消息隊列其實很簡單

  “RabbitMQ?”“Kafka?”“RocketMQ?”...在日常學(xué)習(xí)與開發(fā)過程中,我們常常聽到消息隊列這個關(guān)鍵詞。我也在我的多篇文章中提到了這個概念。可能你是熟練使用消息隊列的老手,又或者你是不懂消息隊列的新手,不論你了不了解消息隊列,本文都將帶你搞懂消息隊列的一些基本理論。如果你是老手,你可能從本文學(xué)到你之前不曾注意的一些關(guān)于消息隊列的重要概念,如果你是新手,相信本文將是你打開消息隊列大門的一板磚。

一 什么是消息隊列

  我們可以把消息隊列比作是一個存放消息的容器,當(dāng)我們需要使用消息的時候可以取出消息供自己使用。消息隊列是分布式系統(tǒng)中重要的組件,使用消息隊列主要是為了通過異步處理提高系統(tǒng)性能和削峰、降低系統(tǒng)耦合性。目前使用較多的消息隊列有ActiveMQ,RabbitMQ,Kafka,RocketMQ,我們后面會一一對比這些消息隊列。

  另外,我們知道隊列 Queue 是一種先進先出的數(shù)據(jù)結(jié)構(gòu),所以消費消息時也是按照順序來消費的。比如生產(chǎn)者發(fā)送消息1,2,3...對于消費者就會按照1,2,3...的順序來消費。但是偶爾也會出現(xiàn)消息被消費的順序不對的情況,比如某個消息消費失敗又或者一個 queue 多個consumer 也會導(dǎo)致消息被消費的順序不對,我們一定要保證消息被消費的順序正確。

  除了上面說的消息消費順序的問題,使用消息隊列,我們還要考慮如何保證消息不被重復(fù)消費?如何保證消息的可靠性傳輸(如何處理消息丟失的問題)?......等等問題。所以說使用消息隊列也不是十全十美的,使用它也會讓系統(tǒng)可用性降低、復(fù)雜度提高,另外需要我們保障一致性等問題。

二 為什么要用消息隊列

  我覺得使用消息隊列主要有兩點好處:1.通過異步處理提高系統(tǒng)性能(削峰、減少響應(yīng)所需時間);2.降低系統(tǒng)耦合性。如果在面試的時候你被面試官問到這個問題的話,一般情況是你在你的簡歷上涉及到消息隊列這方面的內(nèi)容,這個時候推薦你結(jié)合你自己的項目來回答。

  《大型網(wǎng)站技術(shù)架構(gòu)》第四章和第七章均有提到消息隊列對應(yīng)用性能及擴展性的提升。

(1) 通過異步處理提高系統(tǒng)性能(削峰、減少響應(yīng)所需時間)


  如上圖,在不使用消息隊列服務(wù)器的時候,用戶的請求數(shù)據(jù)直接寫入數(shù)據(jù)庫,在高并發(fā)的情況下數(shù)據(jù)庫壓力劇增,使得響應(yīng)速度變慢。但是在使用消息隊列之后,用戶的請求數(shù)據(jù)發(fā)送給消息隊列之后立即 返回,再由消息隊列的消費者進程從消息隊列中獲取數(shù)據(jù),異步寫入數(shù)據(jù)庫。由于消息隊列服務(wù)器處理速度快于數(shù)據(jù)庫(消息隊列也比數(shù)據(jù)庫有更好的伸縮性),因此響應(yīng)速度得到大幅改善。

  通過以上分析我們可以得出消息隊列具有很好的削峰作用的功能——即通過異步處理,將短時間高并發(fā)產(chǎn)生的事務(wù)消息存儲在消息隊列中,從而削平高峰期的并發(fā)事務(wù)。 舉例:在電子商務(wù)一些秒殺、促銷活動中,合理使用消息隊列可以有效抵御促銷活動剛開始大量訂單涌入對系統(tǒng)的沖擊。如下圖所示:

  因為用戶請求數(shù)據(jù)寫入消息隊列之后就立即返回給用戶了,但是請求數(shù)據(jù)在后續(xù)的業(yè)務(wù)校驗、寫數(shù)據(jù)庫等操作中可能失敗。因此使用消息隊列進行異步處理之后,需要適當(dāng)修改業(yè)務(wù)流程進行配合,比如用戶在提交訂單之后,訂單數(shù)據(jù)寫入消息隊列,不能立即返回用戶訂單提交成功,需要在消息隊列的訂單消費者進程真正處理完該訂單之后,甚至出庫后,再通過電子郵件或短信通知用戶訂單成功,以免交易糾紛。這就類似我們平時手機訂火車票和電影票。

(2) 降低系統(tǒng)耦合性

  我們知道如果模塊之間不存在直接調(diào)用,那么新增模塊或者修改模塊就對其他模塊影響較小,這樣系統(tǒng)的可擴展性無疑更好一些。

  我們最常見的事件驅(qū)動架構(gòu)類似生產(chǎn)者消費者模式,在大型網(wǎng)站中通常用利用消息隊列實現(xiàn)事件驅(qū)動結(jié)構(gòu)。如下圖所示:

  消息隊列使利用發(fā)布-訂閱模式工作,消息發(fā)送者(生產(chǎn)者)發(fā)布消息,一個或多個消息接受者(消費者)訂閱消息。 從上圖可以看到消息發(fā)送者(生產(chǎn)者)和消息接受者(消費者)之間沒有直接耦合,消息發(fā)送者將消息發(fā)送至分布式消息隊列即結(jié)束對消息的處理,消息接受者從分布式消息隊列獲取該消息后進行后續(xù)處理,并不需要知道該消息從何而來。對新增業(yè)務(wù),只要對該類消息感興趣,即可訂閱該消息,對原有系統(tǒng)和業(yè)務(wù)沒有任何影響,從而實現(xiàn)網(wǎng)站業(yè)務(wù)的可擴展性設(shè)計

  消息接受者對消息進行過濾、處理、包裝后,構(gòu)造成一個新的消息類型,將消息繼續(xù)發(fā)送出去,等待其他消息接受者訂閱該消息。因此基于事件(消息對象)驅(qū)動的業(yè)務(wù)架構(gòu)可以是一系列流程。

  另外為了避免消息隊列服務(wù)器宕機造成消息丟失,會將成功發(fā)送到消息隊列的消息存儲在消息生產(chǎn)者服務(wù)器上,等消息真正被消費者服務(wù)器處理后才刪除消息。在消息隊列服務(wù)器宕機后,生產(chǎn)者服務(wù)器會選擇分布式消息隊列服務(wù)器集群中的其他服務(wù)器發(fā)布消息。

備注: 不要認為消息隊列只能利用發(fā)布-訂閱模式工作,只不過在解耦這個特定業(yè)務(wù)環(huán)境下是使用發(fā)布-訂閱模式的。除了發(fā)布-訂閱模式,還有點對點訂閱模式(一個消息只有一個消費者),我們比較常用的是發(fā)布-訂閱模式。 另外,這兩種消息模型是 JMS 提供的,AMQP 協(xié)議還提供了 5 種消息模型。

三 使用消息隊列帶來的一些問題

系統(tǒng)可用性降低: 系統(tǒng)可用性在某種程度上降低,為什么這樣說呢?在加入MQ之前,你不用考慮消息丟失或者說MQ掛掉等等的情況,但是,引入MQ之后你就需要去考慮了!

系統(tǒng)復(fù)雜性提高: 加入MQ之后,你需要保證消息沒有被重復(fù)消費、處理消息丟失的情況、保證消息傳遞的順序性等等問題!

一致性問題: 我上面講了消息隊列可以實現(xiàn)異步,消息隊列帶來的異步確實可以提高系統(tǒng)響應(yīng)速度。但是,萬一消息的真正消費者并沒有正確消費消息怎么辦?這樣就會導(dǎo)致數(shù)據(jù)不一致的情況了!

四 JMS VS AMQP 4.1 JMS 4.1.1 JMS 簡介

  JMS(JAVA Message Service,java消息服務(wù))是java的消息服務(wù),JMS的客戶端之間可以通過JMS服務(wù)進行異步的消息傳輸。JMS(JAVA Message Service,Java消息服務(wù))API是一個消息服務(wù)的標(biāo)準(zhǔn)或者說是規(guī)范,允許應(yīng)用程序組件基于JavaEE平臺創(chuàng)建、發(fā)送、接收和讀取消息。它使分布式通信耦合度更低,消息服務(wù)更加可靠以及異步性。

ActiveMQ 就是基于 JMS 規(guī)范實現(xiàn)的。

4.1.2 JMS兩種消息模型

①點到點(P2P)模型


  使用隊列(Queue)作為消息通信載體;滿足生產(chǎn)者與消費者模式,一條消息只能被一個消費者使用,未被消費的消息在隊列中保留直到被消費或超時。比如:我們生產(chǎn)者發(fā)送100條消息的話,兩個消費者來消費一般情況下兩個消費者會按照消息發(fā)送的順序各自消費一半(也就是你一個我一個的消費。)

② 發(fā)布/訂閱(Pub/Sub)模型


  發(fā)布訂閱模型(Pub/Sub) 使用主題(Topic)作為消息通信載體,類似于廣播模式;發(fā)布者發(fā)布一條消息,該消息通過主題傳遞給所有的訂閱者,在一條消息廣播之后才訂閱的用戶則是收不到該條消息的

4.1.3 JMS 五種不同的消息正文格式

  JMS定義了五種不同的消息正文格式,以及調(diào)用的消息類型,允許你發(fā)送并接收以一些不同形式的數(shù)據(jù),提供現(xiàn)有消息格式的一些級別的兼容性。

StreamMessage -- Java原始值的數(shù)據(jù)流

MapMessage--一套名稱-值對

TextMessage--一個字符串對象

ObjectMessage--一個序列化的 Java對象

BytesMessage--一個字節(jié)的數(shù)據(jù)流

4.2 AMQP

  ? AMQP,即Advanced Message Queuing Protocol,一個提供統(tǒng)一消息服務(wù)的應(yīng)用層標(biāo)準(zhǔn) 高級消息隊列協(xié)議(二進制應(yīng)用層協(xié)議),是應(yīng)用層協(xié)議的一個開放標(biāo)準(zhǔn),為面向消息的中間件設(shè)計,兼容 JMS。基于此協(xié)議的客戶端與消息中間件可傳遞消息,并不受客戶端/中間件同產(chǎn)品,不同的開發(fā)語言等條件的限制。

RabbitMQ 就是基于 AMQP 協(xié)議實現(xiàn)的。

4.3 JMS vs AMQP
對比方向 JMS AMQP
定義 Java API 協(xié)議
跨語言
跨平臺
支持消息類型 提供兩種消息模型:①Peer-2-Peer;②Pub/sub 提供了五種消息模型:①direct exchange;②fanout exchange;③topic change;④headers exchange;⑤system exchange。本質(zhì)來講,后四種和JMS的pub/sub模型沒有太大差別,僅是在路由機制上做了更詳細的劃分;
支持消息類型 支持多種消息類型 ,我們在上面提到過 byte[](二進制)

總結(jié):

AMQP 為消息定義了線路層(wire-level protocol)的協(xié)議,而JMS所定義的是API規(guī)范。在 Java 體系中,多個client均可以通過JMS進行交互,不需要應(yīng)用修改代碼,但是其對跨平臺的支持較差。而AMQP天然具有跨平臺、跨語言特性。

JMS 支持TextMessage、MapMessage 等復(fù)雜的消息類型;而 AMQP 僅支持 byte[] 消息類型(復(fù)雜的類型可序列化后發(fā)送)。

由于Exchange 提供的路由算法,AMQP可以提供多樣化的路由方式來傳遞消息到消息隊列,而 JMS 僅支持 隊列 和 主題/訂閱 方式兩種。

五 常見的消息隊列對比
對比方向 概要
吞吐量 萬級的 ActiveMQ 和 RabbitMQ 的吞吐量(ActiveMQ 的性能最差)要比 十萬級甚至是百萬級的 RocketMQ 和 Kafka 低一個數(shù)量級。
可用性 都可以實現(xiàn)高可用。ActiveMQ 和 RabbitMQ 都是基于主從架構(gòu)實現(xiàn)高可用性。RocketMQ 基于分布式架構(gòu)。 kafka 也是分布式的,一個數(shù)據(jù)多個副本,少數(shù)機器宕機,不會丟失數(shù)據(jù),不會導(dǎo)致不可用
時效性 RabbitMQ 基于erlang開發(fā),所以并發(fā)能力很強,性能極其好,延時很低,達到微秒級。其他三個都是 ms 級。
功能支持 除了 Kafka,其他三個功能都較為完備。 Kafka 功能較為簡單,主要支持簡單的MQ功能,在大數(shù)據(jù)領(lǐng)域的實時計算以及日志采集被大規(guī)模使用,是事實上的標(biāo)準(zhǔn)
消息丟失 ActiveMQ 和 RabbitMQ 丟失的可能性非常低, RocketMQ 和 Kafka 理論上不會丟失。

總結(jié):

ActiveMQ 的社區(qū)算是比較成熟,但是較目前來說,ActiveMQ 的性能比較差,而且版本迭代很慢,不推薦使用。

RabbitMQ 在吞吐量方面雖然稍遜于 Kafka 和 RocketMQ ,但是由于它基于 erlang 開發(fā),所以并發(fā)能力很強,性能極其好,延時很低,達到微秒級。但是也因為 RabbitMQ 基于 erlang 開發(fā),所以國內(nèi)很少有公司有實力做erlang源碼級別的研究和定制。如果業(yè)務(wù)場景對并發(fā)量要求不是太高(十萬級、百萬級),那這四種消息隊列中,RabbitMQ 一定是你的首選。如果是大數(shù)據(jù)領(lǐng)域的實時計算、日志采集等場景,用 Kafka 是業(yè)內(nèi)標(biāo)準(zhǔn)的,絕對沒問題,社區(qū)活躍度很高,絕對不會黃,何況幾乎是全世界這個領(lǐng)域的事實性規(guī)范。

RocketMQ 阿里出品,Java 系開源項目,源代碼我們可以直接閱讀,然后可以定制自己公司的MQ,并且 RocketMQ 有阿里巴巴的實際業(yè)務(wù)場景的實戰(zhàn)考驗。RocketMQ 社區(qū)活躍度相對較為一般,不過也還可以,文檔相對來說簡單一些,然后接口這塊不是按照標(biāo)準(zhǔn) JMS 規(guī)范走的有些系統(tǒng)要遷移需要修改大量代碼。還有就是阿里出臺的技術(shù),你得做好這個技術(shù)萬一被拋棄,社區(qū)黃掉的風(fēng)險,那如果你們公司有技術(shù)實力我覺得用RocketMQ 挺好的

kafka 的特點其實很明顯,就是僅僅提供較少的核心功能,但是提供超高的吞吐量,ms 級的延遲,極高的可用性以及可靠性,而且分布式可以任意擴展。同時 kafka 最好是支撐較少的 topic 數(shù)量即可,保證其超高吞吐量。kafka 唯一的一點劣勢是有可能消息重復(fù)消費,那么對數(shù)據(jù)準(zhǔn)確性會造成極其輕微的影響,在大數(shù)據(jù)領(lǐng)域中以及日志采集中,這點輕微影響可以忽略這個特性天然適合大數(shù)據(jù)實時計算以及日志收集。

參考:《Java工程師面試突擊第1季-中華石杉老師》

ThoughtWorks準(zhǔn)入職Java工程師。專注Java知識分享!開源 Java 學(xué)習(xí)指南——JavaGuide(15k+ Star)的作者。公眾號多篇文章被各大技術(shù)社區(qū)轉(zhuǎn)載。公眾號后臺回復(fù)關(guān)鍵字“1”可以領(lǐng)取一份我精選的Java資源哦!

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/72733.html

相關(guān)文章

  • 一定能看懂的RocketMQ事務(wù)消息源碼分析(干貨)

    摘要:但是服務(wù)器又確實是收到了這條消息的,只是給客戶端的響應(yīng)丟失了,所以導(dǎo)致的結(jié)果就是扣款失敗,成功發(fā)貨。既然消息的發(fā)送不能和本地事務(wù)寫在一起,那如何來保證其整體具有原子性的需求呢答案就是今天我們介紹的主角事務(wù)消息。 前言 得益于MQ削峰填谷,系統(tǒng)解耦,操作異步等功能特性,在互聯(lián)網(wǎng)行業(yè),可以說有分布式服務(wù)的地方,MQ都往往不會缺席。由阿里自研的RocketMQ更是經(jīng)歷了多年的雙十一高并發(fā)挑戰(zhàn)...

    myshell 評論0 收藏0
  • 我的第一篇博客

    摘要:前言說來慚愧,馬上就要到而立之年,可是嚴格來講這應(yīng)該算是我的第一篇博客。堅持萬事開頭難,這第一篇博客寫完我更是覺得寫博客其實并沒有那么簡單,有時候覺得很簡單的東西可能寫出來就不是那么回事了。 前言 說來慚愧,馬上就要到而立之年,可是嚴格來講這應(yīng)該算是我的第一篇博客。 從第一行Hello World至今,算一算和代碼打交道也有些年頭了,其實我本人一直以來都有記筆記和寫demo的習(xí)慣,最早...

    Nekron 評論0 收藏0
  • 【C++從0到1】新手都能看懂的C++入門(上篇),建議收藏

    摘要:上面這三種均不造成重載,現(xiàn)在來說明原因。結(jié)論對于引用返回,返回的對象必須是棧幀銷毀后還存在的。全局,靜態(tài),未銷毀的函數(shù)棧幀當(dāng)中的都是可以的指針與引用如圖兩者底層實現(xiàn)差不多,引用是用指針模擬的。不建議聲明和定義分離,分離會導(dǎo)致鏈接錯誤。 ...

    xcold 評論0 收藏0
  • 超詳細,新手都能看懂 !使用SpringBoot+Dubbo 搭建一個簡單的分布式服務(wù)

    Github 地址:https://github.com/Snailclimb/springboot-integration-examples ,歡迎各位 Star。 目錄: 使用 SpringBoot+Dubbo 搭建一個簡單分布式服務(wù) 實戰(zhàn)之前,先來看幾個重要的概念 什么是分布式? 什么是 Duboo? Dubbo 架構(gòu) 什么是 RPC? 為什么要用 Dubbo? 開始實戰(zhàn) 1 ...

    chengtao1633 評論0 收藏0
  • Laravel 5.4 入門系列 13. 終篇: 小白也能看懂的 Laravel 核心概念講解

    摘要:但是服務(wù)通常由服務(wù)提供者來管理的。小結(jié)通過上述的例子,基本上可以理解服務(wù)容器和服務(wù)提供者的使用。懂得了服務(wù)容器和服務(wù)提供者,理解門面也就不難了。 自動依賴注入 什么是依賴注入,用大白話將通過類型提示的方式向函數(shù)傳遞參數(shù)。 實例 1 首先,定義一個類: /routes/web.php class Bar {} 假如我們在其他地方要使用到 Bar 提供的功能(服務(wù)),怎么辦,直接傳入?yún)?shù)即...

    BenCHou 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<