乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      SpringCloud前置知識 RabbitMQ

       印度阿三17 2020-02-24

      一、微服務(wù)架構(gòu)介紹

      1.單體架構(gòu)

      單體架構(gòu)也被稱為單體應(yīng)用,它是將所有的功能模塊全部耦合在一個項(xiàng)目中

      1.1 單體架構(gòu)特點(diǎn)

      1.最終會被打包成一個獨(dú)立的單元(一個唯一 的jar包或war包)

      2.會以一個進(jìn)程的方式來運(yùn)行

      1.2 單體架構(gòu)的優(yōu)點(diǎn)與缺點(diǎn)

      優(yōu)點(diǎn)

      • 項(xiàng)目易于管理

      • 部署簡單

      缺點(diǎn)

      • 測試成本高

      • 可伸縮性差

      • 可靠性差

      • 迭代困難

      • 跨語言程度差

      • 團(tuán)隊(duì)協(xié)作難

      2.微服務(wù)架構(gòu)

      2.1 什么是微服務(wù)

      微服務(wù)是一種架構(gòu)風(fēng)格。一個大型的復(fù)雜軟件應(yīng)用,由一個或多個微服務(wù)組成。系統(tǒng)中 的各個微服務(wù)可被獨(dú)立部署,各個微服務(wù)之間是松耦合的。每個微服務(wù)僅關(guān)注于完成一件任 務(wù)并很好的完成該任務(wù)。

      2.2 常見的架構(gòu)風(fēng)格
      • 客戶端與服務(wù)端的

      • 基于組件模型的架構(gòu)(EJB)

      • 分層架構(gòu)(MVC)

      • 面向服務(wù)架構(gòu)(SOA)

      2.3 微服務(wù)的特點(diǎn)
      • 系統(tǒng)是由多個服務(wù)構(gòu)成

      • 每個服務(wù)可以單獨(dú)獨(dú)立部署

      • 每個服務(wù)之間是松耦合的,服務(wù)內(nèi)部高內(nèi)聚,服務(wù)外部低耦合,高內(nèi)聚就是一個項(xiàng)目專注的完成一個功能

      2.4 微服務(wù)的優(yōu)點(diǎn)與缺點(diǎn)

      優(yōu)點(diǎn):

      • 容易測試

      • 可伸縮性強(qiáng)

      • 可靠性強(qiáng)

      • 跨語言程度更加靈活

      • 團(tuán)隊(duì)協(xié)作容易

      • 系統(tǒng)迭代容易

      缺點(diǎn):

      • 運(yùn)維成本過高,部署的數(shù)量較多

      • 接口兼容多版本

      • 分布式系統(tǒng)的復(fù)雜性

      • 分布式事務(wù)

      二、MVC、RPC、SOA、微服務(wù)架構(gòu)之間的區(qū)別

      1.MVC架構(gòu)

      其實(shí)MVC就是傳統(tǒng)的單體架構(gòu)

      代表技術(shù):SpringMVC、Spring、MyBatis等等。

      2.RPC架構(gòu)

      RPC(Remote Procedure Call):遠(yuǎn)程過程調(diào)用。他一種通過網(wǎng)絡(luò)從遠(yuǎn)程計算機(jī)程序上請求 服務(wù),而不需要了解底層網(wǎng)絡(luò)技術(shù)的協(xié)議。

      代表技術(shù):Thrift、Hessian 等等

      3. SOA架構(gòu)

      SOA(Service oriented Architecture):面向服務(wù)架構(gòu)

      ESB(Enterparise Servce Bus):企業(yè)服務(wù)總線,服務(wù)中介。主要是提供了一個服務(wù)于服務(wù)之間的交互。 ESB 包含的功能如:負(fù)載均衡,流量控制,加密處理,服務(wù)的監(jiān)控,異常處理,監(jiān)控 告急等等。

      代表技術(shù):Mule、WSO2

      4.微服務(wù)架構(gòu)

      微服務(wù)就是一個輕量級的服務(wù)治理方案。

      代表技術(shù):SpringCloud、dubbo 等等

      三、微服務(wù)的設(shè)計原則

      • AKF拆分原則

      • 前后端分離原則

      • 無狀態(tài)服務(wù)

      • RestFul通信風(fēng)格

      1. AKF拆分原則

      業(yè)界對于可擴(kuò)展的系統(tǒng)架構(gòu)設(shè)計有一個樸素的理念,就是: **通過加機(jī)器就可以解決容量和可用性問題。(如果一臺不行那就兩臺) **

      這一理念在“云計算”概念瘋狂流行的今天,得到了廣泛的認(rèn)可!對于一個規(guī)模 迅速增長的系統(tǒng)而言,容量和性能問題當(dāng)然是首當(dāng)其沖的。但是隨著時間的向前, 系統(tǒng)規(guī)模的增長,除了面對性能與容量的問題外,還需要面對功能與模塊數(shù)量上 的增長帶來的系統(tǒng)復(fù)雜性問題以及業(yè)務(wù)的變化帶來的提供差異化服務(wù)問題。而許多系統(tǒng),在架構(gòu)設(shè)計時并未充分考慮到這些問題,導(dǎo)致系統(tǒng)的重構(gòu)成為常態(tài),從 而影響業(yè)務(wù)交付能力,還浪費(fèi)人力財力!對此,《可擴(kuò)展的藝術(shù)》一書提出了一 個更加系統(tǒng)的可擴(kuò)展模型—— AKF 可擴(kuò)展立方 (Scalability Cube)。這個立方 體中沿著三個坐標(biāo)軸設(shè)置分別為:X、Y、Z。

      • Y 軸(功能) —— 關(guān)注應(yīng)用中功能劃分,基于不同的業(yè)務(wù)拆分

      • X 軸(水平擴(kuò)展) —— 關(guān)注水平擴(kuò)展,也就是”加機(jī)器解決問題”

      • Z 軸(數(shù)據(jù)分區(qū)) —— 關(guān)注服務(wù)和數(shù)據(jù)的優(yōu)先級劃分,如按地域劃分

      1.1 Y軸(功能 )

      Y 軸擴(kuò)展會將龐大的整體應(yīng)用拆分為多個服務(wù)。每個服務(wù)實(shí)現(xiàn)一組相關(guān)的功 能,如訂單管理、客戶管理等。在工程上常見的方案是服務(wù)化架構(gòu)(SOA) 。比 如對于一個電子商務(wù)平臺,我們可以拆分成不同的服務(wù),組成下面這樣的架構(gòu):

      但通過觀察上圖容易發(fā)現(xiàn),當(dāng)服務(wù)數(shù)量增多時,服務(wù)調(diào)用關(guān)系變得復(fù)雜。為系統(tǒng)添加一個新功能,要調(diào)用的服務(wù)數(shù)也變得不可控,由此引發(fā)了服務(wù)管理上的混亂。所以,一般情況下,需要采用服務(wù)注冊的機(jī)制形成服務(wù)網(wǎng)關(guān)來進(jìn)行服務(wù)治理。系統(tǒng)的架構(gòu)將變成下圖所示:

      1.2 X軸(水平擴(kuò)展)

      X 軸擴(kuò)展與我們前面樸素理念是一致的,通過絕對平等地復(fù)制服務(wù)與數(shù)據(jù), 以解決容量和可用性的問題。其實(shí)就是將微服務(wù)運(yùn)行多個實(shí)例,做集群加負(fù)載均衡的模式。

      為了提升單個服務(wù)的可用性和容量, 對每一個服務(wù)進(jìn)行 X 軸擴(kuò)展劃分。

      1.3 Z軸(數(shù)據(jù)分區(qū))

      Z 軸擴(kuò)展通常是指基于請求者或用戶獨(dú)特的需求,進(jìn)行系統(tǒng)劃分,并使得劃分出來的子系統(tǒng)是相互隔離但又是完整的。以生產(chǎn)汽車的工廠來舉例:福特公司為了發(fā)展在中國的業(yè)務(wù),或者利用中國的廉價勞動力,在中國建立一個完整的子 工廠,與美國工廠一樣,負(fù)責(zé)完整的汽車生產(chǎn)。這就是一種Z軸擴(kuò)展。

      工程領(lǐng)域常見的 Z 軸擴(kuò)展有以下兩種方案:

      • 單元化架構(gòu)

        在分布式服務(wù)設(shè)計領(lǐng)域,一個單元(Cell)就是滿足某個分區(qū)所有業(yè)務(wù)操作 的自包含閉環(huán)。如上面我們說到的Y軸擴(kuò)展的 SOA 架構(gòu),客戶端對服務(wù)端節(jié)點(diǎn) 的選擇一般是隨機(jī)的,但是,如果在此加上Z軸擴(kuò)展,那服務(wù)節(jié)點(diǎn)的選擇將不再是隨機(jī)的了,而是每個單元自成一體。如下圖:

      • 數(shù)據(jù)分區(qū)

        為了性能數(shù)據(jù)安全上的考慮,我們將一個完整的數(shù)據(jù)集按一定的維度劃分出 不同的子集。 一個分區(qū)(Shard),就是是整體數(shù)據(jù)集的一個子集。比如用尾號 來劃分用戶,那同樣尾號的那部分用戶就可以認(rèn)為是一個分區(qū)。數(shù)據(jù)分區(qū)為一般 包括以下幾種數(shù)據(jù)劃分的方式:

        1. 數(shù)據(jù)類型(如:業(yè)務(wù)類型)

        2. 數(shù)據(jù)范圍(如:時間段,用戶 ID)

        3. 數(shù)據(jù)熱度(如:用戶活躍度,商品熱度)

        4. 按讀寫分(如:商品描述,商品庫存)

      2. 前后端分離原則

      何為前后端分離?前后端本來不就分離么?這要從尷尬的 jsp 講起。分工精細(xì)化從來都 是蛋糕做大的原則,多個領(lǐng)域工程師最好在不需要接觸其他領(lǐng)域知識的情況下合作,才可能 使效率越來越高,維護(hù)也會變得簡單。jsp 的模板技術(shù)融合了 html 和 java 代碼,使得傳統(tǒng) MVC 開發(fā)中的前后端在這里如膠似漆,前端做好頁面,后端轉(zhuǎn)成模板,發(fā)現(xiàn)問題再找前端, 前端又看不懂 java 代碼…前后端分離的目的就是將這尷尬局面打破。 前后端分離原則,簡單來講就是前端和后端的代碼分離,我們推薦的模式是最好采用物 理分離的方式部署,進(jìn)一步促使更徹底的分離。如果繼續(xù)直接使用服務(wù)端模板技術(shù),如:jsp, 把 java、js、html、css 都堆到一個頁面里,稍微復(fù)雜一點(diǎn)的頁面就無法維護(hù)了。

      這種分離方式有幾個好處:

      • 前后端技術(shù)分離,可以由各自的專家來對各自的領(lǐng)域進(jìn)行優(yōu)化,這樣前段的用戶體 驗(yàn)優(yōu)化效果更好。

      • 分離模式下,前后端交互界面更清晰,就剩下了接口模型,后端的接口簡潔明了, 更容易維護(hù)。

      • 前端多渠道集成場景更容易實(shí)現(xiàn),后端服務(wù)無需變更,采用統(tǒng)一的數(shù)據(jù)和模型,可 以支持多個前端:例如:微信 h5 前端、PC 前端、安卓前端、IOS 前端。

      3. 無狀態(tài)服務(wù)

      對于無狀態(tài)服務(wù),首先說一下什么是狀態(tài):如果一個數(shù)據(jù)需要被多個服務(wù)共 享,才能完成一筆交易,那么這個數(shù)據(jù)被稱為狀態(tài)。進(jìn)而依賴這個“狀態(tài)”數(shù)據(jù)的 服務(wù)被稱為有狀態(tài)服務(wù),反之稱為無狀態(tài)服務(wù)。

      那么這個無狀態(tài)服務(wù)原則并不是說在微服務(wù)架構(gòu)里就不允許存在狀態(tài),表達(dá) 的真實(shí)意思是要把有狀態(tài)的業(yè)務(wù)服務(wù)改變?yōu)闊o狀態(tài)的計算類服務(wù),那么狀態(tài)數(shù)據(jù) 也就相應(yīng)的遷移到對應(yīng)的“有狀態(tài)數(shù)據(jù)服務(wù)”中。

      場景說明:例如我們以前在本地內(nèi)存中建立的數(shù)據(jù)緩存、Session 緩存,到 現(xiàn)在的微服務(wù)架構(gòu)中就應(yīng)該把這些數(shù)據(jù)遷移到分布式緩存中存儲,讓業(yè)務(wù)服務(wù)變 成一個無狀態(tài)的計算節(jié)點(diǎn)。遷移后,就可以做到按需動態(tài)伸縮,微服務(wù)應(yīng)用在運(yùn) 行時動態(tài)增刪節(jié)點(diǎn),就不再需要考慮緩存數(shù)據(jù)如何同步的問題。

      4. RestFul的通訊風(fēng)格

      作為一個原則來講本來應(yīng)該是個“無狀態(tài)通信原則”,在這里我們直接推薦一 個實(shí)踐優(yōu)選的 Restful 通信風(fēng)格 ,因?yàn)樗泻芏嗪锰帲?/p>

      • 無狀態(tài)協(xié)議 HTTP,具備先天優(yōu)勢,擴(kuò)展能力很強(qiáng)。例如需要安全加密,有 現(xiàn)成的成熟方案 HTTPS 即可。

      • JSON 報文序列化,輕量簡單,人與機(jī)器均可讀,學(xué)習(xí)成本低,搜索引擎友好。

      • 語言無關(guān),各大熱門語言都提供成熟的 Restful API 框架,相對其他的一些 RPC 框架生態(tài)更完善。

      四、SpringCloud簡介

      1.什么是SpringCloud

      SpringCloud是一個服務(wù)治理平臺,提供了一些服務(wù)框架。包含了:服務(wù)注冊 與發(fā)現(xiàn)、配置中心、消息中心 、負(fù)載均衡、數(shù)據(jù)監(jiān)控等等。

      Spring Cloud 是一個微服務(wù)框架,**相比 Dubbo 等 RPC 框架, Spring Cloud 提 供的全套的分布式系統(tǒng)解決方案。 **

      Spring Cloud 對微服務(wù)基礎(chǔ)框架 Netflix 的多個開源組件進(jìn)行了封裝,同時又實(shí)現(xiàn) 了和云端平臺以及和 Spring Boot 開發(fā)框架的集成。

      Spring Cloud 為微服務(wù)架構(gòu)開發(fā)涉及的配置管理,服務(wù)治理,熔斷機(jī)制,智能路由, 微代理,控制總線,一次性 token,全局一致性鎖,leader 選舉,分布式 session,集 群狀態(tài)管理等操作提供了一種簡單的開發(fā)方式。

      Spring Cloud 為開發(fā)者提供了快速構(gòu)建分布式系統(tǒng)的工具,開發(fā)者可以快速的啟動 服務(wù)或構(gòu)建應(yīng)用、同時能夠快速和云平臺資源進(jìn)行對接。

      2. SpringCloud的項(xiàng)目的位置

      SpingCloud是Spring 的一個頂級項(xiàng)目與 SpringBoot、SpringData 位于同一位置。

      3.SpringCloud的子項(xiàng)目

      3.1 SpringCloud Config

      配置管理工具,支持使用 Git 存儲配置內(nèi)容,支持應(yīng) 用配置的外部化存儲,支持客戶端配置信息刷新、加解密配置內(nèi)容等

      3.2 SpringCloud Bus

      事件、消息總線,用于在集群(例如,配置變化事件)中 傳播狀態(tài)變化,可與 Spring Cloud Config 聯(lián)合實(shí)現(xiàn)熱部署。

      3.3 Spring Cloud Netflix>

      **針對多種 Netflix 組件提供的開發(fā)工具包,其中包括 Eureka、Hystrix、Zuul、Archaius 等。 **

      • Netflix Eureka

        一個基于 rest 服務(wù)的服務(wù)治理組件,包括服務(wù)注冊中心、服務(wù)注冊與服務(wù)發(fā)現(xiàn)機(jī)制的實(shí)現(xiàn),實(shí)現(xiàn)了云端負(fù)載均衡和中間層服務(wù)器的故障轉(zhuǎn)移。

      • Netflix Hystrix

        容錯管理工具,實(shí)現(xiàn)斷路器模式,通過控制服務(wù)的節(jié)點(diǎn), 從而對延遲和故障提供更強(qiáng)大的容錯能力。

      • Netflix Ribbon

        客戶端負(fù)載均衡的服務(wù)調(diào)用組件。

      • Netflix Feign

        基于Ribbon和Hystrix的聲明式服務(wù)調(diào)用組件。

      • Netflix Zuul

        微服務(wù)網(wǎng)關(guān),提供動態(tài)路由,訪問過濾等服務(wù)。

      • Netflix Archaius:

        配置管理 API,包含一系列配置管理 API,提供動 態(tài)類型化屬性、線程安全配置操作、輪詢框架、回調(diào)機(jī)制等功能。

      3.4 Spring Cloud for Cloud Foundry

      通過 Oauth2 協(xié)議綁定服務(wù)到 CloudFoundry,CloudFoundry 是 VMware 推出的開源 PaaS 云平臺。

      3.5 Spring Cloud Sleuth

      日志收集工具包,封裝了 Dapper,Zipkin 和 HTrace 操作。

      3.6 Spring Cloud Data Flow

      大數(shù)據(jù)操作工具,通過命令行方式操作數(shù)據(jù)流。

      3.7 Spring Cloud Security

      安全工具包,為你的應(yīng)用程序添加安全控制,主要是指OAuth2。

      3.8 Spring Cloud Consul

      封裝了Consul操作,consul是一個服務(wù)發(fā)現(xiàn)與配置工具,與Docker容器可以無縫集成。

      3.9 Spring Cloud Zookeeper

      操作Zookeeper的工具包 , 用使用zookeeper方式的服務(wù)注冊和發(fā)現(xiàn)。

      3.10 Spring Cloud Stream:

      數(shù)據(jù)流操作開發(fā)包,封裝了Redis、Rabbit、Kafka 等發(fā)送接收消息。

      3.11 Spring Cloud CLI

      基于 Spring Boot CLI,可以讓你以命令行方式快速建立云組件。

      五、SpringCloud與Dubbo的區(qū)別

      六、 Spring Cloud版本說明

      1.常見版本號說明

      軟件版本號:2.0.2.RELEASE

      • 2:主版本號。當(dāng)功能模塊有較大更新或者整體架構(gòu)發(fā)生變化時,主版本號會更新

      • 0:次版本號。次版本表示只是局部的一些變動。

      • 2:修改版本號。一般是 bug 的修復(fù)或者是小的變動

      • RELEASE:希臘字母版本號。次版本號用戶標(biāo)注當(dāng)前版本的軟件處于哪個開發(fā)階段

      1.1希臘字母版本號
      • Base:設(shè)計階段。只有相應(yīng)的設(shè)計沒有具體的功能實(shí)現(xiàn)

      • Alpha:軟件的初級版本。存在較多的 bug

      • Bate:表示相對 alpha 有了很大的進(jìn)步,消除了嚴(yán)重的 bug,還存在一些潛在的 bug。

      • Release:該版本表示最終版。

      2. Spring Cloud 版本號說明

      2.1為什么 Spring Cloud 版本用的是單詞而不是數(shù)字?

      設(shè)計的目的是為了更好的管理每個 Spring Cloud 的子項(xiàng)目的清單。避免子的版本號與子 項(xiàng)目的版本號混淆。

      2.2 版本號單詞的定義規(guī)則

      采用倫敦的地鐵站名稱來作為版本號的命名,根據(jù)首字母排序,字母順序靠后的版本號越大。

      2.3 版本發(fā)布計劃說明

      七、RabbitMQ

      1.什么是RabbitMQ

      MQ全稱Message Queue(消息隊(duì)列),是一種應(yīng)用程序與應(yīng)用程序之間通信的一種方式,應(yīng)用程序可以通過向消息隊(duì)列中讀寫消息進(jìn)行信息的交互,而不是以應(yīng)用相互調(diào)用的方式進(jìn)行通信。

      2.安裝RabbitMQ

      2.1 安裝rabbitmq所需要的依賴包
      yum install build-essential openssl openssl-devel unixODBC unixODBC-devel make gcc gcc-c   kernel-devel m4 ncurses-devel tk tc xz
      2.2 下載安裝包(cd /usr/local/software)
      wget www.rabbitmq.com/releases/erlang/erlang-18.3-1.el7.centos.x86_64.rpm
      wget http://repo./CentOS/7/x86_64/socat-1.7.3.2-5.el7.lux.x86_64.rpm
      wget www.rabbitmq.com/releases/rabbitmq-server/v3.6.5/rabbitmq-server-3.6.5-1.noarch.rpm

      2.3 安裝服務(wù)命令
      #第一步:安裝erlang語言環(huán)境
      rpm -ivh erlang-18.3-1.el7.centos.x86_64.rpm
      #第二步:安裝socat加解密軟件
      rpm -ivh socat-1.7.3.2-5.el7.lux.x86_64.rpm
      #第三步:最后安裝rabbitmq
      rpm -ivh rabbitmq-server-3.6.5-1.noarch.rpm
      2.4 修改集群用戶與連接心跳檢測

      **注意修改vim /usr/lib/rabbitmq/lib/rabbitmq_server-3.6.5/ebin/rabbit.app文件 **

      修改:loopback_users 中的 <<“guest”>>,只保留guest(不修改只能通過localhost訪問)

      2.5 修改本機(jī)系統(tǒng)文件
      #修改 
      vim /etc/rabbitmq/rabbitmq-env.conf

      添加:NODENAME=rabbit

      #修改
      vim /etc/hostname

      #修改本地文件 
      vim /etc/hosts

      #驗(yàn)證服務(wù)器是可用的
      rabbitmq-server start &

      **執(zhí)行管控臺插件 **

      rabbitmq-plugins enable rabbitmq_management

      #檢查端口
      lsof -i:5672

      #通過
      ps -ef|grep rabbitmq

      訪問地址:http://192.168.159.8:15672

      #下載延時插件:
      wget https://dl./rabbitmq/communityplugins/3.6.x/rabbitmq_delayed_message_exchange/rabbitmq_delayed_message_exchange-20171215- 3.6.x.zip  
      
      #解壓延時插件
      unzip rabbitmq_delayed_message_exchange-20171215-3.6.x.zip
      #把延時插件拷貝到指定目錄下
      cp rabbitmq_delayed_message_exchange-20171215-3.6.x.ez /usr/lib/rabbitmq/lib/rabbitmq_server-3.7.5/plugins
      #啟動延時插件
      rabbitmq-plugins enable rabbitmq_delayed_message_exchange

      3.命令行和管控臺

      **開啟管控臺插件 rabbitmq-plugus rabbitmq_management 來開啟管控臺 **

      測試連接: http://ip:15672(來訪問) 用戶名密碼 guest/guest

      3.1 管理控制臺命令

      a.起停服務(wù)命令

      #啟動服務(wù)
      rabbitmqctl start_app

      啟動rabbitmq節(jié)點(diǎn)保證需要erlang虛擬機(jī)節(jié)點(diǎn)起來才能執(zhí)行)

      #停止服務(wù)
      rabbitmqctl stop_app

      停止rabbtimq節(jié)點(diǎn),但是不會停止erlang節(jié)點(diǎn)rabbitmqctl stop都會停止

      #查看服務(wù)狀態(tài) 
      rabbtimqctl status

      b. 用戶操作命令

      #查看所有用戶列表
      rabbitmqctl list_users
      #添加用戶
      rabbitmqctl add_user luyi luyi
      #設(shè)置rabbitmq用戶的角色
      rabbitmqctl set_user_tags luyi administrator
      #為用戶設(shè)置權(quán)限
      rabbitmqctl set_permissions -p / luyi ".*" ".*" ".*"
      
      rabbitmqctl set_permissions -p <虛擬機(jī)> <用戶名> ".*" ".*" ".*"
      #列出用戶權(quán)限
      rabbitmqctl list_user_permissions luyi
      #清除用戶權(quán)限
      rabbitmqctl clear_permissions -p <虛擬機(jī)> <用戶名>
      rabbitmqctl clear_permissions -p / root
      #刪除用戶
      rabbitmqctl delete_user root #root是用戶名
      #修改密碼
      rabbitmqctl change_password 用戶名 新密碼

      c.虛擬主機(jī)操作

      rabbitmqctl add_vhost /cloudmall 增加一個虛擬主機(jī)

      rabbitmqctl list_vhosts; 查看所有的虛擬主機(jī)

      rabbitmqctl list_permissions -p /cloudmall 查看虛擬主機(jī)的權(quán)限

      rabbitmqctl delete_vhost /cloudmall 刪除虛擬主機(jī)

      d. 操作隊(duì)列命令

      rabbitmqctl list_queues 查詢所有隊(duì)列

      rabbitmqctl -p vhostpath purge_queue blue 清除隊(duì)列消息

      e. 高級命令

      rabbitmqctl reset 移除所有數(shù)據(jù) 該命令需要在 rabbitmqctl stop_app命令之后才執(zhí)行(也就是說 在服 務(wù)停止后) r

      abbitmqctl join_cluster [–ram] 組成集群命令

      rabbitmqctl cluster_status 查看集群狀態(tài)

      rabbitmqctl change_cluster_node_type dist|ram 修改集群節(jié)點(diǎn)存儲數(shù)據(jù)模式

      rabbitmqctl forget_cluster_node [–offline]忘記節(jié)點(diǎn) (摘除節(jié)點(diǎn))

      rabbitmqctc rename_cluster_node oldnode1 newnode1 oldnode2 newnode2 修改節(jié)點(diǎn)名稱

      4.為什么使用RabbitMQ

      4.1 實(shí)現(xiàn)異步

      4.2 解耦

      4.3 流量削峰

      5.消息隊(duì)列基礎(chǔ)知識

      5.1 Provider

      消息生產(chǎn)者,也就是發(fā)送消息的程序

      5.2 Consumer

      消息消費(fèi)者,也就是接收消息的程序

      5.3 沒有使用消息隊(duì)列的通信方式

      5.4 使用消息隊(duì)列后的通信方式

      5.5 什么是隊(duì)列

      隊(duì)列就像生活中的商店,商品制造商是消息生產(chǎn)者,顧客是消息消費(fèi)者,他們之間通過商店實(shí)現(xiàn)交互

      5.6 隊(duì)列和應(yīng)用程序的關(guān)系

      多個消息生產(chǎn)者可以將消息發(fā)送到同一個消息隊(duì)列中,多個消息消費(fèi)者可以從同一個消息隊(duì)列中取出消息。

      6.RabbitMQ入門

      6.1 創(chuàng)建項(xiàng)目
      6.2 添加依賴
      <dependencies>
          <dependency>
              <groupId>org.springframework.boot</groupId>
              <artifactId>spring-boot-starter-amqp</artifactId>
          </dependency>
          <dependency>
              <groupId>org.springframework.boot</groupId>
              <artifactId>spring-boot-starter-web</artifactId>
          </dependency>
      
          <dependency>
              <groupId>org.springframework.boot</groupId>
              <artifactId>spring-boot-starter-test</artifactId>
              <scope>test</scope>
          </dependency>
          <dependency>
              <groupId>org.springframework.amqp</groupId>
              <artifactId>spring-rabbit-test</artifactId>
              <scope>test</scope>
          </dependency>
      </dependencies>
      6.3 配置全局配置文件
      #設(shè)置應(yīng)用的名稱
      spring.application.name=springcloud01-mq
      
      #指定rabbitmq
      spring.rabbitmq.host=192.168.234.128
      spring.rabbitmq.port=5672
      spring.rabbitmq.username=luyi
      spring.rabbitmq.password=luyi
      6.4 創(chuàng)建配置類
      /**
       * Author: LuYi
       * Date: 2019/11/3 14:03
       * Description: 隊(duì)列配置類
       */
      @Configuration
      public class QueueConfig {
      
          /**
           * 創(chuàng)建隊(duì)列
           * @return
           */
          @Bean
          public Queue createQueue(){
              return new Queue("hello-queue");
          }
      }
      6.5 編寫消息發(fā)送者
      /**
       * Author: LuYi
       * Date: 2019/11/3 14:06
       * Description: 消息發(fā)送者
       */
      @Component
      public class Sender {
      
          @Autowired
          private RabbitTemplate rabbitTemplate;
      
          /**
           * 發(fā)送消息的方法
           */
          public void send(String msg){
              //向消息隊(duì)列發(fā)送消息
              //參數(shù)一: 隊(duì)列名稱
              //參數(shù)二: 消息
              rabbitTemplate.convertAndSend("hello-queue", msg);
          }
      }
      6.6 編寫消息接收者
      /**
       * Author: LuYi
       * Date: 2019/11/3 14:12
       * Description: 消息接收者
       */
      @Component
      public class Receiver {
      
          /**
           * 接收消息的方法,采用消息隊(duì)列監(jiān)聽機(jī)制
           * @param msg
           */
          @RabbitListener(queues = "hello-queue")
          public void process(String msg){
      
              System.out.println("Receiver : "   msg);
          }
      }
      6.7 測試
      /**
       * 消息隊(duì)列測試類
       */
      @RunWith(SpringRunner.class)
      @SpringBootTest(classes = Springcloud01MqApplication.class)
      class Springcloud01MqApplicationTests {
      
      	@Autowired
      	private Sender sender;
      
      	@Test
      	void contextLoads() {
      	}
      
      	/**
      	 * 測試消息隊(duì)列
      	 */
      	@Test
      	public void test1(){
      		sender.send("Hello RabbitMQ");
      	}
      }

      7.RabbitMQ原理圖

      1.Message(消息):消息是不具名的,它是由消息頭和消息體組成。消息體是不透明的,而消息頭則由一系列可選屬性組成,這些屬性包括:routing-key(路由鍵)、priority(相對于其他消息的優(yōu)先權(quán))、delivery-mode(指出消息可能持久性存儲)等。

      2.Publisher(生產(chǎn)者):向交換機(jī)發(fā)送消息的客戶端程序

      3.Consumer(消費(fèi)者):從消息隊(duì)列中獲取消息的客戶端程序

      4.Exchange(交換機(jī)):用來接收客戶端發(fā)過來的消息,并將這些消息路由給服務(wù)器中的消息隊(duì)列

      三種常用的交換機(jī):

      a.direct(發(fā)布與訂閱,完全匹配)

      b.fanout(廣播)

      c.topic(主題,規(guī)則匹配)

      5.Binding(綁定):用于交換機(jī)與消息隊(duì)列之間的關(guān)聯(lián),一個綁定就是根據(jù)路由鍵將交換機(jī)與消息隊(duì)列連接起來的規(guī)則。

      6.Queue(消息隊(duì)列):用于保存消息,直到將消息發(fā)送給消費(fèi)者

      7.Routing-key(路由鍵):RabbitMQ決定將消息投遞到那個消息隊(duì)列的規(guī)則。隊(duì)列通過路由鍵綁定交換機(jī),消息發(fā)送到MQ服務(wù)器時,消息將擁有一個路由鍵,即便是空的,RabbitMQ也會將其和綁定使用的路由鍵進(jìn)行匹配。

      如果匹配,消息會被發(fā)送到消息隊(duì)列,如果不匹配,消息將進(jìn)入黑洞。

      8.Connection(鏈接):Rabbit服務(wù)器和服務(wù)之間建立的TCP連接

      9.Channel(信道):信道是TCP中的虛擬鏈接,比如電纜就是TCP,信道則是一個獨(dú)立光纖束。一條TCP連接建立多條信道是沒有問題的。

      TCP一旦打開,就會創(chuàng)建AMQP信道。無論是發(fā)布消息、接收消息、訂閱隊(duì)列,這些動作都是通過信道完成的。

      10.Virtual Host(虛擬主機(jī)):表示一臺交換機(jī)和消息隊(duì)列。虛擬主機(jī)是共享相同的身份認(rèn)證和加密環(huán)境的獨(dú)立服務(wù)器域, 每個 vhost 本質(zhì)上就是一個 mini 版的 RabbitMQ 服務(wù)器,擁有自己的隊(duì)列、交換器、綁定和權(quán)限機(jī)制。 vhost 是 AMQP 概念的基礎(chǔ),必須在鏈接時指定, RabbitMQ 默認(rèn)的 vhost 是/  

      11.Borker:表示消息隊(duì)列的服務(wù)器實(shí)體

      交換機(jī)和路由器的關(guān)系是什么?

      交換機(jī)需要通過路由鍵和消息隊(duì)列進(jìn)行綁定,如果路由鍵相同,那么消息會被路由到對應(yīng)的消息隊(duì)列中,可以理解為路由鍵是決定消息發(fā)送到那個消息隊(duì)列的規(guī)則

      八、RabbitMQ交換器

      1.Direct(發(fā)布與訂閱 完全匹配)

      1.1 需求

      1.2 創(chuàng)建項(xiàng)目

      rabbitmq-direct-consumer

      rabbitmq-direct-provider

      1.3 修改全局配置文件

      consumer的配置文件

      #設(shè)置應(yīng)用的名稱
      spring.application.name=springcloud01-mq
      
      #指定rabbitmq
      spring.rabbitmq.host=192.168.234.128
      spring.rabbitmq.port=5672
      spring.rabbitmq.username=luyi
      spring.rabbitmq.password=luyi
      
      #設(shè)置交換器的名稱(處理日志的交換器)
      mq.config.exchange=log.direct
      
      #info級別的隊(duì)列名稱
      mq.config.queue.info=log.info
      
      #info的路由鍵
      mq.config.queue.info.routing.key=log.info.routing.key
      
      #error級別的隊(duì)列名稱
      mq.config.queue.error=log.error
      
      #error的路由鍵
      mq.config.queue.error.routing.key=log.error.routing.key

      provider的配置文件

      #設(shè)置應(yīng)用的名稱
      spring.application.name=springcloud01-mq
      
      #指定rabbitmq
      spring.rabbitmq.host=192.168.234.128
      spring.rabbitmq.port=5672
      spring.rabbitmq.username=luyi
      spring.rabbitmq.password=luyi
      
      #設(shè)置交換器的名稱(處理日志的交換器)
      mq.config.exchange=log.direct
      
      #info的路由鍵
      mq.config.queue.info.routing.key=log.info.routing.key
      
      #error的路由鍵
      mq.config.queue.error.routing.key=log.error.routing.key
      1.4 編寫consumer

      InfoReceiver

      /**
       * Author: LuYi
       * Date: 2019/11/3 14:12
       * Description: 消息接收者
       *
       * @RabbitListener bindings:綁定隊(duì)列
       *
       * @QueueBinding value:綁定隊(duì)列名稱
       *                exchange:配置交換器
       *
       * @Queue value:配置隊(duì)列名稱
       *         autoDelete:是否為可刪除的臨時隊(duì)列
       *
       * @Exchange value:為交換器起名
       *            type:指定當(dāng)前交換器的類型
       */
      @Component
      @RabbitListener(
              bindings = @QueueBinding(
                      value = @Queue(value = "${mq.config.queue.info}", autoDelete = "true"),
                      exchange = @Exchange(value = "${mq.config.exchange}", type = ExchangeTypes.DIRECT),
                      key = "${mq.config.queue.info.routing.key}"
              )
      )
      public class InfoReceiver {
      
          /**
           * 接收消息的方法,采用消息隊(duì)列監(jiān)聽機(jī)制
           * @param msg
           */
          @RabbitHandler
          public void process(String msg){
      
              System.out.println("InfoReceiver : "   msg);
          }
      }

      ErrorReceiver

      /**
       * Author: LuYi
       * Date: 2019/11/3 14:12
       * Description: 消息接收者
       *
       * @RabbitListener bindings:綁定隊(duì)列
       *
       * @QueueBinding value:綁定隊(duì)列名稱
       *                exchange:配置交換器
       *
       * @Queue value:配置隊(duì)列名稱
       *         autoDelete:是否為可刪除的臨時隊(duì)列
       *
       * @Exchange value:為交換器起名
       *            type:指定當(dāng)前交換器的類型
       */
      @Component
      @RabbitListener(
              bindings = @QueueBinding(
                      value = @Queue(value = "${mq.config.queue.error}", autoDelete = "true"),
                      exchange = @Exchange(value = "${mq.config.exchange}", type = ExchangeTypes.DIRECT),
                      key = "${mq.config.queue.error.routing.key}"
              )
      )
      public class ErrorReceiver {
      
          /**
           * 接收消息的方法,采用消息隊(duì)列監(jiān)聽機(jī)制
           * @param msg
           */
          @RabbitHandler
          public void process(String msg){
      
              System.out.println("ErrorReceiver : "   msg);
          }
      }
      1.5 編寫provider
      /**
       * Author: LuYi
       * Date: 2019/11/3 14:06
       * Description: 消息發(fā)送者
       */
      @Component
      public class Sender {
      
          @Autowired
          private RabbitTemplate rabbitTemplate;
      
          //交換器名稱
          @Value("${mq.config.exchange}")
          private String exchange;
      
          //路由鍵名稱
          @Value("${mq.config.queue.error.routing.key}")
          private String routingKey;
      
          /**
           * 發(fā)送消息的方法
           */
          public void send(String msg){
              //向消息隊(duì)列發(fā)送消息
              //參數(shù)一: 交換器名稱
              //參數(shù)二: 路由鍵
              //參數(shù)三: 消息
              rabbitTemplate.convertAndSend(exchange, routingKey, msg);
          }
      }
      1.6 測試
      /**
       * 消息隊(duì)列測試類
       */
      @RunWith(SpringRunner.class)
      @SpringBootTest(classes = Springcloud01MqApplication.class)
      class Springcloud01MqApplicationTests {
      
      	@Autowired
      	private Sender sender;
      
      	@Test
      	void contextLoads() {
      	}
      
      	@Test
      	public void test1() throws InterruptedException {
      		while (true){
      			Thread.sleep(1000);
      			sender.send("Hello RabbitMQ");
      		}
      	}
      
      }

      2.Topic交換器(主題,規(guī)則匹配)

      2.1 需求

      2.2 創(chuàng)建項(xiàng)目

      rabbitmq-topic-consumer

      rabbitmq-topic-provider

      2.3 修改配置文件

      provider

      #設(shè)置應(yīng)用的名稱
      spring.application.name=springcloud01-mq
      
      #指定rabbitmq
      spring.rabbitmq.host=192.168.234.128
      spring.rabbitmq.port=5672
      spring.rabbitmq.username=luyi
      spring.rabbitmq.password=luyi
      
      #設(shè)置交換器的名稱(處理日志的交換器)
      mq.config.exchange=log.topic

      consumer

      #設(shè)置應(yīng)用的名稱
      spring.application.name=springcloud01-mq
      
      #指定rabbitmq
      spring.rabbitmq.host=192.168.234.128
      spring.rabbitmq.port=5672
      spring.rabbitmq.username=luyi
      spring.rabbitmq.password=luyi
      
      #設(shè)置交換器的名稱(處理日志的交換器)
      mq.config.exchange=log.topic
      
      #info級別的隊(duì)列名稱
      mq.config.queue.info=log.info
      
      #error級別的隊(duì)列名稱
      mq.config.queue.error=log.error
      
      #log級別的隊(duì)列名稱
      mq.config.queue.all=log.all
      2.4 編寫provider

      UserSender

      /**
       * Author: LuYi
       * Date: 2019/11/3 14:06
       * Description: 消息發(fā)送者
       */
      @Component
      public class UserSender {
      
          @Autowired
          private RabbitTemplate rabbitTemplate;
      
          //交換器名稱
          @Value("${mq.config.exchange}")
          private String exchange;
      
          /**
           * 發(fā)送消息的方法
           */
          public void send(String msg){
              //向消息隊(duì)列發(fā)送消息
              //參數(shù)一: 交換器名稱
              //參數(shù)二: 路由鍵
              //參數(shù)三: 消息
              rabbitTemplate.convertAndSend(exchange, "user.log.debug", "user.log.debug  " msg);
              rabbitTemplate.convertAndSend(exchange, "user.log.info", "user.log.info  " msg);
              rabbitTemplate.convertAndSend(exchange, "user.log.warn", "user.log.warn  " msg);
              rabbitTemplate.convertAndSend(exchange, "user.log.error", "user.log.error  " msg);
          }
      }

      ProductSender

      /**
       * Author: LuYi
       * Date: 2019/11/3 14:06
       * Description: 消息發(fā)送者
       */
      @Component
      public class ProductSender {
      
          @Autowired
          private RabbitTemplate rabbitTemplate;
      
          //交換器名稱
          @Value("${mq.config.exchange}")
          private String exchange;
      
          /**
           * 發(fā)送消息的方法
           */
          public void send(String msg){
              //向消息隊(duì)列發(fā)送消息
              //參數(shù)一: 交換器名稱
              //參數(shù)二: 路由鍵
              //參數(shù)三: 消息
              rabbitTemplate.convertAndSend(exchange, "product.log.debug", "product.log.debug  " msg);
              rabbitTemplate.convertAndSend(exchange, "product.log.info", "product.log.info  " msg);
              rabbitTemplate.convertAndSend(exchange, "product.log.warn", "product.log.warn  " msg);
              rabbitTemplate.convertAndSend(exchange, "product.log.error", "product.log.error  " msg);
          }
      }

      OrderSender

      /**
       * Author: LuYi
       * Date: 2019/11/3 14:06
       * Description: 消息發(fā)送者
       */
      @Component
      public class OrderSender {
      
          @Autowired
          private RabbitTemplate rabbitTemplate;
      
          //交換器名稱
          @Value("${mq.config.exchange}")
          private String exchange;
      
          /**
           * 發(fā)送消息的方法
           */
          public void send(String msg){
              //向消息隊(duì)列發(fā)送消息
              //參數(shù)一: 交換器名稱
              //參數(shù)二: 路由鍵
              //參數(shù)三: 消息
              rabbitTemplate.convertAndSend(exchange, "order.log.debug", "order.log.debug  " msg);
              rabbitTemplate.convertAndSend(exchange, "order.log.info", "order.log.info  " msg);
              rabbitTemplate.convertAndSend(exchange, "order.log.warn", "order.log.warn  " msg);
              rabbitTemplate.convertAndSend(exchange, "order.log.error", "order.log.error  " msg);
          }
      }
      2.5 編寫consumer

      InfoReceiver

      /**
       * Author: LuYi
       * Date: 2019/11/3 14:12
       * Description: 消息接收者
       *
       * @RabbitListener bindings:綁定隊(duì)列
       *
       * @QueueBinding value:綁定隊(duì)列名稱
       *                exchange:配置交換器
       *
       * @Queue value:配置隊(duì)列名稱
       *         autoDelete:是否為可刪除的臨時隊(duì)列
       *
       * @Exchange value:為交換器起名
       *            type:指定當(dāng)前交換器的類型
       */
      @Component
      @RabbitListener(
              bindings = @QueueBinding(
                      value = @Queue(value = "${mq.config.queue.info}", autoDelete = "true"),
                      exchange = @Exchange(value = "${mq.config.exchange}", type = ExchangeTypes.TOPIC),
                      key = "*.log.info"
              )
      )
      public class InfoReceiver {
      
          /**
           * 接收消息的方法,采用消息隊(duì)列監(jiān)聽機(jī)制
           * @param msg
           */
          @RabbitHandler
          public void process(String msg){
      
              System.out.println("InfoReceiver : "   msg);
          }
      }

      ErrorReceiver

      /**
       * Author: LuYi
       * Date: 2019/11/3 14:12
       * Description: 消息接收者
       *
       * @RabbitListener bindings:綁定隊(duì)列
       *
       * @QueueBinding value:綁定隊(duì)列名稱
       *                exchange:配置交換器
       *
       * @Queue value:配置隊(duì)列名稱
       *         autoDelete:是否為可刪除的臨時隊(duì)列
       *
       * @Exchange value:為交換器起名
       *            type:指定當(dāng)前交換器的類型
       */
      @Component
      @RabbitListener(
              bindings = @QueueBinding(
                      value = @Queue(value = "${mq.config.queue.error}", autoDelete = "true"),
                      exchange = @Exchange(value = "${mq.config.exchange}", type = ExchangeTypes.TOPIC),
                      key = "*.log.error"
              )
      )
      public class ErrorReceiver {
      
          /**
           * 接收消息的方法,采用消息隊(duì)列監(jiān)聽機(jī)制
           * @param msg
           */
          @RabbitHandler
          public void process(String msg){
      
              System.out.println("ErrorReceiver : "   msg);
          }
      }

      AllReceiver

      /**
       * Author: LuYi
       * Date: 2019/11/3 14:12
       * Description: 消息接收者
       *
       * @RabbitListener bindings:綁定隊(duì)列
       *
       * @QueueBinding value:綁定隊(duì)列名稱
       *                exchange:配置交換器
       *
       * @Queue value:配置隊(duì)列名稱
       *         autoDelete:是否為可刪除的臨時隊(duì)列
       *
       * @Exchange value:為交換器起名
       *            type:指定當(dāng)前交換器的類型
       */
      @Component
      @RabbitListener(
              bindings = @QueueBinding(
                      value = @Queue(value = "${mq.config.queue.all}", autoDelete = "true"),
                      exchange = @Exchange(value = "${mq.config.exchange}", type = ExchangeTypes.TOPIC),
                      key = "*.log.*"
              )
      )
      public class AllReceiver {
      
          /**
           * 接收消息的方法,采用消息隊(duì)列監(jiān)聽機(jī)制
           * @param msg
           */
          @RabbitHandler
          public void process(String msg){
      
              System.out.println("AllReceiver : "   msg);
          }
      }
      2.6 測試
      /**
       * 消息隊(duì)列測試類
       */
      @RunWith(SpringRunner.class)
      @SpringBootTest(classes = Springcloud01MqApplication.class)
      class Springcloud01MqApplicationTests {
      
      	@Autowired
      	private UserSender userSender;
      	@Autowired
      	private ProductSender productSender;
      	@Autowired
      	private OrderSender orderSender;
      
      	@Test
      	void contextLoads() {
      	}
      
      	@Test
      	public void test1() {
      		userSender.send("UserSender...");
      		productSender.send("ProductSender...");
      		orderSender.send("OrderSender...");
      	}
      
      }

      3. Fanout交換器(廣播)

      3.1 需求

      3.2 創(chuàng)建項(xiàng)目

      rabbitmq-fanout-consumer

      rabbitmq-fanout-provider

      3.3 修改配置文件

      consumer

      #設(shè)置應(yīng)用的名稱
      spring.application.name=springcloud01-mq
      
      #指定rabbitmq
      spring.rabbitmq.host=192.168.234.128
      spring.rabbitmq.port=5672
      spring.rabbitmq.username=luyi
      spring.rabbitmq.password=luyi
      
      #設(shè)置交換器的名稱
      mq.config.exchange=order.fanout
      
      #短信隊(duì)列名稱
      mq.config.queue.sms=order.sms
      
      #push隊(duì)列名稱
      mq.config.queue.push=order.push

      provider

      #設(shè)置應(yīng)用的名稱
      spring.application.name=springcloud01-mq
      
      #指定rabbitmq
      spring.rabbitmq.host=192.168.234.128
      spring.rabbitmq.port=5672
      spring.rabbitmq.username=luyi
      spring.rabbitmq.password=luyi
      
      #設(shè)置交換器的名稱(處理日志的交換器)
      mq.config.exchange=order.fanout
      3.4 編寫consumer

      SmsReceiver

      /**
       * Author: LuYi
       * Date: 2019/11/3 14:12
       * Description: 消息接收者
       *
       * @RabbitListener bindings:綁定隊(duì)列
       *
       * @QueueBinding value:綁定隊(duì)列名稱
       *                exchange:配置交換器
       *
       * @Queue value:配置隊(duì)列名稱
       *         autoDelete:是否為可刪除的臨時隊(duì)列
       *
       * @Exchange value:為交換器起名
       *            type:指定當(dāng)前交換器的類型
       */
      @Component
      @RabbitListener(
              bindings = @QueueBinding(
                      value = @Queue(value = "${mq.config.queue.sms}", autoDelete = "true"),
                      exchange = @Exchange(value = "${mq.config.exchange}", type = ExchangeTypes.FANOUT)
              )
      )
      public class SmsReceiver {
      
          /**
           * 接收消息的方法,采用消息隊(duì)列監(jiān)聽機(jī)制
           * @param msg
           */
          @RabbitHandler
          public void process(String msg){
      
              System.out.println("SmsReceiver : "   msg);
          }
      }

      PushReceiver

      /**
       * Author: LuYi
       * Date: 2019/11/3 14:12
       * Description: 消息接收者
       *
       * @RabbitListener bindings:綁定隊(duì)列
       *
       * @QueueBinding value:綁定隊(duì)列名稱
       *                exchange:配置交換器
       *
       * @Queue value:配置隊(duì)列名稱
       *         autoDelete:是否為可刪除的臨時隊(duì)列
       *
       * @Exchange value:為交換器起名
       *            type:指定當(dāng)前交換器的類型
       */
      @Component
      @RabbitListener(
              bindings = @QueueBinding(
                      value = @Queue(value = "${mq.config.queue.push}", autoDelete = "true"),
                      exchange = @Exchange(value = "${mq.config.exchange}", type = ExchangeTypes.FANOUT)
              )
      )
      public class PushReceiver {
      
          /**
           * 接收消息的方法,采用消息隊(duì)列監(jiān)聽機(jī)制
           * @param msg
           */
          @RabbitHandler
          public void process(String msg){
      
              System.out.println("PushReceiver : "   msg);
          }
      }
      3.5 編寫provider
      /**
       * Author: LuYi
       * Date: 2019/11/3 14:06
       * Description: 消息發(fā)送者
       */
      @Component
      public class OrderSender {
      
          @Autowired
          private RabbitTemplate rabbitTemplate;
      
          //交換器名稱
          @Value("${mq.config.exchange}")
          private String exchange;
      
          /**
           * 發(fā)送消息的方法
           */
          public void send(String msg){
              //向消息隊(duì)列發(fā)送消息
              //參數(shù)一: 交換器名稱
              //參數(shù)二: 路由鍵
              //參數(shù)三: 消息
              rabbitTemplate.convertAndSend(exchange, "", msg);
          }
      }
      3.6 測試
      /**
       * 消息隊(duì)列測試類
       */
      @RunWith(SpringRunner.class)
      @SpringBootTest(classes = Springcloud01MqApplication.class)
      class Springcloud01MqApplicationTests {
      
      	@Autowired
      	private OrderSender orderSender;
      
      	@Test
      	void contextLoads() {
      	}
      
      	@Test
      	public void test1() throws InterruptedException {
      		while (true){
      			Thread.sleep(1000);
      			orderSender.send("Hello RabbitMQ");
      		}
      	}
      
      }

      4.使用RabbbitMQ實(shí)現(xiàn)松耦合設(shè)計

      4.1 修改配置文件
      #設(shè)置應(yīng)用的名稱
      spring.application.name=springcloud01-mq
      
      #指定rabbitmq
      spring.rabbitmq.host=192.168.234.128
      spring.rabbitmq.port=5672
      spring.rabbitmq.username=luyi
      spring.rabbitmq.password=luyi
      
      #設(shè)置交換器的名稱
      mq.config.exchange=order.fanout
      
      #短信隊(duì)列名稱
      mq.config.queue.sms=order.sms
      
      #push隊(duì)列名稱
      mq.config.queue.push=order.push
      
      #紅包服務(wù)隊(duì)列名稱
      mq.config.queue.red=order.red
      4.2 添加receiver

      RedReceiver

      /**
       * Author: LuYi
       * Date: 2019/11/4 16:20
       * Description: 消息接收者
       *
       * @RabbitListener bindings:綁定隊(duì)列
       *
       * @QueueBinding value:綁定隊(duì)列名稱
       *                exchange:配置交換器
       *
       * @Queue value:配置隊(duì)列名稱
       *         autoDelete:是否為可刪除的臨時隊(duì)列
       *
       * @Exchange value:為交換器起名
       *            type:指定當(dāng)前交換器的類型
       */
      @Component
      @RabbitListener(
              bindings = @QueueBinding(
                      value = @Queue(value = "${mq.config.queue.red}", autoDelete = "true"),
                      exchange = @Exchange(value = "${mq.config.exchange}", type = ExchangeTypes.FANOUT)
              )
      )
      public class RedReceiver {
      
          @RabbitHandler
          public void process(String msg){
              System.out.println("給用戶發(fā)送10元紅包     "   msg);
          }
      }

      九、RabbitMQ消息處理

      1. RabbitMQ的消息持久化處理

      1.1 創(chuàng)建項(xiàng)目

      rabbitmq-direct-durable-provider

      rabbitmq-direct-durable-consumer

      1.2 autoDelete

      @Queue:當(dāng)所有消費(fèi)客戶端連接斷開后,是否自動刪除隊(duì)列,如果設(shè)置成true表示刪除,false表示不刪除

      @Exchange:當(dāng)所有綁定隊(duì)列都不在使用時,是否自動刪除交換機(jī),true:刪除,false:不刪除

      2.RabbitMQ中的消息確認(rèn)ACK機(jī)制

      • 什么是消息確認(rèn)ACK

        如果在消費(fèi)者接收消息是,服務(wù)器出現(xiàn)了異常導(dǎo)致這條消息無法被接收,這是RabbitMQ可以通過ACK機(jī)制保證消息不丟失

      • ACK的消息確認(rèn)機(jī)制

        ACK機(jī)制是消費(fèi)者接收到消息之后向RabbitMQ發(fā)送的,RabbitMQ收到ACK后才會將該消息從消息隊(duì)列中刪除。

        • 如果RabbitMQ沒有接收到消費(fèi)者的ACK標(biāo)識,那么RabbitMQ會將這個消息放入消息隊(duì)列中再次發(fā)送。

        • 如果在集群情況下,RabbitMQ會將這個消息推送給在線的其他消費(fèi)者。這種機(jī)制確保了消費(fèi)者服務(wù)端在發(fā)生故障時不會丟失任何消息。

        • 消息永遠(yuǎn)不會從RabbitMQ中刪除,只有當(dāng)消費(fèi)者正確發(fā)送了ACK并且RabbitMQ也做出了確認(rèn)之后才會進(jìn)行刪除。

        • 消息的ACK確認(rèn)機(jī)制是默認(rèn)打開的。

      • ACK機(jī)制的開發(fā)注意事項(xiàng)

        如果忘記了ACK,那么當(dāng)Consumer退出時,Message會一直重發(fā),這樣就會占用大量的RabbitMQ的內(nèi)存,由于RabbitMQ會長時間運(yùn)行,所以這個情況是致命的。

      魯毅發(fā)布了11 篇原創(chuàng)文章 · 獲贊 0 · 訪問量 146私信 關(guān)注來源:https://www./content-4-639951.html

        本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多