docker rabbitmq_一文看懂Rabbitmq,從安裝到實戰演練

Rabbitmq的初步使用

隨著微服務概念發展,大應用逐步拆分為小應用,提高開發效率,專門的人做專門的事情,逐漸的流行起來。

在微服務上實現通信的方式大部分是采用rpc方式,也有升級版本的grpc。

還有另外一種實現就是使用mq來進行解耦。

今天初識mq,快速入門先,準備一個環境實現案例,該文涉及以下內容:

  • 安裝rabbitmq
  • mq能解決的問題
  • 實戰演練

安裝

rabbitmq的安裝我們采用docker的方式,docker方便我們快速的實現rabbitmq的安裝,不需要再對安裝mq進行頭疼。

docker 的兩種方式

docker方式

//拉取mq鏡像
docker pull rabbitmq
//啟動mq
docker run -d --name rabbitmq3.7.7 -p 5672:5672 -p 15672:15672 -v `pwd`/data:/var/lib/rabbitmq --hostname myRabbit -e RABBITMQ_DEFAULT_VHOST=my_vhost  -e RABBITMQ_DEFAULT_USER=admin -e RABBITMQ_DEFAULT_PASS=admin df80af9ca0c9

說明:

  1. -d 后臺運行容器;
  2. --name 指定容器名;
  3. -p 指定服務運行的端口(5672:應用訪問端口;15672:控制臺Web端口號);
  4. -v 映射目錄或文件;
  5. --hostname 主機名(RabbitMQ的一個重要注意事項是它根據所謂的 “節點名稱” 存儲數據,默認為主機名);
  6. -e 指定環境變量;(RABBITMQDEFAULTVHOST:默認虛擬機名;RABBITMQDEFAULTUSER:默認的用戶名;RABBITMQDEFAULTPASS:默認用戶名的密碼)

docker-compose 方式

version

下載的rabbitmq內置管理界面,ip:15672 用戶名與密碼是我們在啟動是寫入的。

739c35ebecc6cc686c34148f7f06729d.png

mq能解決什么?

通俗的來說,主要使用MQ來解決以下三個問題。

異步消息

在業務中,經常會遇到同時發送郵件,短信或者其他通知內容服務。業務初期,采用同步或者異步處理方式都需要等發送完畢后再返回給客戶端。中間有一定的延遲

0f10817f8a808879665fd11e4351073d.png

業務增長后,此方式系統性能就會造成很大的浪費。采用消息隊列,將這幾個服務進行解耦,只需將消息內容發送到消息隊列中,降低用戶的等待時間,體驗效果比原先好很多。

36a503018d4227d9633f88e991cd31db.png

應用間解耦

同一個服務中可能需要其他服務的配合才能完成一項業務操作.還是拿常見的購物案例來說明。

在京東下單支付后,消息要通知到商家,郵件通知用戶已經購買某商品。

如果這兩種操作都采用同步執行,用戶等待時間會變長。

采用mq方式之后,訂單系統將消息持久化到mq上,返回給用戶下單成功。

  • 商家接收到用戶的下單信息,進行處理,如果有庫存管理那么需要進行庫存處理。
  • 郵件通知用戶,告知用戶下單成功。

mq保證消息的可靠投遞,不會導致消息丟失,保證消息的高可靠性。如果庫存出現失敗也不會導致用戶下單失敗的情況,可以重新進行投遞。

流量削峰

流量削峰,一般是同一時間涌進來很多請求,后臺處理不過來。那么需要采用削峰方式來處理。

簡單來說是通過一個隊列承接瞬時過來流量洪峰,在消費端平滑的將消息推送出去,如果消費者消費不及時可以將消息內容持久化在隊列中,消息不存在丟失。

  1. 消費端不及時進行消費,還可以動態的擴增消費者數量,提高消費速度。
  2. 設定相關的閥值,多余的消息直接丟棄,告知用戶秒殺失敗等業務消息內容。

8611fa2a30504c3586c846f81e350483.png

實戰案例

本文是按照Java語言進行,使用Spring boot搭建,包管理工具Gradle。

導入rabbitmq jar包

 compile("org.springframework.boot:spring-boot-starter-amqp:1.5.10.RELEASE")

配置mq

yaml 文件配置

spring:rabbitmq:host: 192.168.110.5port: 5672username: gutstpassword: guest

準備好模板類,供后面直接使用

package com.infervision.config;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.AcknowledgeMode;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.ChannelAwareMessageListener;
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** @author: fruiqi* @date: 19-2-18 下午2:42* @version:1.0 rabbit配置**/
@Configuration
public class RabbitConfig {
/*** 日志**/private static final Logger logger = LoggerFactory.getLogger(RabbitConfig.class);@Value("${spring.rabbitmq.username}")String userName;@Value("${spring.rabbitmq.password}")String userPassword;@Value("${spring.rabbitmq.host}")String host;@Value("${spring.rabbitmq.port}")Integer port;
/*** 注入** @param* @return com.rabbitmq.client.Connection* @author fruiqi* @date 19-1-22 下午5:41**/@Beanpublic ConnectionFactory getConnection() throws Exception {CachingConnectionFactory factory = new CachingConnectionFactory();factory.setUsername(userName);factory.setPassword(userPassword);factory.setHost(host);factory.setPort(port);return factory;}/*** 創建制定的 監聽容器** @param queueName  監聽的隊列名字* @param listenerChannel 設置是否將監聽的頻道 公開給已注冊的* @param PrefetchCount  告訴代理一次請求多少條消息過來* @param ConcurrentConsumers  制定創建多少個并發的消費者數量* @param acknowledgeMode  消息確認模式* @param listener 監聽器* @return org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer**/public SimpleMessageListenerContainer setSimpleMessageListenerContainer(String queueName, boolean listenerChannel,int PrefetchCount, int ConcurrentConsumers,AcknowledgeMode acknowledgeMode,ChannelAwareMessageListener listener) throws Exception {SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(getConnection());container.setQueueNames(queueName);container.setExposeListenerChannel(listenerChannel);container.setPrefetchCount(PrefetchCount);container.setConcurrentConsumers(ConcurrentConsumers);container.setAcknowledgeMode(acknowledgeMode);container.setMessageListener(listener);return container;}
}package com.infervision.config;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;/*** @author: fruiqi* @date: 19-2-18 下午2:51* @version:1.0**/
@Component
public class MsgSender {private static final Logger logger = LoggerFactory.getLogger(MsgSender.class);@Autowiredprivate RabbitTemplate rabbitTemplate;/*** @param exchange 交換機名稱* @param routingKey 路由名稱* @param message 消息內容* @return void* @description //TODO 發送消息到消息隊列中**/public void sendMsg(String exchange, String routingKey, Object message) {try {rabbitTemplate.convertAndSend(exchange,routingKey,message);}catch (Exception e){logger.error("[ERROR] send statistic message error ",e);}}}

實例鏈接mq

在使用rabbitmq 有的時候需要自己客戶端創建queue,但有的時候并不是自己創建,在rabbitmq頁面上進行創建queue,其他消費者直接引用。

客戶端創建mq

//初始化隊列,如果隊列已存在,則不作任何處理 如果有權限控制如下操作并不能實現@Beanpublic Queue dicomQueue() {return new Queue(getMacPreStr(DICOM_QUEUE_NAME));}//初始化交換機@Beanpublic Exchange topicExchange() {return ExchangeBuilder.topicExchange((DEFAULT_TOPIC_EXCHANGE).durable(true).build();}// 將隊列與交換機按照路由規則進行綁定@BeanBinding bindingExchangeDicomQueue(Queue dicomQueue, TopicExchange topicExchange) {return BindingBuilder.bind(dicomQueue).to(topicExchange).with(DICOM_QUEUE_ROUTING_KEY);}

使用

隊列的使用:一個是發送,屬于生產者;一個是監聽,屬于消費者.

生產者實現

在mq配置模板類中,專門實現了一個發送類,發送文件內容,直接調用發送接口即可。

@AutowiredRabbitService rabbitService;/*** 練習 發送數據到 mq中* 1. 發送的數據會到 mq中* 2. 我們配置的 listener 是用來消費消息的* 3. 客戶端配置 可以參考 RabbitClientConfig* @param name 名字編號* @param vo   實體內容* @return: com.infervision.model.NameVo*/@ApiOperation(value = "增加name信息", notes = "實體信息")@PostMapping(value = "/{name}")@ApiImplicitParam(paramType = "query", name = "name", value = "用戶名字", required = true, dataType = "string")public NameVo addNameVo(@RequestParam String name, @RequestBody NameVo vo) {rabbitService.sendMessage(DEFAULT_TOPIC_TEST_EXCHANGE, LABEL_FIEL_XML_QUEUE_ROUTING_KEY, JSON.toJSONString(vo));return vo;}@Service
public class RabbitServiceImpl implements RabbitService {@AutowiredMsgSender msgSender;/*** 嘗試發送 message 到mq中* @param message* @return: void*/@Overridepublic void sendMessage(String exchange, String routingKey,String message) {msgSender.sendMsg(exchange, routingKey, message);}
}

消費者實現

消費者實現有兩種方式,一種通過注解的方式監聽,一種是實現ChannelAwareMessageListener類來實現消費。

注解實現監聽

//在方法上進行注入。配置工廠幫助提高單個消費者一次性消費的消息數量,設置多少個消費者,用來提高程序的性能
@RabbitListener(queues = "dicom.queue",containerFactory = "multipleConsumerContainerFactory")public void processDicomMessage(Message message, Channel channel) {logger.info(message);}// 工廠可以在配置模板類中中配置好。
@Bean("multipleConsumerContainerFactory")public SimpleRabbitListenerContainerFactory multipleConsumerContainerFactory(SimpleRabbitListenerContainerFactoryConfigurer configurer, ConnectionFactory connectionFactory) {SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();factory.setPrefetchCount(50);factory.setConcurrentConsumers(10);factory.setAcknowledgeMode(AcknowledgeMode.MANUAL);configurer.configure(factory, connectionFactory);return factory;}

實現接口方式

/**

總結

以上內容就完成了rabbitmq 從搭建到使用全部的流程。當然里面還有更多的可以讓我們去探討,比如mq的隊列模式,一個系統配置多個mq等等內容。敬請期待我們下一篇mq系列內容。

大家在系統中使用過mq嗎?你們使用的mq是什么樣的?可以在留言區我們一起探討哦。

·END·

路雖遠,行則必至

本文原發于 同名微信公眾號「胖琪的升級之路」,回復「1024」你懂得,給個贊唄。

微信ID:YoungRUIQ

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/538750.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/538750.shtml
英文地址,請注明出處:http://en.pswp.cn/news/538750.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Angular v6 正式發布

Angular 6 正式發布 Angular 6 已經正式發布了!這個主要版本并不關注于底層的框架,更多地關注于工具鏈,以及使 Angular 在未來更容易快速推進。 作為發布的一部分,我們同步了主要的框架包 (angular/core, angular/common, angula…

bootstrap五星評分_如何用純代碼實現評分星級顯示?

showRatingStars/*** showRatingStars 顯示評分星級* param {Object} myCanvas 畫布對象* param {Number} rating 評分* param {Number} counts star個數* param {Number} size star大小* param {Object} style star樣式* Example: style {* borderColor:"#21DEEF",…

18.變量

Java是一種強類型語言,每個變量都必須聲明其類型。 Java變量是程序中最基本的存儲單元,其要素包括變量名,變量類型和作用域。 變量在使用前必須對其聲明,只有在變量聲明以后,才能為其分配相應長度的存儲單元。 注意事項…

alertdialog android api 11,android – 設備api級別11的DialogFragments

我設法在兼容包的DialogFragment.java中正確修復了這個問題:改變第74行:boolean mShowsDialog false;注釋掉第232行:// mShowsDialog mContainerId 0;然后將兩個show方法更改為:public void show(FragmentManager manager, Str…

py 字典添加多個value_# Python 3 # Python 3字典Dictionary(1)

Python3 字典字典是另一種可變容器模型,且可存儲任意類型對象。字典的每個鍵值(key>value)對用冒號(:)分割,每個對之間用逗號(,)分割,整個字典包括在花括號({})中 ,格式如下所示:d {key1 : value1, key2 : value2 }鍵必須是唯…

饒軍:Apache Kafka的過去,現在,和未來

歡迎大家前往騰訊云社區,獲取更多騰訊海量技術實踐干貨哦~ 本文首發在云社區,未經許可,不得轉載。大家好,我大概簡單的介紹一下,我叫饒軍,我是硅谷的初創公司Con?uent的聯合創始人之一,我們公司…

機器人 樹莓派 自閉癥_用機器人孩子提高社交能力 讓自閉兒童走出自閉

一項由耶魯大學的研究團隊研究發現,通過讓患有自閉癥譜系障礙(autism spectrum disorders,ASD)的孩童與機器人相處一個月,極大地提高了自閉癥兒童的社交能力。耶魯大學研究中的機器人可以通過眼神接觸和模仿其它社交行為,通過講故事和互動游戲…

19.常量-final

final 常量 final修飾,只能被初始化一次。 public static void main(String[] args){final int a3;a4;//報錯/*TestVariable.java:7: 錯誤: 無法為最終變量a分配值a4;^ 1 個錯誤*/}常量一般用大寫來修飾。 ------------- 更多的Java,Angular,…

Android手機avi轉換為mp4手機,如何把avi轉換為mp4

AVI是目前比較常見的一種音視頻交錯格式,這種格式的文件在多種地方是可以看到的,大多在游戲錄制、光盤文件中可以見到此類文件。其畫質不錯,適合在電腦上觀看,但是現在我們使用較多的是手機、iPad等設備。如果我們想要在這些設備上…

偽代碼書寫規范_C++代碼書寫規范(推薦新手程序員)

代碼就是程序員的面子,無論是在工作中在電腦上寫程序代碼還是在面試時在紙上寫演示代碼我們都希望寫出整潔,優雅的代碼。特別在工作中當我們碰到需要維護別人的代碼,或者是多人參與一個項目大家一起寫代碼的時候,如果碰到一些丑陋…

Java基礎17:Java IO流總結

版權聲明:本文為博主原創文章,未經博主允許不得轉載。 https://blog.csdn.net/a724888/article/details/80201802 這位大俠,這是我的公眾號:程序員江湖。 分享程序員面試與技術的那些事。 干貨滿滿,關注就送。 本文介…

nuxt頁面跳轉_nuxt 項目如何解決組件復用時頁面不刷新的問題

組件復用會在兩種情況下發生:1、使用 keep-alive 時,頁面再次跳轉時,數據不更新每一次路由的切換都會導致頁面被重新渲染,無論是各種鉤子還是異步獲取數據函數都會被執行,為了提高網站性能,可以使用 keep-a…

20.命名規范

所有變量,方法,類名:見名知意 變量,方法名 --首字母小寫和駝峰原則。 如:run(),getName() 常量 ---大寫字母和下劃線:MAX_VALUE 類名 ---首字母大寫和駝峰原則。 如:Man,HelloWorld ------…

k8s查看pod的yaml文件_K8s-yaml的使用及命令

YAML配置文件管理對象對象管理:# 創建deployment資源kubectl create-f nginx-deployment.yaml# 查看deploymentkubectl get deploy# 查看ReplicaSetkubectl get rs# 查看pods所有標簽kubectl get pods--show-labels# 根據標簽查看podskubectl get pods-l appnginx# …

Orange Business Services 全球發布 Easy Go Network,幫助企業加速實現“網絡即服務”...

100% 數字化, 軟件定義網絡( SDN) 產品在 75 個國家上市 在云、移動化、大數據和物聯網(IoT)趨勢的推動下,企業不斷尋求更加智能和更加靈活的網絡,以支持他們的數字化轉型方案。而網絡只有演進至“網絡即服務”(NaaS&a…

vue的html自動刷新,Vue頁面刷新記住頁面狀態的實現

環境vue項目,頁面有搜索、篩選項等。需求頁面跳轉,切換或者刷新,希望可以記住用戶在頁面的篩選狀態方案v1vue有提供一種緩存組件的解決方案 — keep-alive。緩存不活動的組件實例,而不是銷毀它們。我們可以使用keep-alive包括路由…

python 程序停止打印日志_Python日志打印

簡單示例import sysimport ctypesimport loggingimport logging.handlersreload(sys)sys.setdefaultencoding(utf-8)LOG_FILE test_loglogging.basicConfig(filename LOG_FILE,format %(asctime)s - %(levelname)s -%(process)d- %(filename)s:%(funcName)s:%(lineno)d - %(…

21.和和instance of

>> 右移一位。相當于除2 << 左移一位。相當于乘2 public static void main(String[] args) {int a3<<2;int b12>>2;System.out.println("a"a);System.out.println("b"b);}解析&#xff1a; a3*2*212 b12/2/23 運行結果&#xf…

html語言閃爍特效代碼,css3 文字閃爍特效代碼

今天給大家分享幾個文字閃爍特效代碼&#xff0c;純css3代碼實現&#xff0c;對于新手小伙伴值得拿來學習一下。文字閃爍特效一通過改變透明度來實現文字的漸變閃爍&#xff0c;代碼如下&#xff1a;文字閃爍&#xff1a;閃爍效果.main{color: #666;margin-top: 50px;}/* 定義k…