1,隊列的概念
只允許在一端插入數據操作,在另一端進行刪除數據操作的特殊線性表;進行插入操作的一端稱為隊尾(入隊列),進行刪除操作的一端稱為隊頭(出隊列);隊列具有先進先出(FIFO)的特性。
2,順序隊列
(1)隊頭不動,出隊列時隊頭后的所有元素向前移動
缺陷:操作是如果出隊列比較多,要搬移大量元素
(2)隊頭移動,出隊列時隊頭向后移動一個位置
如果還有新元素進行入隊列容易造成假溢出。
假溢出:順序隊列因多次入隊列和出隊列操作后出現的尚有存儲空間但是不能進行入隊操作的溢出。
真溢出:順序隊列的最大存儲空間已經存滿而又要求進行入隊列操作所引起的溢出。
3.循環隊列
循環隊列如何進行判 空和滿 操作:
少用一個存儲單元
設置一個標記flag
初始值 flag=0;入隊列:flag=1;出隊列:flag=0
隊列為空時:(front == rear && flag==0)
隊列為滿時:(front == rear && flag == 1)
設置一個計數器
4,鏈式隊列
鏈式隊列:特殊單鏈表,只在單鏈表上進行頭刪尾插的操作
【1.定義一個隊列結構體】
由於是鏈式隊列,所有先定義一個存放數據域和指針域的結構體
隊列結構體中定義一個隊頭指針和隊尾指針
[3.初始化隊列]
讓隊列的隊頭,隊尾分別指向空
[4.入隊列]
判斷隊中是否有元素
找到隊尾元素
讓新入隊的元素鏈在原先隊列的隊尾上,更新新的隊尾
這里的出隊列采用是讓隊頭元素不斷后移,刷新隊頭元素,這樣優化時間效率
一,消息隊列概述
消息隊列,是分布式系統中重要的組件,其通用的使用場景可以簡單地描述為:
當不需要立即獲取結果,但是並發量又需要進行控制的時候,差不多就是需要使用消息隊列的時候。
消息隊列主要解決了應用耦合、異步處理、流量削鋒等問題。
當前使用較多的消息隊列又RabbitMQ、RocketMQ\ActiveMQ\Kafka\ZeroMQ、MetaMq等,而部分數據庫如Redis、Mysql以及phxsql也實現消息隊列的功能。
二、消息隊列使用場景
消息隊列在實際應用中包括如下四個場景:
應用耦合:多應用間通過消息隊列對同一消息進行處理,避免調用接口失敗導致整個過程失敗;
異步處理:多應用對消息隊列中同一消息進行處理,應用間並發處理消息,相比串行處理,減少處理時間;
限流削峰:廣泛應用於秒殺或搶購活動中,避免流量過大導致應用系統掛掉的情況
消息驅動的系統:系統分為消息隊列、消息生產者、消息消費者、生產者負責產生消息,消費者(可能有多個)負責對消息進行處理;
2.1 異步處理
具體場景:用戶為了使用某個應用,進行注冊,系統需要發送注冊郵件並驗證短信。對這兩個操作的處理方式有兩種:串行及並行
(1)串行方式:新注冊信息生成后,先發送注冊郵件,再發送驗證短信;
(2)並發處理:新注冊信息寫入后,由發短信和發郵件並行處理;
在這種方式下,發短信和發郵件,需處理完成后在返回給客戶端。
假設以上三個子系統處理的時間均為50ms,且不考慮網絡延遲,則總的處理時間
串行:50+50+50 = 150ms
並行:50+50 = 100ms
如使用消息隊列:
並在寫入消息隊列后立即返回成功給客戶端,則總的響應時間依賴於寫入消息隊列的時間,而寫入消息隊列的時間本身是可以很快的,基本可以忽略不計,因此總的處理時間相比串行提高了2倍,相比並行提高了一倍;
2.2 應用耦合
具體場景:用戶使用QQ相冊上傳一張圖片,人臉識別系統會對該圖片進行人臉識別,一般的做法是,服務器接收到圖片后,圖片上傳系統立即調用人臉識別,調用完成后再返回成功,如下圖所示:
該方法有如下缺點:
人臉識別系統被調失敗,導致圖片上傳失敗;
延遲高,需要人臉識別系統處理完成后,在返回給客戶端,即使用戶並不需要立即知道結果;
圖片上傳系統與人臉識別系統之間互相調用,需要做耦合;
若使用消息隊列:
客戶端上傳圖片后,圖片上傳系統將圖片信息如uin,批次寫入消息隊列,直接返回成功;而人臉識別系統則定時從消息隊列中取數據,完成對新增圖片的識別。
此時圖片上傳系統並不需要關心人臉識別系統是否對這些圖片信息的處理、以及何時對這些圖片信息進行處理。事實上,由於用戶並不需要立即知道人臉識別結果,人臉識別系統可以選擇不同的調度策略,按照閑時、忙時、正常時間,對隊列中的圖片信息進行處理。
2.3 限流削峰
具體場景:購物網站開展秒殺活動,一般由於瞬時訪問量過大,服務器接受過大,會導致流量暴增,相關系統無法處理請求甚至崩潰。而加入消息隊列后,系列可以從消息隊列中取數據,相當於消息隊列做了以次緩沖。
該方法有如下優點:
1,請求先入消息隊列,而不是由業務處理系統直接處理,做了一次緩存,極大地減少業務處理系統壓力:
2,隊列長度可以做限制,事實上,秒殺時,后入隊列的用戶無法秒殺到商品,這些請求可以直接被拋棄,返回活動已結束或商品已售完信息;
2.4 消息驅動的系統
具體場景:用戶新上傳了一批照片,人臉識別系統需要對這個用戶的所有照片進行聚類,聚類完成后由對賬系統重新生成用戶的人臉索引(加快查詢)。這三個子系統間消息隊列連接起來,前一個階段的處理結果放入隊列中,后一個階段從隊列中獲取消息繼續處理。
該方式有如下優點:
避免了直接調用下一個系統導致當前系統失敗:
每個系統對於消息的處理方式可以更為靈活,可以選擇收到消息時就處理,可以選擇定時處理,也可以划分時間段按不同處理速度處理;
三,消息隊列的兩種模式
消息隊列包括兩種模式,點對點模式(point to point ,queue)和發布/訂閱模式(publish/subscribe , topic)
3.1 點對點模式
點對點模式下包括三個角色
消息隊列
發送者(生產者)
接收者(消費者)
消息發送者生產消息發送到queue中,然后消息接收者從queue取出並且消費消息。消息被消費以后,queue中不再有存儲,所以消息接收者不可能消費到已經被消費的消息。
點對點模式特點:
每個消息只有一個接收者(Consumer)(即一旦被消息,消息就不再在消息隊列中):
發送者和接收者間沒有依賴性,發送者發送消息之后,不管有沒有接收者在運行,都不會影響到發送者下次發送消息
接收者在成功接收消息之后需向隊列應答成功,以便消息隊列刪除當前接收的消息
3.2 發布/訂閱模式
發布/訂閱模式下包括三個角色:
角色主題
發布者
訂閱者
發布/訂閱模式特點:
每個消息可以有多個訂閱者;
發布者和訂閱者之間有時間上的依賴性。針對某個主題的訂閱者,它必須創建一個訂閱者之后,才能消費發布者的消息。
為了消費消息,訂閱者需要提前訂閱該角色主題,並保持在線運行;
四,常用消息隊列介紹
本部分主要介紹四種常用的消息隊列(RabbitMQ/ActiveMQ/RocketMQ/Kafka)的主要特性、優點、缺點。
4.1 RabbitMQ
RabbitMQ 2007年發布,是一個在AMQP(高級消息隊列協議)基礎上完成的,可復用的企業消息系統,是當前最主流的消息中間件之一。
主要特性:
1.可靠性:提供多種技術可以讓你在性能和可靠性之間進行權衡。這些技術包括持久性機制、投遞確認、發布者證實和高可用性機制;
2,靈活的路由:消息在到達隊列前是通過交換機進行路由的。RabbitMQ典型的路由邏輯提供了多種內置交換機類型。如果你有更復雜的路由需求,可以將這些交換機組合起來使用,你甚至可以實現自己的交換機類型,並且當作RabbitMQ的插件來使用;
3消息集群:在相同局域網中的多個RabbitMQ服務器可以聚合在一起,作為一個獨立的邏輯代理來使用;
4,隊列高可用:隊列可以在集群中的機器上進行鏡像,以確保在硬件問題下還保證消息安全;
5,多種協議的支持:支持多種消息隊列協議;
6,服務器端用Erlang語言編寫,支持只要是你能想到的所有編程語言;
7,管理界面:RabbitMQ有一個易用的用戶界面,使得用戶可以監控和管理消息Broker的許多方面;
8,跟蹤機制:如果消息異常,RabbitMQ提供消息跟蹤機制,使用者可以找出發生了什么;
9,插件機制:提供了許多插件,來從多方面進行擴展,也可以編寫自己的插件
使用RabbitMQ需要:
Erlang語言包
RabbitMQ安裝包
RabbiMQ可以運行在Erlang語言所支持的平台之上:
Solatis BSD Linux MacOSX TRU64 Windows NT/2000/XP/Vista/Windows 7/Windows 8
Windows Server 2003/2008/2012
Windows 95,98
VxWorks
優點:
1.由於erland 語言的特性,mq性能較好,高並發
2,健壯、穩定、易用、跨平台、支持多種語言、文檔齊全
3,有消息確認機制和持久化機制,可靠性高
4,高度可定制的路由
5,管理界面較豐富,在互聯網公司也有較大規模的應用
6,社區活躍度高
缺點:
1,盡量結合erlang語言本身的並發優勢,性能較好,但是不利於做二次開發和維護
2,實現了代理架構,意味着消息在發送到客戶端之前可以在中央節點上排隊。此特性使得RabbitMQ易於使用和部署,但是使得其運行速度較慢,因為中央節點增加了延遲,消息封裝后也比較大;
3,需要學習比較復雜的接口和協議,學習和維護成本較高
4.2 Kafka
Apacha Kafka是一個分布式消息發布訂閱系統。它最初由LinkedIn公司基於獨特的設計實現為一個分布式的提交日志系統(a distributed commit log),之后稱為Apache項目的一部分。Kafka系統快速、可擴展並且可持久化。他的分區特性,可復制和可容錯都是其不錯的特性,
主要特性:
1,快速持久化,可以在O(1)的系統開銷下進行消息持久化
2,高吞吐,在一台普通的服務器上既可以達到10w/s的吞吐率
3,完全的分布式系統,Broker、Producer、Consumer都原生自動支持分布式,自動實現負載均衡
4,支持同步和異步復制兩種HA
5,支持數據批量發送和拉取
6,zero-copy:減少IO操作步棸;
7,數據遷移,擴容對用戶透明
8,無需停機即可擴展機器
9,其他特性:嚴格的消息順序、豐富的消息拉取模型、高校訂閱者水平擴展、實時的消息訂閱、億級的消息堆積能力、定期刪除機制
使用Kafka需要
java JDK
kafka 安裝包
優點:
1,客戶端語言豐富,支持java、.net、php、ruby、python、go等多種語言
2,性能卓越,單機寫入TPS約在百萬條/秒,消息大小10個字節
3,提供完全分布式架構,並有replica機制,擁有較高的可用性和可靠性,理論上支持消息無限堆積
4,支持批量操作
5,消費者采用pull方式獲取消息,消息有序,通過控制能夠保證所有消息被消息且僅被消息一次
6,有優秀的第三檔Kafka Web管理界面Kafka-Manager
7,在日志領域比較成熟,被多家公司和多個開源項目使用;
缺點
1,kafka單機超過64個隊列/分區,load會發生明顯得飆高現象,隊列越多,load越高,發送消息時間邊長
2,使用短輪詢方式,實時性取決於輪詢間隔時間
3,消費失敗不支持重試
4,支持消息順序,但是一台代理宕機后,就會產生消息亂序
5,社區更新較慢
五、參考資料:
5.1 消息隊列:
-
大型網站架構之分布式消息隊列 http://blog.csdn.net/shaobingj126/article/details/50585035
-
消息隊列的使用場景 https://www.zhihu.com/question/34243607/answer/127666030
-
淺談異步消息隊列模型 http://www.cnblogs.com/sunkeydev/p/5248855.html
-
消息隊列的兩種模式 http://blog.csdn.net/heyutao007/article/details/50131089
5.2 RabbitMQ
-
RabbitMQ主頁 https://www.rabbitmq.com/
-
RabbitMQ學習教程 https://www.rabbitmq.com/getstarted.html
-
專欄:RabbitMQ從入門到精通 http://blog.csdn.net/column/details/rabbitmq.html
-
RabbitMQ能為你做些什么 http://rabbitmq.mr-ping.com/description.html
-
RabbitMQ指南(1)-特性及功能 https://blog.zenfery.cc/archives/79.html
5.3 ActiveMQ
-
ActiveMQ主頁 http://activemq.apache.org/
-
Apache ActiveMQ介紹 http://jfires.iteye.com/blog/1187688
-
ActiveMQ的簡介與安裝 http://blog.csdn.net/sl1992/article/details/72824562
-
ActiveMQ 和消息簡介 http://www.cnblogs.com/craftsman-gao/p/7002605.html
5.4 RocketMQ
-
主頁 https://github.com/alibaba/RocketMQ
-
RocketMQ 原理簡介 http://alibaba.github.io/RocketMQ-docs/document/design/RocketMQ_design.pdf
-
RocketMQ與kafka對比(18項差異) http://jm.taobao.org/2016/03/24/rmq-vs-kafka/
5.5 Kafka
1.Kafka主頁: http://kafka.apache.org/
-
Kafka特性 http://www.cnblogs.com/lsx1993/p/4847719.html
-
Kafka客戶端支持語言 https://cwiki.apache.org/confluence/display/KAFKA/Clients
5.6 RabbitMQ/ActiveMQ/RocketMQ/Kafka對比
-
RocketMQ,隊列選型 http://www.zmannotes.com/index.php/2016/01/17/rocketmq/
-
RabbitMQ和Kafka http://www.dongcoder.com/detail-416804.html
-
即時通信RabbitMQ二-性能測試 http://www.jianshu.com/p/d31ae9e3bfb6
-
RabbitMq、ActiveMq、ZeroMq、kafka之間的比較,資料匯總 http://blog.csdn.net/linsongbin1/article/details/47781187
-
消息隊列軟件產品大比拼 http://www.cnblogs.com/amityat/archive/2011/08/31/2160293.html
總結:
消息隊列利用有效可靠得消息傳遞機制進行平台無關得數據交流,並基於數據通信來進行分布式系統得集成。也有直接使用數據庫redis充當消息隊列得案例。而這些消息隊列產品,各有側重,在實際選型時,需要結合自身需求及MQ產品特性,綜合考慮。