探究解析微服務下的RabbitMQ

摘要:概覽本文主要詳情如何使用RabbitMQ消息代理商來實現分布式系統之間的通信,從而促進微服務的松耦合。RabbitMQ,也被稱為開源消息代理商,它支持多種消息協議,并且可以部署在分布式系統上。它輕量級,便于部署應用程序。它主要充任一個隊列,其中輸入的消息可以首先被操作。RabbitMQ可以在許多操作系統

概覽

本文主要詳情如何使用RabbitMQ消息代理商來實現分布式系統之間的通信,從而促進微服務的松耦合。

RabbitMQ,也被稱為開源消息代理商,它支持多種消息協議,并且可以部署在分布式系統上。它輕量級,便于部署應用程序。它主要充任一個隊列,其中輸入的消息可以首先被操作。RabbitMQ可以在許多操作系統和云環境中運行,并為大多數流行語言提供了廣泛的開發工具。它是生產者-消費者模式,生產者發出信息,消費者消費信息。RabbitMQ的主要特點如下:

異步消息

分布式部署

管理和監控

企業和云計算

安裝

對于RabbitMQ,首先需要在系統中安裝ErLang,由于RabbitMQ是用ErLang語言編寫的。安裝Erlang之后,你可以通過下面的詳情從它的官網下載最新版本的?RabbitMQ?。

在微服務中使用RabbitMQ

在您的微服務體系結構中,RabbitMQ是實現消息隊列的最簡單的免費的可用選項之一。這些隊列模式有助于解耦各個微服務之間的通信來添加應用程序的彈性。我們可以將這些隊列用于各種目的,比方核心微服務之間的交互、微服務的解耦、實現故障轉移機制,以及通過消息代理商發送電子郵件通知。

無論在哪里,只需有兩個或者兩個以上的核心板塊需要相互通信,我們就不應該進行直接的HTTP調用,由于它們會使核心層產生緊耦合,并且當每個核心板塊有更多實例時將很難管理。而且每當服務宕機時,HTTP調用模式就會失敗,由于在服務重啟之后,我們將無法跟蹤舊的HTTP請求調用。這就產生了對RabbitMQ的需求。

在微服務中設置RabbitMQ

在微服務架構中,為了演示,我們將使用一個可以通過任何核心微服務發送電子郵件通知的示例模式。在這種模式下,我們將有一個可以存在任何核心微服務的生產者,它將生成電子郵件內容并將其發送到隊列。而后,這個電子郵件內容由總是在等待隊列中新消息的消費者來解決。

請注意,因為正在使用Spring Boot構建微服務,因而我們將為Spring提供配置。

1)生產者:這一層負責生成電子郵件內容,并將此內容發送給RabbitMQ中的消息代理商。

a)在properties文件中,我們需要配置隊列名和交換類型,以及安裝RabbitMQ服務器的主機和端口。

queue.name=messagequeue

fanout.exchange=messagequeue-exchange

spring.rabbitmq.host: localhost

spring.rabbitmq.port: 5672

spring.rabbitmq.username: guest

spring.rabbitmq.password: guest

b)我們需要創立一個配置類,它將使用隊列名和交換類型將隊列綁定到微服務板塊。

@Configuration

public class RabbitConfiguration {

@Value("${fanout.exchange}")

private String fanoutExchange;

@Value("${queue.name}")

private String queueName;

@Bean

Queue queue() {

? return new Queue(queueName, true);

}

@Bean

FanoutExchange exchange() {

? return new FanoutExchange(fanoutExchange);

}

@Bean

Binding binding(Queue queue, FanoutExchange exchange) {

? return BindingBuilder.bind(queue).to(exchange);

}

}

c)最后,我們需要一個工具類,它將使用Spring框架提供的RabbitTemplate將實際的電子郵件內容發送到隊列中。

@Component

public class QueueProducer {

protected Logger logger = LoggerFactory.getLogger(getClass());

@Value("${fanout.exchange}")

private String fanoutExchange;

private final RabbitTemplate rabbitTemplate;

@Autowired

public QueueProducer(RabbitTemplate rabbitTemplate) {

? super();

? this.rabbitTemplate = rabbitTemplate;

}

public void produce(NotificationRequestDTO notificationDTO) throws Exception {

? logger.info("Storing notification...");

? rabbitTemplate.setExchange(fanoutExchange);

? rabbitTemplate.convertAndSend(new ObjectMapper().writeValueAsString(notificationDTO));

? logger.info("Notification stored in queue sucessfully");

}

}

d)而后,您可以在板塊的任何地方調用這個produce方法。

{

? queueProducer.produce(notificationDTO);

}

2) 消費者:這一層負責使用FIFO方法從RabbitMQ消息代理商中消費消息,而后執行與電子郵件相關的操作。

a)在這個properties文件中,我們需要配置隊列名和交換類型,以及安裝RabbitMQ服務器的主機和端口。

queue.name=messagequeue

fanout.exchange=messagequeue-exchange

spring.rabbitmq.host: localhost

spring.rabbitmq.port: 5672

spring.rabbitmq.username: guest

spring.rabbitmq.password: guest

b)我們需要創立一個配置類,它將使用隊列名和交換類型將隊列綁定到微服務板塊。此外,在消費者的RabbitMQ配置中,我們需要創立一個充任消費者的MessageListenerAdapter?bean,它始終偵聽從隊列中傳入的消息。這個MessageListenerAdapter將有一個帶有消費者工具類和defaultListenerMethod的有參構造函數,在這里我們可以指定與電子郵件相關的操作。

@Configuration

public class RabbitConfiguration {

private static final String LISTENER_METHOD = "receiveMessage";

@Value("${queue.name}")

private String queueName;

@Value("${fanout.exchange}")

private String fanoutExchange;

@Bean

Queue queue() {

? return new Queue(queueName, true);

}

@Bean

FanoutExchange exchange() {

? return new FanoutExchange(fanoutExchange);

}

@Bean

Binding binding(Queue queue, FanoutExchange exchange) {

? return BindingBuilder.bind(queue).to(exchange);

}

@Bean

SimpleMessageListenerContainer container(ConnectionFactory connectionFactory,

? MessageListenerAdapter listenerAdapter) {

? SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();

? container.setConnectionFactory(connectionFactory);

? container.setQueueNames(queueName);

? container.setMessageListener(listenerAdapter);

? return container;

}

@Bean

MessageListenerAdapter listenerAdapter(QueueConsumer consumer) {

? return new MessageListenerAdapter(consumer, LISTENER_METHOD);

}

}

c)而后,需要創立具備特定消息偵聽器方法的?QueueConsumer類,在該類中我們可以進行實際發送電子郵件的操作。

@Component

public class QueueConsumer {

@Autowired

MailServiceImpl mailServiceImpl;

protected Logger logger = LoggerFactory.getLogger(getClass());

public void receiveMessage(String message) {

? logger.info("Received (String) " + message);

? processMessage(message);

}

public void receiveMessage(byte[] message) {

? String strMessage = new String(message);

? logger.info("Received (No String) " + strMessage);

? processMessage(strMessage);

}

private void processMessage(String message) {

? try {

? MailDTO mailDTO = new ObjectMapper().readValue(message, MailDTO.class);

? ValidationUtil.validateMailDTO(mailDTO);

? mailServiceImpl.sendMail(mailDTO, null);

? } catch (JsonParseException e) {

? logger.warn("Bad JSON in message: " + message);

? } catch (JsonMappingException e) {

? logger.warn("cannot map JSON to NotificationRequest: " + message);

? } catch (Exception e) {

? logger.error(e.getMessage());

? }

}

}

總結

通過使用RabbitMQ,您可以避免服務之間直接的HTTP調用,并消除核心微服務的緊密耦合。這將幫助您在更高級別上實現微服務的可伸縮性,并在微服務之間增加故障轉移機制。

  • 全部評論(0)
最新發布的資訊信息
【系統環境|服務器應用】Discuz發布帖子時默認顯示第一個主題分類的修改方法(2019-12-09 00:13)
【系統環境|軟件環境】Android | App內存優化 之 內存泄漏 要點概述 以及 處理實戰(2019-12-04 14:27)
【系統環境|軟件環境】MySQL InnoDB 事務(2019-12-04 14:26)
【系統環境|軟件環境】vue-router(單頁面應用控制中心)常見用法(2019-12-04 14:26)
【系統環境|軟件環境】Linux中的Kill命令(2019-12-04 14:26)
【系統環境|軟件環境】Linux 入門時必學60個文件解決命令(2019-12-04 14:26)
【系統環境|軟件環境】更新版ThreeJS 3D粒子波浪動畫(2019-12-04 14:26)
【系統環境|軟件環境】前臺開發WebStorm常用快捷鍵,火速收藏!(2019-12-04 14:25)
【系統環境|軟件環境】微博H5登錄和發微博組件(2019-12-04 14:25)
【系統環境|軟件環境】5分鐘談前臺面試,小伙伴都驚呆了(2019-12-04 14:23)
手機二維碼手機訪問領取大禮包
返回頂部
澳洲幸运10精准人工计划