队列工厂之RabbitMQ
本次和大家分享的是RabbitMQ隊(duì)列的用法,前一篇文章隊(duì)列工廠之(MSMQ)中在描述的時(shí)候已經(jīng)搭建了簡(jiǎn)單工廠,因此本章內(nèi)容是在其之上擴(kuò)充的子項(xiàng)不再過(guò)多講解工廠的代碼了;RabbitMQ應(yīng)該是現(xiàn)在互聯(lián)網(wǎng)公司消息隊(duì)列用的最多的一種之一吧,看看招聘基本都會(huì)有這個(gè)單詞的出現(xiàn),她相比前一篇分享的MSMQ來(lái)說(shuō)配置更多樣化,安裝步驟數(shù)兩者都差不多吧,最大差別MSMQ是windows捆綁的服務(wù)幾乎只能在windows上使用,而Rabbit現(xiàn)目前運(yùn)行支持的系統(tǒng)比較多;在寫(xiě)隊(duì)列工廠第二篇文章的時(shí)候,其實(shí)代碼已經(jīng)都完成了目前隊(duì)列工廠包括有如下隊(duì)列(msmq,redis,rabbitmq),你可以去下載源碼和測(cè)試用例:QueueReposity-隊(duì)列工廠;希望大家能夠喜歡,也希望各位多多"掃碼支持"和"推薦"謝謝!
?
??RabbitMQ安裝和控制臺(tái)
??封裝RabbitMQ隊(duì)列的讀和寫(xiě)
??隊(duì)列工廠之RabbitMQ測(cè)試用例
?
下面一步一個(gè)腳印的來(lái)分享:
??RabbitMQ安裝和控制臺(tái)
要說(shuō)RabbitMQ的安裝,首先我們要下載對(duì)應(yīng)服務(wù)器操作系統(tǒng)的RabbitMQ安裝文件,因?yàn)樗袑?duì)應(yīng)不同操作系統(tǒng)的安裝版本,這點(diǎn)需要注意;我本地電腦系統(tǒng)是win7(屬于windows)所以去官網(wǎng)下載安裝包:https://www.rabbitmq.com/,進(jìn)入官網(wǎng)后選擇“Installation”,能看到很多安裝版本的下載源,這里可選擇從Downloads on rabbitmq.com下載,點(diǎn)擊“windows”即可下載:
目前最新版本地址:
https://www.rabbitmq.com/releases/rabbitmq-server/v3.6.6/rabbitmq-server-3.6.6.exe;
通常我都是進(jìn)入這個(gè)界面的Installation Guides節(jié)點(diǎn)后-》With installer (recommended),這個(gè)時(shí)候進(jìn)入的是windows系統(tǒng)所需的幫助文檔吧,同樣可以選擇版本下載;進(jìn)入該界面的主要目的是需要下載一個(gè)Erlang Windows的安裝文件(更深層原因:RabbitMq運(yùn)行依賴于Erlang語(yǔ)言),點(diǎn)擊Erlang Windows Binary File進(jìn)入下載界面,然后選擇您操作系統(tǒng)對(duì)應(yīng)的版本,如果您也是windows64位的可以直接用這個(gè)地址下載:
http://erlang.org/download/otp_win64_19.2.exe
此刻兩個(gè)必須的東西已經(jīng)下載完成,先安裝erlang語(yǔ)言的exe,再安裝rabbitmq-server-3.6.6.exe;有剛開(kāi)始接觸RabbitMQ的朋友會(huì)問(wèn)為什么需要Erlang的支持,因?yàn)樗褪荅rlang開(kāi)發(fā)出來(lái)的,Erlang語(yǔ)言是一種通用的面向并發(fā)的編程語(yǔ)言,專門(mén)用來(lái)編寫(xiě)分布式的一種語(yǔ)言;當(dāng)你安裝前面說(shuō)的那個(gè)erlang安裝包后,您電腦開(kāi)始菜單中就有Erlang開(kāi)發(fā)編輯器,有時(shí)間您可以用來(lái)練練手,就目前而言這種語(yǔ)言單詞一般出現(xiàn)在一流大公司的招聘中,中小型一般沒(méi)有,可能也因?yàn)楹苌僦行⌒凸緯?huì)涉及到并發(fā)的原因吧;到這里安裝就完成了,下面需要通過(guò)命令行執(zhí)行一些指令,由于RabbitMQ配置很多這里我撿一定會(huì)用到的幾個(gè)來(lái)示范,其他具體可以參考官方文檔:
首先找到安裝rabbitmq的目錄并進(jìn)入rabbitmq_server-3.6.6找到sbin文件夾-》按住Shift+鼠標(biāo)右鍵sbin文件夾-》在此處打開(kāi)命令窗體-》參考這個(gè)地址https://www.rabbitmq.com/management.html的命令:rabbitmq-plugins enable rabbitmq_management -》錄入到剛才打開(kāi)的cmd窗體中:
這個(gè)是開(kāi)啟rabbitmq管理器的指令,這個(gè)時(shí)候你可以在你瀏覽器中錄入http://localhost:15672/ 通過(guò)游客賬號(hào)進(jìn)入rabbitmq的監(jiān)控后臺(tái):
url:http://localhost:15672/
Username:guest
Password:guest
此刻如果你看到如下圖的界面,那恭喜你成功了,搭建RabbitMQ服務(wù)成功了:
因?yàn)镽abbit不光有隊(duì)列,還有其他的路由,交換機(jī)等功能,所以能看到很多的統(tǒng)計(jì)或描述,這里我們只用到Queues的選項(xiàng),點(diǎn)擊進(jìn)入Queues界面能看到?jīng)]有任何的數(shù)據(jù),但是有一個(gè)Add queue的按鈕,這個(gè)控制臺(tái)允許你手動(dòng)添加一個(gè)隊(duì)列數(shù)據(jù),當(dāng)然這不是我們今天的話題:
上面的guest已經(jīng)夠咋們測(cè)試使用了,至于剩余的什么管理員賬號(hào)或密碼等操作的設(shè)置可以去看這個(gè):
rabbitmqctl操作的文檔:https://www.rabbitmq.com/man/rabbitmqctl.1.man.html#
plugins操作文檔:https://www.rabbitmq.com/plugins.html
?
??封裝RabbitMQ隊(duì)列的讀和寫(xiě)
在C#中運(yùn)用RabbitMQ官網(wǎng)列舉了幾種方式,這里我選擇直接使用其提供的RabbitMQ.Client的nuget包,就目前這個(gè)nuget而言4.0.0及以上版本必須要NETFramework 4.5.1及以上版本或netcore版本才允許使用,筆者這里用的是Framework4.5框架所以引用了此版本的nuget包:
Install-Package RabbitMQ.Client -Version 3.6.6
引用過(guò)后就是往前面講的隊(duì)列工廠填寫(xiě)代碼,首先繼承統(tǒng)一配置文件讀取類?PublicClass.ConfClass<QRabbitMQ>?,然后實(shí)現(xiàn)?IQueue?接口,這里封裝了RabbitMq常用的幾個(gè)操作方法,具體代碼:
1 /// <summary>2 /// RabbitMq3 /// </summary>4 public class QRabbitMQ : PublicClass.ConfClass<QRabbitMQ>, IQueue5 {6 private IConnection con = null;7 8 public void Create()9 { 10 if (string.IsNullOrWhiteSpace(this.ApiUrl) || string.IsNullOrWhiteSpace(this.ApiKey)) { throw new Exception("創(chuàng)建RabbitMq隊(duì)列需要指定隊(duì)列:HostName和Port"); } 11 12 try 13 { 14 var factory = new ConnectionFactory() { HostName = this.ApiUrl, Port = Convert.ToInt32(this.ApiKey) }; 15 con = con ?? factory.CreateConnection(); 16 } 17 catch (Exception ex) 18 { 19 throw new Exception(ex.Message); 20 } 21 } 22 23 public long Total(string name = "Redis_01") 24 { 25 if (con == null) { throw new Exception("請(qǐng)先創(chuàng)建隊(duì)列連接"); } 26 using (var channel = con.CreateModel()) 27 { 28 return channel.MessageCount(name); 29 } 30 } 31 32 public Message Read(string name = "RabbitMQ_01") 33 { 34 if (con == null) { throw new Exception("請(qǐng)先創(chuàng)建隊(duì)列連接"); } 35 if (string.IsNullOrWhiteSpace(name)) { throw new Exception("name不能為空"); } 36 37 var message = new Message(); 38 message.Label = name; 39 message.Formatter = new XmlMessageFormatter(new Type[] { typeof(string) }); 40 using (var channel = con.CreateModel()) 41 { 42 var baseResult = channel.BasicGet(name, true); //true:獲取后刪除隊(duì)列 false:不刪除 43 if (baseResult == null) { return message; } 44 var body = baseResult.Body; 45 message.Body = Encoding.UTF8.GetString(body); 46 } 47 return message; 48 } 49 50 public bool Write(string content, string name = "RabbitMQ_Queue01") 51 { 52 if (con == null) { throw new Exception("請(qǐng)先創(chuàng)建隊(duì)列連接"); } 53 if (string.IsNullOrWhiteSpace(content) || string.IsNullOrWhiteSpace(name)) { throw new Exception("content和name不能為空"); } 54 55 using (var channel = con.CreateModel()) 56 { 57 channel.QueueDeclare(name, false, false, false, null); 58 var body = Encoding.UTF8.GetBytes(content); 59 60 channel.BasicPublish(string.Empty, name, null, body); 61 return true; 62 } 63 } 64 65 public void Dispose() 66 { 67 if (con != null) 68 { 69 con.Close(); 70 con.Dispose(); 71 con = null; 72 } 73 } 74 }代碼主要使用流程是:創(chuàng)建(Create)-》讀(Read)|寫(xiě)(Write)-》釋放(Dispose);有了具體的RabbitMq實(shí)現(xiàn)類,那么在工廠中直接通過(guò)泛型映射來(lái)獲取該實(shí)現(xiàn)類的對(duì)象:
1 /// <summary>2 /// ==================3 /// author:神牛步行34 /// des:該列工廠開(kāi)源,包括隊(duì)列有MSMQ,RedisMQ,RabbitMQ5 /// blogs:http://www.cnblogs.com/wangrudong003/6 /// ==================7 /// 隊(duì)列工廠8 /// </summary>9 public class QueueReposity<T> where T : class,IQueue, new() 10 { 11 public static IQueue Current 12 { 13 get 14 { 15 return PublicClass.ConfClass<T>.Current; 16 } 17 } 18 }?
??隊(duì)列工廠之RabbitMQ測(cè)試用例
通過(guò)上面配置環(huán)境和封裝自己的方法,這里寫(xiě)了一個(gè)簡(jiǎn)單的測(cè)試用例,分為Server(加入消息隊(duì)列)和Client(獲取消息隊(duì)列),首先來(lái)看Server端的代碼:
1 /// <summary>2 /// 隊(duì)列服務(wù)端測(cè)試用例3 /// </summary>4 class Program5 {6 static void Main(string[] args)7 {8 //Redis_Server();9 10 RabbitMQ_Server(); 11 12 //MSMQ_Server(); 13 } 14 private static void RabbitMQ_Server() 15 { 16 //實(shí)例化QMsmq對(duì)象 17 var mq = QueueReposity<QRabbitMQ>.Current; 18 19 try 20 { 21 Console.WriteLine("Server端創(chuàng)建:RabbitMQ實(shí)例"); 22 mq.Create(); 23 24 var num = 0; 25 do 26 { 27 Console.WriteLine("輸入循環(huán)數(shù)量(數(shù)字,0表示結(jié)束):"); 28 var readStr = Console.ReadLine(); 29 num = string.IsNullOrWhiteSpace(readStr) ? 0 : Convert.ToInt32(readStr); 30 31 Console.WriteLine("插入數(shù)據(jù):"); 32 for (int i = 0; i < num; i++) 33 { 34 var str = "我的編號(hào)是:" + i; 35 mq.Write(str); 36 Console.WriteLine(str); 37 } 38 } while (num > 0); 39 } 40 catch (Exception ex) 41 { 42 } 43 finally 44 { 45 Console.WriteLine("釋放。"); 46 mq.Dispose(); 47 } 48 Console.ReadLine(); 49 } 50 }通過(guò):創(chuàng)建(Create)-》讀(Read)|寫(xiě)(Write)-》釋放(Dispose) 的流程來(lái)使用我們的隊(duì)列工廠,感覺(jué)挺簡(jiǎn)單的,此時(shí)我們運(yùn)行下這個(gè)Server端,然后錄入?yún)?shù):
這個(gè)時(shí)候就往RabbitMq隊(duì)列中加入了11條數(shù)據(jù),我們通過(guò)她的后臺(tái)去找剛才添加的隊(duì)列:
能夠看到我們剛剛插入的隊(duì)列總數(shù)和名稱,如果你想看里面具體內(nèi)容,可以點(diǎn)擊名字“mq_01”進(jìn)入某一個(gè)隊(duì)列的界面,往下面拉滾動(dòng)條找到“Get messages”選項(xiàng),默認(rèn)查看Messages是1我們修改為10,再點(diǎn)擊get messages就能夠看到如下圖我們剛才插入的具體內(nèi)容了:
截圖有點(diǎn)長(zhǎng)哦,不知道dudu會(huì)不會(huì)怪我哈哈,到這里能看到隊(duì)列插入是成功的,然后我們來(lái)通過(guò)client端消費(fèi)隊(duì)列,具體代碼:
1 /// <summary>2 /// 隊(duì)列客戶端測(cè)試用例3 /// </summary>4 class Program5 {6 static void Main(string[] args)7 {8 //RedisMQ_Client();9 10 RabbitMQ_Client(); 11 12 //MSMQ_Client(); 13 } 14 15 private static void RabbitMQ_Client() 16 { 17 //實(shí)例化QMsmq對(duì)象 18 var mq = QueueReposity<QRabbitMQ>.Current; 19 try 20 { 21 Console.WriteLine("Client端創(chuàng)建:RabbitMQ實(shí)例"); 22 mq.Create(); 23 24 while (true) 25 { 26 try 27 { 28 var total = mq.Total(); 29 if (total > 0) { Console.WriteLine("隊(duì)列條數(shù):" + total); } 30 31 var result = mq.Read(); 32 if (result.Body == null) { continue; } 33 Console.WriteLine(string.Format("接受隊(duì)列{0}:{1}", result.Label, result.Body)); 34 } 35 catch (Exception ex) 36 { Console.WriteLine("異常信息:" + ex.Message); } 37 } 38 } 39 catch (Exception ex) 40 { 41 throw ex; 42 } 43 finally 44 { 45 Console.WriteLine("釋放。"); 46 mq.Dispose(); 47 } 48 } 49 }再來(lái)咋們運(yùn)行exe看下效果:
此刻剛剛加入隊(duì)列中的數(shù)據(jù)就讀取出來(lái)了,這個(gè)時(shí)候我們?cè)倏碦abbitmq控制臺(tái),get messages已經(jīng)獲取不出來(lái)具體的內(nèi)容信息了,因?yàn)檫@個(gè)客戶端消費(fèi)了數(shù)據(jù),隊(duì)列中的數(shù)據(jù)自動(dòng)清除了,至于是否想清除數(shù)據(jù)這個(gè)設(shè)置在代碼:
1 var baseResult = channel.BasicGet(name, true); //true:獲取后刪除隊(duì)列 false:不刪除以上對(duì)封裝RabbitMQ的代碼分享和環(huán)境搭建講解,希望能給您帶來(lái)好的幫助,謝謝閱讀;
與50位技術(shù)專家面對(duì)面20年技術(shù)見(jiàn)證,附贈(zèng)技術(shù)全景圖總結(jié)
以上是生活随笔為你收集整理的队列工厂之RabbitMQ的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Hystrix之Dashboard的常见
- 下一篇: C与C++的内存机制的比较