版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第8章SpringBoot其他功能——異步消息SpringBoot實(shí)用教程(第4版)目錄01異步消息模型及中間件1.異步消息模型2.JMS3.AMQP4.消息中間件異步消息模型及中間件1.異步消息模型在SpringBoot中,異步消息是通過(guò)“消息代理”實(shí)現(xiàn)的,當(dāng)發(fā)送者發(fā)出消息后,消息將暫時(shí)先由消息代理保管,消息代理將消息存入一個(gè)隊(duì)列(Queue),當(dāng)有接收者要求接收消息時(shí),消息代理再?gòu)年?duì)列中取出消息傳遞給接收者,然后清除該消息(這時(shí)候隊(duì)列里已經(jīng)沒(méi)有這條消息了),如圖8.1所示。異步消息模型及中間件2.JMSJMS(JavaMessageService,Java消息服務(wù))是Java平臺(tái)上面向消息中間件的技術(shù)規(guī)范,它的設(shè)計(jì)目標(biāo)是為方便系統(tǒng)中Java應(yīng)用程序間的消息交換,并且通過(guò)提供標(biāo)準(zhǔn)的產(chǎn)生、發(fā)送、接收消息的接口來(lái)簡(jiǎn)化異步消息功能開(kāi)發(fā)。JMS所提供的接口主要有:(1)ConnectionFactory(連接工廠)它是用戶創(chuàng)建的到JMS消息代理連接的被管對(duì)象,JMS客戶通過(guò)可移植的接口訪問(wèn)連接,這樣當(dāng)?shù)讓拥膶?shí)現(xiàn)改變時(shí),上層代碼無(wú)須改動(dòng)。(2)Connection(連接對(duì)象)連接對(duì)象代表了一條應(yīng)用程序和消息代理之間的通信鏈路。在獲得了連接工廠后,就可以創(chuàng)建一個(gè)與JMS消息代理的連接,它允許用戶進(jìn)一步創(chuàng)建會(huì)話以發(fā)送消息到目的地,或從目的地接收消息。(3)Destination(目的地)目的地是指消息發(fā)布和接收的地點(diǎn),它是包裝了目的地標(biāo)識(shí)符的被管對(duì)象,由JMS管理員創(chuàng)建這些對(duì)象,然后用戶通過(guò)JNDI來(lái)發(fā)現(xiàn)它們。(4)Session(會(huì)話)會(huì)話表示一個(gè)單線程的上下文,用于發(fā)送和接收消息。會(huì)話可以支持事務(wù),如果用戶選擇了事務(wù)支持,會(huì)話上下文將保存一組消息,直到事務(wù)被提交才發(fā)送這些消息。而在提交事務(wù)之前,用戶可以使用回滾操作取消這些消息。異步消息模型及中間件(5)MessageProducer(生產(chǎn)者)生產(chǎn)者是由會(huì)話創(chuàng)建的對(duì)象,用于發(fā)送消息到目的地。用戶既可以創(chuàng)建某個(gè)目的地的生產(chǎn)者,也可以創(chuàng)建一個(gè)通用的生產(chǎn)者,待發(fā)送消息時(shí)再指定其目的地。(6)MessageConsumer(消費(fèi)者)消費(fèi)者也是由會(huì)話創(chuàng)建的對(duì)象,用于接收目的地的消息。(7)Message(消息)消息是在生產(chǎn)者和消費(fèi)者之間傳送的對(duì)象,實(shí)際上就是從一個(gè)應(yīng)用程序傳送到另一個(gè)應(yīng)用程序的對(duì)象。一個(gè)消息由3個(gè)主要部分構(gòu)成。①消息頭(必須):包含用于識(shí)別和為消息尋找路由的操作設(shè)置。②屬性(可選):一組多個(gè)消息屬性可用于創(chuàng)建定制的字段和過(guò)濾器(消息選擇器),另外還包含額外的屬性以支持其他消息代理實(shí)現(xiàn)和用戶的兼容。③消息體(可選):消息可以有一個(gè)消息體,JMS允許用戶創(chuàng)建文本、映射、字節(jié)、流和對(duì)象這5種不同類型的消息體。異步消息模型及中間件3.AMQPAMQP的基本概念如下:(1)客戶端AMQP連接或會(huì)話的發(fā)起者。AMQP是非對(duì)稱的,客戶端生產(chǎn)和消費(fèi)消息,服務(wù)器存儲(chǔ)和路由這些消息。(2)服務(wù)器接受客戶端連接,實(shí)現(xiàn)AMQP消息隊(duì)列和路由功能的進(jìn)程,實(shí)際上也就是消息代理的實(shí)現(xiàn)(中間件)。(3)AMQP模型它是一個(gè)由關(guān)鍵實(shí)體和語(yǔ)義表示的邏輯框架,遵從AMQP規(guī)范的服務(wù)器必須提供這些實(shí)體和語(yǔ)義。為了實(shí)現(xiàn)規(guī)范中定義的語(yǔ)義,客戶端可以發(fā)送命令來(lái)控制AMQP服務(wù)器。(4)連接一個(gè)網(wǎng)絡(luò)連接,例如TCP/IP套接字連接。(5)端點(diǎn)一個(gè)AMQP連接包括兩個(gè)端點(diǎn),一個(gè)是客戶端,一個(gè)是服務(wù)器。(6)搭檔當(dāng)描述兩個(gè)端點(diǎn)之間的交互過(guò)程時(shí),使用術(shù)語(yǔ)“搭檔”來(lái)表示“另一個(gè)”端點(diǎn)的簡(jiǎn)記法。例如定義端點(diǎn)A和端點(diǎn)B,當(dāng)它們進(jìn)行通信時(shí),端點(diǎn)B就是端點(diǎn)A的搭檔,端點(diǎn)A也是端點(diǎn)B的搭檔。異步消息模型及中間件(7)會(huì)話端點(diǎn)之間的命名對(duì)話,在一個(gè)會(huì)話上下文中,保證消息“恰好傳遞一次”。(8)信道多路復(fù)用連接中的一條獨(dú)立的雙向數(shù)據(jù)流通道,為會(huì)話提供物理傳輸介質(zhì)。(9)幀AMQP傳輸?shù)囊粋€(gè)原子單元。(10)段幀的有序集合,形成一個(gè)完整子單元。(11)片段集段的有序集合,形成一個(gè)邏輯工作單元。(12)消息頭描述消息數(shù)據(jù)屬性的一種特殊段。(13)消息體包含應(yīng)用程序數(shù)據(jù)的一種特殊段。消息體對(duì)于服務(wù)器來(lái)說(shuō)完全透明,即服務(wù)器不能查看或修改消息體。(14)消息內(nèi)容包含在消息體中的數(shù)據(jù)。異步消息模型及中間件(15)消息隊(duì)列一個(gè)命名實(shí)體,用來(lái)保存消息直到消費(fèi)者接收。(16)消費(fèi)者一個(gè)從消息隊(duì)列中請(qǐng)求消息的客戶端應(yīng)用程序。(17)生產(chǎn)者一個(gè)向交換器發(fā)布消息的客戶端應(yīng)用程序。(18)控制單向指令,AMQP規(guī)范假設(shè)這些指令的傳輸是不可靠的。(19)命令需要確認(rèn)的指令,AMQP規(guī)范規(guī)定這些指令的傳輸是可靠的。(20)異常在執(zhí)行一個(gè)或多個(gè)命令時(shí)可能發(fā)生的錯(cuò)誤狀態(tài)。(21)類一批用來(lái)描述某種特定功能的AMQP命令或者控制。(22)交換器服務(wù)器中的實(shí)體,用來(lái)接收生產(chǎn)者發(fā)送的消息并將這些消息路由給服務(wù)器中的隊(duì)列。異步消息模型及中間件(23)交換器類型基于不同路由語(yǔ)義的交換器類。(24)綁定器消息隊(duì)列和交換器之間的關(guān)聯(lián)。(25)綁定器關(guān)鍵字綁定的名稱。一些交換器類型可能使用這個(gè)名稱作為定義綁定器路由行為的模式。(26)路由關(guān)鍵字一個(gè)消息頭,交換器可以用它來(lái)決定如何路由某條消息。(27)持久存儲(chǔ)一種服務(wù)器資源,當(dāng)服務(wù)器重啟時(shí),保存的消息數(shù)據(jù)不會(huì)丟失。(28)臨時(shí)存儲(chǔ)一種服務(wù)器資源,當(dāng)服務(wù)器重啟時(shí),保存的消息數(shù)據(jù)會(huì)丟失。(29)持久化服務(wù)器將消息保存在可靠磁盤存儲(chǔ)中,當(dāng)服務(wù)器重啟時(shí),消息不會(huì)丟失。(30)非持久化服務(wù)器將消息保存在內(nèi)存中,當(dāng)服務(wù)器重啟時(shí),消息可能丟失。(31)虛擬主機(jī)一批交換器、消息隊(duì)列及相關(guān)對(duì)象。虛擬主機(jī)是共享相同的身份認(rèn)證和加密環(huán)境的獨(dú)立服務(wù)器域??蛻舳藨?yīng)用程序在登錄到服務(wù)器之后,可選擇一個(gè)虛擬主機(jī)。異步消息模型及中間件4.消息中間件基于上述這兩種規(guī)范,很多廠商和開(kāi)發(fā)者社區(qū)紛紛推出各自的消息中間件產(chǎn)品,其中比較著名的有:Apache基金會(huì)的ActiveMQ和Kafka、JBoss社區(qū)的HornetQ、TheOpenJMSGroup的OpenJMS、Rabbit科技的RabbitMQ等。當(dāng)前最為主流的兩大消息中間件是ActiveMQ和RabbitMQ。ActiveMQ是JMS的實(shí)現(xiàn),而RabbitMQ則是AMQP的實(shí)現(xiàn)。SpringBoot為這兩個(gè)中間件都提供了很好的支持,它們?cè)趹?yīng)用功能上的地位和作用是對(duì)等的,實(shí)際開(kāi)發(fā)中可根據(jù)需求和使用偏好選用任意一款。目錄02ActiveMQ實(shí)現(xiàn)異步消息1.ActiveMQ安裝使用2.發(fā)送者程序3.接收者程序ActiveMQ實(shí)現(xiàn)異步消息【實(shí)例8.1】用ActiveMQ作為消息中間件,發(fā)送者(商家)在頁(yè)面上編輯并發(fā)出商品降價(jià)促銷信息,接收者(顧客)打開(kāi)頁(yè)面可看到該信息。1.ActiveMQ安裝使用(1)下載ActiveMQ訪問(wèn)ActiveMQ官網(wǎng)/,如圖8.2所示,點(diǎn)頁(yè)面左塊“ActiveMQ"Classic"”區(qū)的“DownloadLatest”按鈕轉(zhuǎn)至下載頁(yè)。ActiveMQ實(shí)現(xiàn)異步消息在下載頁(yè)(/components/classic/download/)上點(diǎn)鏈接“apache-activemq-5.16.3-bin.zip”下載Windows版的ActiveMQ,如圖8.3所示。ActiveMQ實(shí)現(xiàn)異步消息(2)啟動(dòng)ActiveMQ①打開(kāi)解壓的ActiveMQ存盤目錄,從其下\conf目錄中找到配置文件activemq.xml,打開(kāi),找到并注釋掉其中的一行(如下加黑):...<transportConnectors><!--DOSprotection,limitconcurrentconnectionsto1000andframesizeto100MB--><transportConnectorname="openwire"uri="tcp://:61616?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/><!--<transportConnectorname="amqp"uri="amqp://:5672?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>--><transportConnectorname="stomp"uri="stomp://:61613?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/><transportConnectorname="mqtt"uri="mqtt://:1883?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/><transportConnectorname="ws"uri="ws://:61614?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/></transportConnectors>...ActiveMQ實(shí)現(xiàn)異步消息操作如圖8.4所示。ActiveMQ實(shí)現(xiàn)異步消息②進(jìn)入ActiveMQ存盤目錄下的\bin\win64子目錄(注:因筆者的計(jì)算機(jī)操作系統(tǒng)是64位,若用的是32位系統(tǒng),則要進(jìn)入\bin\win32子目錄),看到有一個(gè)activemq.bat文件,如圖8.5所示,雙擊即可啟動(dòng)ActiveMQ。ActiveMQ實(shí)現(xiàn)異步消息此時(shí),彈出命令行窗口如圖8.6所示,輸出啟動(dòng)信息,沒(méi)有錯(cuò)誤就是啟動(dòng)成功。ActiveMQ實(shí)現(xiàn)異步消息(3)訪問(wèn)ActiveMQ打開(kāi)瀏覽器,地址欄輸入http://localhost:8161回車,出現(xiàn)登錄界面如圖8.7所示。ActiveMQ實(shí)現(xiàn)異步消息輸入用戶名密碼(默認(rèn)都是admin),點(diǎn)“登錄”按鈕進(jìn)入ActiveMQ的歡迎頁(yè)面,如圖8.8所示。ActiveMQ實(shí)現(xiàn)異步消息(4)查看消息隊(duì)列在后面運(yùn)行程序時(shí),需要時(shí)刻查看ActiveMQ所管理隊(duì)列中的消息,這里簡(jiǎn)要介紹一下操作方法。①在ActiveMQ歡迎頁(yè)面上點(diǎn)“ManageActiveMQbroker”鏈接(見(jiàn)上圖),進(jìn)入ActiveMQ的管理頁(yè)面,如圖8.9所示。②點(diǎn)管理頁(yè)面導(dǎo)航欄上的“Queues”項(xiàng),轉(zhuǎn)至隊(duì)列查看頁(yè)面,如圖8.10所示。
ActiveMQ實(shí)現(xiàn)異步消息2.發(fā)送者程序先來(lái)開(kāi)發(fā)發(fā)送者程序,步驟如下。(1)創(chuàng)建項(xiàng)目創(chuàng)建SpringBoot項(xiàng)目,項(xiàng)目名為ActiveSender,在出現(xiàn)的向?qū)Ы缑妗癉ependencies”列表中勾選SpringBoot基本框架(“Web”→“SpringWeb”)、Thymeleaf引擎組件(“TemplateEngines”→“Thymeleaf”)、Lombok模型簡(jiǎn)化組件(“DeveloperTools”→“Lombok”)。為使項(xiàng)目支持ActiveMQ,最重要的是添加SpringActiveMQ框架,勾選“Messaging”→“SpringforApacheActiveMQ5”,如圖8.11所示。添加的SpringActiveMQ框架在項(xiàng)目pom.xml文件中對(duì)應(yīng)的依賴項(xiàng)為:<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-activemq</artifactId></dependency>ActiveMQ實(shí)現(xiàn)異步消息(2)配置代理地址在項(xiàng)目perties文件中配置ActiveMQ消息代理的地址:spring.activemq.broker-url=tcp://localhost:61616這個(gè)地址及端口號(hào)是ActiveMQ默認(rèn)的,一般不要改變。ActiveMQ實(shí)現(xiàn)異步消息packagecom.example.activesender.entity;
importlombok.Data;importorg.springframework.jms.core.MessageCreator;
importjavax.jms.JMSException;importjavax.jms.Message;importjavax.jms.Session;
@DatapublicclassMsgimplementsMessageCreator{ privateStringtext;
@Override publicMessagecreateMessage(Sessionsession)throwsJMSException{ returnsession.createTextMessage(this.text); }}(3)定義消息實(shí)體基于JMS規(guī)范的消息實(shí)體需實(shí)現(xiàn)MessageCreator接口,并重寫其createMessage方法。在項(xiàng)目工程目錄樹(shù)的com.example.activesender節(jié)點(diǎn)下創(chuàng)建entity包,其中創(chuàng)建消息實(shí)體類Msg.java,代碼如下:ActiveMQ實(shí)現(xiàn)異步消息(4)開(kāi)發(fā)控制器在控制器中用SpringBoot配置好的JmsTemplate模板向ActiveMQ發(fā)消息。在項(xiàng)目工程目錄樹(shù)的com.example.activesender節(jié)點(diǎn)下創(chuàng)建controller包,其中創(chuàng)建控制器類SendController.java,代碼如下:packagecom.example.activesender.controller;
importcom.example.activesender.entity.Msg;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.jms.core.JmsTemplate;importorg.springframework.stereotype.Controller;importorg.springframework.ui.Model;importorg.springframework.web.bind.annotation.RequestMapping;
@Controller@RequestMapping("msg")publicclassSendController{ @AutowiredJmsTemplatejmsTemplate; //注入JmsTemplate模板
@RequestMapping("/input") publicStringsendMsg(Modelmodel,Msgmsg){ if(msg.getText()!=null&&msg.getText()!=""){jmsTemplate.send("商品促銷通知",msg); }model.addAttribute("msg",msg); return"input"; }}ActiveMQ實(shí)現(xiàn)異步消息(5)前端頁(yè)面在項(xiàng)目工程目錄樹(shù)的src→main→resources→templates下創(chuàng)建前端頁(yè)面input.html,代碼為:<!DOCTYPEhtml><htmllang="en"xmlns:th=""><head><metacharset="UTF-8"><title>消息錄入</title></head><bodybgcolor="#e0ffff"><br><formth:action="@{/msg/input}"th:object="${msg}"method="post"><inputth:type="text"th:field="*{text}"th:placeholder="請(qǐng)輸入消息內(nèi)容"/><inputth:type="submit"value="發(fā)送"></form><br><pth:text="'您編輯的內(nèi)容【'+${msg.text}+'】已發(fā)送至ActiveMQ保存。'"th:if="${msg.text!=null&&msg.text!=''}"/></body></html>ActiveMQ實(shí)現(xiàn)異步消息(6)運(yùn)行確保已經(jīng)啟動(dòng)了ActiveMQ。啟動(dòng)項(xiàng)目,打開(kāi)瀏覽器,在地址欄輸入http://localhost:8080/msg/input回車,顯示頁(yè)面如圖8.12所示。ActiveMQ實(shí)現(xiàn)異步消息在文本框中輸入消息內(nèi)容,點(diǎn)“發(fā)送”按鈕,下面顯示文字提示消息已被發(fā)送至ActiveMQ。此時(shí),查看ActiveMQ的隊(duì)列,可看到保存在其中的消息條目,如圖8.13所示。ActiveMQ實(shí)現(xiàn)異步消息消息條目各字段的含義如圖8.14所示,其中,“NumberOfPendingMessages”是等待接收者接收的消息數(shù),當(dāng)前為1條;“NumberOfConsumers”是消費(fèi)者,也就是接收者的個(gè)數(shù),由于當(dāng)前尚未有接收者程序在運(yùn)行,故個(gè)數(shù)顯示為0;“MessagesEnqueued”是進(jìn)入隊(duì)列的消息數(shù),為1條;“MessagesDequeued”表示移出隊(duì)列的消息數(shù),由于隊(duì)列中的這條消息還未被任何接收者接收,故暫時(shí)不能移出隊(duì)列,值為0。ActiveMQ實(shí)現(xiàn)異步消息3.接收者程序要進(jìn)一步測(cè)試消息的接收過(guò)程,必須要有個(gè)接收者程序,步驟如下。(1)創(chuàng)建項(xiàng)目創(chuàng)建SpringBoot項(xiàng)目,項(xiàng)目名為ActiveReceiver,在出現(xiàn)的向?qū)Ы缑妗癉ependencies”列表中勾選SpringBoot基本框架(“Web”→“SpringWeb”)、Thymeleaf引擎組件(“TemplateEngines”→“Thymeleaf”)、SpringActiveMQ框架(“Messaging”→“SpringforApacheActiveMQ5”)。(2)配置代理地址與發(fā)送者程序的配置完全一樣,在項(xiàng)目perties文件中配置:spring.activemq.broker-url=tcp://localhost:61616ActiveMQ實(shí)現(xiàn)異步消息(3)開(kāi)發(fā)接收器接收器作為一個(gè)組件(以@Component注解),監(jiān)聽(tīng)和接收來(lái)自消息代理(ActiveMQ)特定目的地隊(duì)列中的消息。在項(xiàng)目工程目錄樹(shù)的com.example.activereceiver節(jié)點(diǎn)下創(chuàng)建component包,其中創(chuàng)建接收器類Receiver.java,代碼如下:packageponent;
importorg.springframework.jms.annotation.JmsListener;importorg.springframework.stereotype.Component;
@ComponentpublicclassReceiver{ privateStringtext; //存儲(chǔ)消息內(nèi)容
@JmsListener(destination="商品促銷通知") publicvoidreceiveMsg(Stringmessage){this.text=message; }
publicStringgetText(){ returnthis.text; }}ActiveMQ實(shí)現(xiàn)異步消息(4)開(kāi)發(fā)控制器在控制器中注入接收器,將接收到的消息內(nèi)容發(fā)往前端頁(yè)面。在項(xiàng)目工程目錄樹(shù)的com.example.activereceiver節(jié)點(diǎn)下創(chuàng)建controller包,其中創(chuàng)建控制器類ReceiveController.java,代碼如下:packagecom.example.activereceiver.controller;
importponent.Receiver;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.stereotype.Controller;importorg.springframework.ui.Model;importorg.springframework.web.bind.annotation.RequestMapping;
@Controller@RequestMapping("msg")publicclassReceiveController{ @AutowiredReceiverreceiver; //注入接收器
@RequestMapping("/show") publicStringshowMsg(Modelmodel){model.addAttribute("text",receiver.getText());//獲取接收器中的消息內(nèi)容 return"show"; }}ActiveMQ實(shí)現(xiàn)異步消息(5)前端頁(yè)面在項(xiàng)目工程目錄樹(shù)的src→main→resources→templates下創(chuàng)建前端頁(yè)面show.html,代碼為:<!DOCTYPEhtml><htmllang="en"xmlns:th=""><head><metacharset="UTF-8"><title>消息顯示</title></head><bodybgcolor="#e0ffff"><br><pth:text="'收到來(lái)自ActiveMQ的消息【'+${text}+'】。'"th:if="${text!=null&&text!=''}"/></body></html>ActiveMQ實(shí)現(xiàn)異步消息(6)運(yùn)行確保ActiveMQ已經(jīng)啟動(dòng)運(yùn)行。啟動(dòng)項(xiàng)目,打開(kāi)瀏覽器,在地址欄輸入http://localhost:8080/msg/show回車,顯示頁(yè)面如圖8.15所示。此時(shí),查看ActiveMQ的隊(duì)列,看到消息條目中各字段的值已經(jīng)發(fā)生了改變,如圖8.16所示。目錄03RabbitMQ實(shí)現(xiàn)異步消息1.RabbitMQ安裝使用2.發(fā)送者程序3.接收者程序RabbitMQ實(shí)現(xiàn)異步消息【實(shí)例8.2】用RabbitMQ作為消息中間件,實(shí)現(xiàn)與【實(shí)例8.2】同樣的異步消息收發(fā)功能。1.RabbitMQ安裝使用RabbitMQ是流行的開(kāi)源消息隊(duì)列系統(tǒng),用Erlang語(yǔ)言開(kāi)發(fā),故要使用它必須先安裝Erlang。1)安裝Erlang(1)下載ErlangErlang下載地址為/downloads,下載得到可執(zhí)行程序安裝包otp_win64_24.0.exe。(2)安裝Erlang雙擊安裝包文件otp_win64_24.0.exe,啟動(dòng)安裝向?qū)Вx擇要安裝的組件,這里采用默認(rèn)選項(xiàng),如圖8.17所示。RabbitMQ實(shí)現(xiàn)異步消息單擊“Next”按鈕,指定安裝路徑,筆者安裝到C:\ProgramFiles\erl-24.0,如圖8.18所示。RabbitMQ實(shí)現(xiàn)異步消息(3)配置環(huán)境變量安裝完后需要為Erlang配置環(huán)境變量,這樣后面安裝的RabbitMQ才能找到并借助Erlang運(yùn)行。在計(jì)算機(jī)操作系統(tǒng)中右擊“此電腦”→“屬性”→“高級(jí)系統(tǒng)設(shè)置”,打開(kāi)“系統(tǒng)屬性”對(duì)話框,點(diǎn)“環(huán)境變量”按鈕,打開(kāi)“環(huán)境變量”對(duì)話框。新建一個(gè)系統(tǒng)變量ERLANG_HOME,變量值設(shè)為Erlang的安裝路徑,如圖8.19所示。RabbitMQ實(shí)現(xiàn)異步消息然后編輯Path系統(tǒng)變量,添加上Erlang的條目“%ERLANG_HOME%\bin”,如圖8.20所示。RabbitMQ實(shí)現(xiàn)異步消息(4)安裝RabbitMQ-Plugins插件這個(gè)插件實(shí)際上就是一個(gè)管理界面,方便用戶在瀏覽器中可視化地查看RabbitMQ各個(gè)消息隊(duì)列的工作情況。打開(kāi)Windows命令行,輸入:rabbitmq-pluginsenablerabbitmq_management運(yùn)行狀態(tài)如圖8.25所示,表示安裝成功。RabbitMQ實(shí)現(xiàn)異步消息(5)將RabbitMQ啟動(dòng)為Windows服務(wù)以管理員身份進(jìn)入Windows命令行,輸入:netstartRabbitMQ回車后出現(xiàn)提示信息“請(qǐng)求的服務(wù)已經(jīng)啟動(dòng)。...”表示成功了,如圖8.26所示。RabbitMQ實(shí)現(xiàn)異步消息在計(jì)算機(jī)操作系統(tǒng)中右擊“此電腦”→“管理”,打開(kāi)“計(jì)算機(jī)管理”窗口,在“服務(wù)和應(yīng)用程序”→“服務(wù)”頁(yè)列表中可找到一個(gè)名為“RabbitMQ”的服務(wù),這個(gè)就是RabbitMQ所對(duì)應(yīng)的Windows服務(wù),如圖8.27所示。RabbitMQ實(shí)現(xiàn)異步消息(6)測(cè)試安裝以管理員身份打開(kāi)Windows命令行,輸入rabbitmqctlstatus如果出現(xiàn)如圖8.28所示的狀態(tài)信息,無(wú)報(bào)錯(cuò),就說(shuō)明安裝是成功的,并且說(shuō)明現(xiàn)在RabbitMQ服務(wù)運(yùn)行正常。RabbitMQ實(shí)現(xiàn)異步消息3)使用RabbitMQ(1)訪問(wèn)RabbitMQ打開(kāi)瀏覽器,地址欄輸入http://localhost:15672回車,出現(xiàn)登錄界面如圖8.29所示。RabbitMQ實(shí)現(xiàn)異步消息輸入用戶名密碼(默認(rèn)都是guest),點(diǎn)“Login”按鈕進(jìn)入RabbitMQ的管理頁(yè)面,如圖8.30所示。RabbitMQ實(shí)現(xiàn)異步消息(2)查看消息隊(duì)列點(diǎn)擊管理頁(yè)面導(dǎo)航欄上的“Queues”項(xiàng),轉(zhuǎn)至隊(duì)列查看頁(yè)面,如圖8.31所示。RabbitMQ實(shí)現(xiàn)異步消息2.發(fā)送者程序先來(lái)開(kāi)發(fā)發(fā)送者程序,步驟如下。(1)創(chuàng)建項(xiàng)目創(chuàng)建SpringBoot項(xiàng)目,項(xiàng)目名為RabbitSender,在出現(xiàn)的向?qū)Ы缑妗癉ependencies”列表中勾選SpringBoot基本框架(“Web”→“SpringWeb”)、Thymeleaf引擎組件(“TemplateEngines”→“Thymeleaf”)、Lombok模型簡(jiǎn)化組件(“DeveloperTools”→“Lombok”)。為使項(xiàng)目支持RabbitMQ,最重要的是添加SpringRabbitMQ框架,勾選“Messaging”→“SpringforRabbitMQ”,如圖8.32所示。添加的SpringRabbitMQ框架在項(xiàng)目pom.xml文件中對(duì)應(yīng)的依賴項(xiàng)為:<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId></dependency>RabbitMQ實(shí)現(xiàn)異步消息RabbitMQ實(shí)現(xiàn)異步消息(2)定義消息實(shí)體與JMS不同,AMQP規(guī)范對(duì)消息實(shí)體并無(wú)特別的要求,直接寫一個(gè)簡(jiǎn)單的模型類即可。在項(xiàng)目工程目錄樹(shù)的com.example.rabbitsender節(jié)點(diǎn)下創(chuàng)建entity包,其中創(chuàng)建消息實(shí)體類Msg.java,代碼如下:packagecom.example.rabbitsender.entity;
importlombok.Data;
@DatapublicclassMsg{ privateStringtext;}(3)開(kāi)發(fā)控制器在控制器中用SpringBoot配置好的RabbitTemplate模板向RabbitMQ發(fā)消息。在項(xiàng)目工程目錄樹(shù)的com.example.rabbitsender節(jié)點(diǎn)下創(chuàng)建controller包,其中創(chuàng)建控制器類SendController.java,代碼顯示。RabbitMQ實(shí)現(xiàn)異步消息(4)前端頁(yè)面在項(xiàng)目工程目錄樹(shù)的src→main→resources→templates下創(chuàng)建前端頁(yè)面input.html,代碼為:<!DOCTYPEhtml><htmllang="en"xmlns:th=""><head><metacharset="UTF-8"><title>消息錄入</title></head><bodybgcolor="#e0ffff"><br><formth:action="@{/msg/input}"th:object="${msg}"method="post"><inputth:type="text"th:field="*{text}"th:placeholder="請(qǐng)輸入消息內(nèi)容"/><inputth:type="submit"value="發(fā)送"></form><br><pth:text="'您編輯的內(nèi)容【'+${msg.text}+'】已發(fā)送至RabbitMQ保存。'"th:if="${msg.text!=null&&msg.text!=''}"/></body></html>RabbitMQ實(shí)現(xiàn)異步消息(5)運(yùn)行啟動(dòng)項(xiàng)目,打開(kāi)瀏覽器,在地址欄輸入http://localhost:8080/msg/input回車,顯示頁(yè)面如圖8.33所示。RabbitMQ實(shí)現(xiàn)異步消息在文本框中輸入消息內(nèi)容,點(diǎn)“發(fā)送”按鈕,下面顯示文字提示消息已被發(fā)送至RabbitMQ。此時(shí),查看RabbitMQ的隊(duì)列,可看到保存在其中的消息條目,如圖8.34所示。RabbitMQ實(shí)現(xiàn)異步消息3.接收者程序接下來(lái)繼續(xù)開(kāi)發(fā)接收者程序,步驟如下。(1)創(chuàng)建項(xiàng)目創(chuàng)建SpringBoot項(xiàng)目,項(xiàng)目名為RabbitReceiver,在出現(xiàn)的向?qū)Ы缑妗癉ependencies”列表中勾選SpringBoot基本框架(“Web”→“SpringWeb”)、Thymeleaf引擎組件(“TemplateEngines”→“Thymeleaf”)、SpringRabbitMQ框架(“Messaging”→“SpringforRabbitMQ”)。(2)開(kāi)發(fā)接收器接收器同樣作為一個(gè)組件(@Component注解),監(jiān)聽(tīng)和接收來(lái)自消息代理(RabbitMQ)特定目的地隊(duì)列中的消息。RabbitMQ實(shí)現(xiàn)異步消息在項(xiàng)目工程目錄樹(shù)的com.example.rabbitreceiver節(jié)點(diǎn)下創(chuàng)建component包,其中創(chuàng)建接收器類Receiver.java,代碼如下:packageponent;
importorg.springframework.amqp.rabbit.annotation.RabbitListener;importorg.springframework.stereotype.Component;
@ComponentpublicclassReceiver{privateStringtext; //存儲(chǔ)消息內(nèi)容
@RabbitListener(queues="商品促銷通知") publicvoidreceiveMsg(Stringmessage){this.text=message; }
publicStringgetText(){ returnthis.text; }}RabbitMQ實(shí)現(xiàn)異步消息(3)開(kāi)發(fā)控制器在控制器中注入接收器,將接收到的消息內(nèi)容發(fā)往前端頁(yè)面。在項(xiàng)目工程目錄樹(shù)的com.example.rabbitreceiver節(jié)點(diǎn)下創(chuàng)建controller包,其中創(chuàng)建控制器類ReceiveController.java,代碼如下:packagecom.example.rabbitreceiver.controller;
importponent.Receiver;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.stereotype.Controller;importorg.springframework.ui.Model;importorg.springframework.web.bind.annotation.RequestMapping;
@Controller@RequestMapping("msg")publicclassReceiveController{ @AutowiredReceiverreceiver; //注入接收器
@RequestMapping("/show") publicStringshowMsg(Modelmodel){model.addAttribute("text",receiver.getText()); //獲取接收器中的消息內(nèi)容 return"show"; }}RabbitMQ實(shí)現(xiàn)異步消息(4)前端頁(yè)面在項(xiàng)目工程目錄樹(shù)的src→main→resources→templates下創(chuàng)建前端頁(yè)面show.html,代碼為:<!DOCTYPEhtml><htmllang="en"xmlns:th=""><head><metacharset="UTF-8"><title>消息顯示</title></head><bodybgcolor="#e0ffff"><br><pth:text="'收到來(lái)自RabbitMQ的消息【'+${text}+'】。'"th:if="${text!=null&&text!=''}"/></body></html>RabbitMQ實(shí)現(xiàn)異步消息(5)運(yùn)行啟動(dòng)項(xiàng)目,打開(kāi)瀏覽器,在地址欄輸入http://localhost:8080/msg/show回車,顯示頁(yè)面如圖8.35所示。RabbitMQ實(shí)現(xiàn)異步消息此時(shí),查看RabbitMQ的隊(duì)列,看到消息條目中各字段的值已經(jīng)發(fā)生了改變,如圖8.36所示。第8章SpringBoot其他功能——WebFlux響應(yīng)式編程初步SpringBoot實(shí)用教程(第4版)目錄01響應(yīng)式編程概述1.需求場(chǎng)景2.Reactor模式3.WebFlux框架4.開(kāi)發(fā)方式5.?dāng)?shù)據(jù)庫(kù)選擇響應(yīng)式編程概述
1.需求場(chǎng)景目前,在SpringBoot所集成的Web核心編程框架(也就是本書前面所有實(shí)例在創(chuàng)建項(xiàng)目時(shí)所勾選的SpringBoot基本框架“Web”→“SpringWeb”)內(nèi)部是基于單線程阻塞機(jī)制工作的,其基本工作模式為:主線程接受用戶請(qǐng)求→執(zhí)行任務(wù)(包括操作后臺(tái)、處理數(shù)據(jù)...)→包裝數(shù)據(jù)、向前端返回響應(yīng)。這種模式在通常絕大多數(shù)的應(yīng)用場(chǎng)景下都能夠工作得很好,但若遇到高并發(fā)請(qǐng)求耗時(shí)任務(wù)的情形卻難以勝任,例如,短時(shí)間內(nèi)有大量用戶同時(shí)向同一個(gè)服務(wù)器線程發(fā)起請(qǐng)求,而它們要服務(wù)器完成的又都是需要耗費(fèi)比較長(zhǎng)時(shí)間的任務(wù),服務(wù)器只能先處理完第1個(gè)用戶的任務(wù)并返回響應(yīng)后,再接著繼續(xù)接下一個(gè)用戶的任務(wù),但網(wǎng)絡(luò)所允許的最長(zhǎng)響應(yīng)時(shí)間是有限度的,故服務(wù)器只能在其最大負(fù)載能力范圍內(nèi)滿足有限數(shù)量用戶的請(qǐng)求,更多的請(qǐng)求由于來(lái)不及處理將直接被拒絕,使得網(wǎng)頁(yè)長(zhǎng)時(shí)間停滯無(wú)刷新也無(wú)法操作,這會(huì)影響到用戶的使用體驗(yàn)。響應(yīng)式編程就是針對(duì)上述問(wèn)題而提出的一種新的編程模式,它的工作過(guò)程為:主線程接受用戶請(qǐng)求→立刻返回響應(yīng)(響應(yīng)中不包含處理的數(shù)據(jù)結(jié)果,只是告知用戶請(qǐng)求已受理,請(qǐng)等待)→開(kāi)啟一個(gè)新的工作線程去執(zhí)行任務(wù)(包括操作后臺(tái)、處理數(shù)據(jù)...)→工作線程完成任務(wù)→包裝結(jié)果數(shù)據(jù)返回給前端。響應(yīng)式編程概述2.Reactor模式響應(yīng)式編程的工作模式被稱為Reactor(反應(yīng)器),其原理模型如圖8.37所示。響應(yīng)式編程概述該模型涉及客戶端、分發(fā)器、處理器三方。(1)(2)(3)客戶端會(huì)先向服務(wù)器注冊(cè)其感興趣的事件(即“訂閱”事件),這些事件并不會(huì)給服務(wù)器發(fā)送請(qǐng)求,只有當(dāng)客戶端發(fā)生了相應(yīng)的注冊(cè)事件時(shí),才會(huì)觸發(fā)服務(wù)器的響應(yīng)。服務(wù)器上存在一個(gè)分發(fā)器線程,這個(gè)線程只是負(fù)責(zé)輪詢客戶端的事件而并不處理具體的請(qǐng)求,當(dāng)它監(jiān)測(cè)到有客戶端事件發(fā)生時(shí),會(huì)將事件對(duì)應(yīng)的請(qǐng)求分發(fā)給匹配的處理器,然后啟用另外一條線程運(yùn)行處理器。當(dāng)處理器處理完請(qǐng)求的業(yè)務(wù)時(shí),再將結(jié)果轉(zhuǎn)換為數(shù)據(jù)流返回給客戶端。響應(yīng)式編程概述3.WebFlux框架與SpringBoot基本框架使用的DispatcherServlet不同,WebFlux使用WebHandler接口,并通過(guò)該接口的實(shí)現(xiàn)類DispatcherHandler實(shí)現(xiàn)了上述模型中分發(fā)器的功能,如圖8.38所示。響應(yīng)式編程概述4.開(kāi)發(fā)方式在SpringBoot中,響應(yīng)式編程存在兩種不同的開(kāi)發(fā)方式:一種是路由函數(shù)式;另一種是MVC注解式。這種方式需要先創(chuàng)建一個(gè)Handler類,它相當(dāng)于MVC控制器中的方法體,不過(guò)此時(shí)的請(qǐng)求/響應(yīng)不再是HttpServletRequest/HttpServletResponse,而變成了ServerRequest/ServerResponse。(1)路由函數(shù)式采用大家所熟悉的注解編程,以@Controller/@RestController來(lái)代替Handler類,URL路徑映射也通過(guò)@RequestMapping提供,只是在創(chuàng)建項(xiàng)目時(shí)要額外添加WebFlux響應(yīng)式框架,以及要注意控制器的返回類型必須是Flux或Mono格式的數(shù)據(jù)流。(2)MVC注解式響應(yīng)式編程概述5.?dāng)?shù)據(jù)庫(kù)選擇WebFlux只能支持SpringDataReactive,它是一種非阻塞的數(shù)據(jù)響應(yīng)方式,但傳統(tǒng)關(guān)系數(shù)據(jù)庫(kù)的開(kāi)發(fā)卻是阻塞的,所以SpringDataReactive并不能對(duì)關(guān)系數(shù)據(jù)庫(kù)的開(kāi)發(fā)給予有效支持,但它仍然可以支持Redis、MongoDB等NoSQL的開(kāi)發(fā),而Redis功能有限,更適合作為緩存使用,于是MongoDB就成為了WebFlux最理想的數(shù)據(jù)源,以響應(yīng)式Web程序訪問(wèn)MongoDB也是當(dāng)前應(yīng)用最廣泛的方式。目錄02響應(yīng)式編程舉例1.準(zhǔn)備數(shù)據(jù)2.創(chuàng)建項(xiàng)目3.配置連接4.開(kāi)發(fā)模型5.開(kāi)發(fā)持久層6.開(kāi)發(fā)業(yè)務(wù)層7.編寫控制器8.啟用響應(yīng)式接口9.運(yùn)行響應(yīng)式編程舉例【實(shí)例8.3】用WebFlux編程操作MongoDB,讀取保存在其中的一條或多條銷售詳情記錄。1.準(zhǔn)備數(shù)據(jù)MongoDB數(shù)據(jù)庫(kù)中的數(shù)據(jù)情況如圖8.39所示。響應(yīng)式編程舉例2.創(chuàng)建項(xiàng)目創(chuàng)建SpringBoot項(xiàng)目,項(xiàng)目名為WebFluxMongo,在出現(xiàn)的向?qū)Ы缑妗癉ependencies”列表中勾選Lombok模型簡(jiǎn)化組件(“DeveloperTools”→“Lombok”)、JPA框架(“SQL”→“SpringDataJPA”)。為使項(xiàng)目支持操作MongoDB的響應(yīng)式編程,最重要的是添加WebFlux框架與MongoDB響應(yīng)式數(shù)據(jù)源,操作如下。(1)添加WebFlux框架勾選“Web”→“SpringReactiveWeb”。(2)添加MongoDB響應(yīng)式數(shù)據(jù)源勾選“NoSQL”→“SpringDataReactiveMongoDB”。以上這兩者在項(xiàng)目pom.xml文件中對(duì)應(yīng)的依賴項(xiàng)如下:<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-mongodb-reactive</artifactId></dependency> <!--MongoDB響應(yīng)式數(shù)據(jù)源--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-webflux</artifactId></dependency> <!--WebFlux框架-->響應(yīng)式編程舉例3.配置連接在項(xiàng)目perties文件中配置MongoDB的數(shù)據(jù)庫(kù)連接,配置內(nèi)容如下:spring.data.mongodb.host=localhostspring.data.mongodb.port=27017spring.data.mongodb.database=mgnetshop
spring.jackson.serialization.indent-output=true4.開(kāi)發(fā)模型由于本例與【實(shí)例5.7】一樣操作的是MongoDB數(shù)據(jù)庫(kù)中的銷售詳情記錄,故采用一模一樣的模型類。直接復(fù)用【實(shí)例5.7】的兩個(gè)模型類,將model包及其下模型類復(fù)制到本項(xiàng)目的包下,改包路徑與當(dāng)前的項(xiàng)目一致即可,代碼略。響應(yīng)式編程舉例5.開(kāi)發(fā)持久層WebFlux框架為基于MongoDB的響應(yīng)式編程提供了ReactiveMongoRepository接口,通過(guò)繼承它來(lái)開(kāi)發(fā)持久層的數(shù)據(jù)接口,這也是一種JPA類型的接口。在項(xiàng)目工程目錄樹(shù)的com.example.webfluxmongo節(jié)點(diǎn)下創(chuàng)建repository包,其中創(chuàng)建接口SaleRepository.java,定義代碼為:packagecom.example.webfluxmongo.repository;
importcom.example.webfluxmongo.model.Saledetail;importorg.springframework.data.mongodb.repository.ReactiveMongoRepository;importorg.springframework.stereotype.Repository;importreactor.core.publisher.Flux;importreactor.core.publisher.Mono;
@RepositorypublicinterfaceSaleRepositoryextendsReactiveMongoRepository<Saledetail,String> { Mono<Saledetail>querySaledetailsByOidAndPid(intoid,intpid); Flux<Saledetail>findByScodeLike(Stringscode);}響應(yīng)式編程舉例6.開(kāi)發(fā)業(yè)務(wù)層下面基于WebFlux的JPA接口來(lái)開(kāi)發(fā)操作MongoDB的業(yè)務(wù)層(1)定義業(yè)務(wù)接口在項(xiàng)目工程目錄樹(shù)的com.example.webfluxmongo節(jié)點(diǎn)下創(chuàng)建service包,其下定義名為SaleService的接口,代碼為:packagecom.example.webfluxmongo.service;
importcom.example.webfluxmongo.model.Saledetail;importreactor.core.publisher.Flux;importreactor.core.publisher.Mono;
publicinterfaceSaleService{ //查詢單條記錄 publicMono<Saledetail>getSale(intoid,intpid);
//查詢多條記錄 publicFlux<Saledetail>findSales(Stringscode);}響應(yīng)式編程舉例(2)開(kāi)發(fā)服務(wù)實(shí)體在service包下創(chuàng)建業(yè)務(wù)接口的實(shí)現(xiàn)類SaleServiceImpl,代碼如下:packagecom.example.webfluxmongo.service;
importcom.example.webfluxmongo.model.Saledetail;importcom.examp
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 風(fēng)景名勝區(qū)自行車租借協(xié)議
- 建筑安裝工程承包合作協(xié)議
- 廣告委托制作協(xié)議書
- 民間借款協(xié)議書的格式要求
- 私車出租給機(jī)構(gòu)協(xié)議
- 2024年加盟經(jīng)銷合同范本
- 建筑工程勞務(wù)擴(kuò)大分包合同完整2024年
- 2024正規(guī)版私人借款合同樣本
- 吉林省農(nóng)業(yè)產(chǎn)品訂購(gòu)協(xié)議
- 房產(chǎn)物業(yè)抵押借款協(xié)議
- 水旋式噴漆室結(jié)構(gòu)、原理及設(shè)計(jì)要點(diǎn)2頁(yè)
- 行政事業(yè)單位經(jīng)濟(jì)責(zé)任審計(jì)報(bào)告范文
- 泵蓋鑄造工藝課程設(shè)計(jì)
- 爆破片日常檢查及定期更換記錄
- 運(yùn)轉(zhuǎn)車間鋼包管理制度
- 銷售大戶監(jiān)管辦法
- 小型裝配式冷庫(kù)設(shè)計(jì)(全套圖紙)
- 西師版小學(xué)數(shù)學(xué)二年級(jí)上冊(cè)半期考試
- 八六版高中英語(yǔ)課文全集
- 審計(jì)工作手冊(cè)
- 胰腺癌一病一品知識(shí)分享
評(píng)論
0/150
提交評(píng)論