一 . MQ:message queue
消息隊(duì)列的作用: 1 通信解耦 2 高峰限流
原理分析:
一開(kāi)始,認(rèn)證系統(tǒng)是強(qiáng)耦合的,A系統(tǒng)傳遞認(rèn)證系統(tǒng)消息接收計(jì)算結(jié)果的過(guò)程中
1 傳給認(rèn)證系統(tǒng)
2 認(rèn)證系統(tǒng)計(jì)算
3 返回計(jì)算結(jié)果
4 讀取A系統(tǒng)邏輯
只要當(dāng)前計(jì)算沒(méi)有完成,對(duì)于認(rèn)證系統(tǒng)來(lái)講消耗線程資源.并存在強(qiáng)耦合現(xiàn)象
有了消息隊(duì)列,每一次連接不管是生成消息還是消費(fèi)消息,都有各自的邏輯與其他邏輯無(wú)關(guān)--通信解耦
通信強(qiáng)耦合的情況下高峰訪問(wèn)拒絕,達(dá)到了高峰限流的效果
二 . Rabbitmq
1 rabbitmq的結(jié)構(gòu)(組件)
? 外部: 生產(chǎn)者和消費(fèi)者
生產(chǎn)者:對(duì)于消息來(lái)講,生成消息客戶端是生產(chǎn)者
消費(fèi)者:消費(fèi)消息執(zhí)行消費(fèi)后的邏輯的客戶端是消費(fèi)者
客戶端可以使用各種其他技術(shù)或者語(yǔ)言 都不是rabbitmq自身的技術(shù)
2 rabbitmq內(nèi)部組件
connection:基于底層通信邏輯的長(zhǎng)連接
channel:基于長(zhǎng)連接創(chuàng)建的;可以在一次長(zhǎng)連接的基礎(chǔ)上多次頻繁的創(chuàng)建和銷毀,占用資源非常少
交換機(jī)Exchange優(yōu)點(diǎn):并發(fā)能力高 并發(fā)穩(wěn)定
客戶端連接發(fā)送消息,多種情況都需要并發(fā)的發(fā)送,如果從客戶端執(zhí)行并發(fā)的發(fā)送邏輯,rabbitmq的并發(fā)能力就限制在了客戶端
exchange基于erlang語(yǔ)言開(kāi)發(fā)的(并發(fā),可控制線程)
queue:rabbitmq中的隊(duì)列,根據(jù)不同的情況隊(duì)列可以完成不同的工作
使用場(chǎng)景:在項(xiàng)目中,將一些無(wú)需即時(shí)返回且耗時(shí)的操作提取出來(lái),進(jìn)行了異步處理,而這種異步處理的方式大大的節(jié)省了服務(wù)器的請(qǐng)求響應(yīng)時(shí)間,從而提高了系統(tǒng)的吞吐量至壤。
三 . rabbitmq的五種工作模式
1 簡(jiǎn)單模式
1 )一個(gè)生產(chǎn)者將消息交給默認(rèn)的交換機(jī)(AMQP default)
2 )交換機(jī)獲取消息后交給綁定的這個(gè)生產(chǎn)者的隊(duì)列(其中關(guān)系是通過(guò)隊(duì)列名稱完成的)
3 )監(jiān)聽(tīng)當(dāng)前隊(duì)列的消費(fèi)者獲取消息,執(zhí)行消費(fèi)邏輯
應(yīng)用場(chǎng)景:短信聊天
2 工作模式(資源爭(zhēng)搶)
1 )生產(chǎn)者將消息交給交換機(jī)
2 )交換機(jī)交給綁定的隊(duì)列
3 )隊(duì)列由多個(gè)消費(fèi)者同時(shí)監(jiān)聽(tīng),只有其中一個(gè)能獲取者一條消息,形成了資源的爭(zhēng)搶,誰(shuí)的資源空閑大,爭(zhēng)搶到的可能越大
3 發(fā)布訂閱(publish/fanout)
1 )生產(chǎn)者扔給交換機(jī)消息
2 )交換機(jī)根據(jù)自身的類型(fanout)將會(huì)把所有消息復(fù)制同步到所有與其綁定的隊(duì)列
3 )每個(gè)隊(duì)列可以有一個(gè)消費(fèi)者,接收消息進(jìn)行消費(fèi)邏輯
4 路由模式(routing/dircet)
1 )生產(chǎn)者還是將消息發(fā)送給交換機(jī),消息攜帶具體的路由key(routingKey)
2 )交換機(jī)類型direct,將接受到消息中的routingKey與之綁定隊(duì)列的routingKey比對(duì)
3 )消費(fèi)者監(jiān)聽(tīng)一個(gè)隊(duì)列,獲取消息,執(zhí)行消費(fèi)邏輯.
5 topic主題模式
1 )生產(chǎn)端發(fā)送消息,消息攜帶具體的路由key
2 )交換機(jī)的類型topic
3 )隊(duì)列綁定交換機(jī)不在使用具體的路由key而是一個(gè)范圍值
與路由模式的區(qū)別:路由模式中的queue綁定攜帶的具體的key值,路由細(xì)化劃分,topic主題模式queue攜帶的key是一個(gè)范圍的匹配,某一類消息的獲取
四 . rabbitmq的安裝及虛擬機(jī)和用戶名的創(chuàng)建
https://www.cnblogs.com/nanlinghan/p/9960361.html
五 . springboot整合rabbitmq
整合思路:1 )配置信息 2 )配置類 (明確初始化對(duì)象,初始化一個(gè)工廠,就從工廠獲取連接;生產(chǎn)端邏輯實(shí)現(xiàn)簡(jiǎn)單;) 3 )二次封裝
springboot
自動(dòng)配置:掃描同名,下級(jí)包
根據(jù)依賴的文件自動(dòng)配置需要的內(nèi)容(一旦依賴了jdbc,不配置datasource就報(bào)錯(cuò))
springboot就會(huì)根據(jù)依賴的amqp自動(dòng)創(chuàng)建連接消息隊(duì)列的內(nèi)部connection,封裝一個(gè)對(duì)外調(diào)用的對(duì)象rabbitTemplate模板對(duì)象;做生產(chǎn)邏輯
利用底層連接,實(shí)現(xiàn)異步非阻塞監(jiān)聽(tīng),只需要在方法上使用注解,就可以將監(jiān)聽(tīng)內(nèi)容傳遞給方法的參數(shù);
???????????歡迎工作一到五年的Java工程師朋友們加入Java架構(gòu)交流圈:874811168 圈內(nèi)提供免費(fèi)的Java架構(gòu)學(xué)習(xí)資料(里面有高可用、高并發(fā)、高性能及分布式富蓄、Jvm性能調(diào)優(yōu)、Spring源碼慢逾,MyBatis立倍,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多個(gè)知識(shí)點(diǎn)的架構(gòu)資料)合理利用自己每一分每一秒的時(shí)間來(lái)學(xué)習(xí)提升自己,不要再用"沒(méi)有時(shí)間“來(lái)掩飾自己思想上的懶惰侣滩!趁年輕口注,使勁拼,給未來(lái)的自己一個(gè)交代君珠!
1 添加依賴
簡(jiǎn)化依賴
groupId在maven庫(kù)是一個(gè)具有結(jié)構(gòu)的文件夾
artifactId是一整個(gè)文件夾
version是一個(gè)文件夾
org\springframework\boot\spring-boot-starter-amqp
org.springframework.boot
spring-boot-starter-amqp
2 配置文件(application.properties)
spring.rabbitmq.host=10.9.100.26
spring.rabbitmq.port=5672
spring.rabbitmq.username=easymall
spring.rabbitmq.password=123456
spring.rabbitmq.virtualHost=/easymall
3 配置文件中聲明對(duì)象
內(nèi)部完成各種連接channel等的封裝
聲明需要的隊(duì)列和交換機(jī)
配置類中完成這種聲明,并且交換機(jī),隊(duì)列的對(duì)象由框架維護(hù),何時(shí)調(diào)用由業(yè)務(wù)邏輯決定;
1 package com.jt.config;
2 import org.springframework.amqp.core.Binding;
3 import org.springframework.amqp.core.BindingBuilder;
4 import org.springframework.amqp.core.DirectExchange;
5 import org.springframework.amqp.core.Queue;
6 import org.springframework.context.annotation.Bean;
7 import org.springframework.context.annotation.Configuration;
8 @Configuration
9 public class RabbitmqConfig {
10? ? //路由模式做案例
11? ? //準(zhǔn)備2個(gè)queue,1個(gè)路由交換機(jī)
12? ? //聲明2個(gè)隊(duì)列
13? ? @Bean
14? ? public Queue queue01(){
15? ? ? ? //org.springframework.amqp.core.
16? ? ? ? return new Queue("springboot-q1", false);
17? ? }?
18? ? @Bean
19? ? public Queue queue02(){
20? ? ? ? //org.springframework.amqp.core.
21? ? ? ? return new Queue("springboot-q2", false);
22? ? }
23? ? @Bean//聲明交換機(jī)
24? ? public DirectExchange ex(){
25? ? ? ? return new DirectExchange("springboot-ex");
26? ? }
27? ? //聲明綁定關(guān)系
28? ? @Bean
29? ? public Binding bind01(){
30? ? ? ? return BindingBuilder.
31? ? ? ? ? ? ? ? bind(queue01()).to(ex()).with("item.add");
32? ? }
33? ? @Bean
34? ? public Binding bind02(){
35? ? ? ? return BindingBuilder.
36? ? ? ? ? ? ? ? bind(queue02()).to(ex()).with("item.update");}}
4 編寫生成者代碼
??? 編寫到一個(gè)controller中,接收訪問(wèn)的參數(shù),利用參數(shù)作為消息發(fā)送到交換機(jī)攜帶路由key
1 package com.jt.controller;
2
3 import org.springframework.amqp.rabbit.core.RabbitTemplate;
4 import org.springframework.beans.factory.annotation.Autowired;
5 import org.springframework.stereotype.Controller;
6 import org.springframework.web.bind.annotation.RequestMapping;
7 import org.springframework.web.bind.annotation.ResponseBody;
????歡迎工作一到五年的Java工程師朋友們加入Java架構(gòu)交流圈:874811168
8
9 @Controller
10 public class MsgController {
11? ? @Autowired
12? ? private RabbitTemplate rabbit;
13? ? /*
14? ? ? * 接收消息msg
15? ? ? */
16? ? @RequestMapping("msg")
17? ? @ResponseBody
18? ? public String sendMsg(String msg,String routingKey){
19? ? ? ? //注入自動(dòng)配置的rabbitTemplate對(duì)象發(fā)送消息
20? ? ? ? rabbit.convertAndSend("springboot-ex", routingKey, msg);
21? ? ? ? return "success";
22? ? }
23 }
5 消費(fèi)端
2個(gè)消費(fèi)者,監(jiān)聽(tīng)2個(gè)隊(duì)列,發(fā)送的不同路由key會(huì)在不同的消費(fèi)端完成消費(fèi)邏輯
1 package com.jt.component;
2
3 import org.springframework.amqp.rabbit.annotation.RabbitListener;
4 import org.springframework.stereotype.Component;
5 @Component
6 public class ConsumerCon {
7? ? //實(shí)現(xiàn)消費(fèi)邏輯,需要完成異步監(jiān)聽(tīng)
8? ? //監(jiān)聽(tīng)注解會(huì)綁定隊(duì)列的消費(fèi)者和當(dāng)前的方法,一旦消費(fèi)者獲取消息,會(huì)把消息內(nèi)容傳遞給
9? ? //自定義的方法參數(shù)msg
?????? //歡迎工作一到五年的Java工程師朋友們加入Java架構(gòu)交流圈:874811168
10? ? @RabbitListener(queues="springboot-q1")
11? ? public void process01(String msg){
12? ? ? ? System.out.println("消費(fèi)者1接收商品新增:"+msg);
13? ? }
14? ?
15? ? @RabbitListener(queues="springboot-q2")
16? ? public void process02(String msg){
17? ? ? ? System.out.println("消費(fèi)者2接收到商品更新:"+msg);
18? ? }
19 }