探索解析微服务下的RabbitMQ
概览
本文主要介绍如何使用RabbitMQ消息代理来实现分布式系统之间的通信,从而促进微服务的松耦合。
RabbitMQ,也被称为开源消息代理,它支持多种消息协议,并且可以部署在分布式系统上。它轻量级,便于部署应用程序。它主要充当一个队列,其中输入的消息可以首先被操作。RabbitMQ可以在许多操作系统和云环境中运行,并为大多数流行语言提供了广泛的开发工具。它是生产者-消费者模式,生产者发出信息,消费者消费信息。RabbitMQ的主要特点如下:
异步消息
分布式部署
管理和监控
企业和云计算
安装
对于RabbitMQ,首先需要在系统中安装ErLang,因为RabbitMQ是用ErLang语言编写的。安装Erlang之后,你可以通过下面的介绍从它的官网下载最新版本的 RabbitMQ 。
在微服务中使用RabbitMQ
在您的微服务体系结构中,RabbitMQ是实现消息队列的最简单的免费的可用选项之一。这些队列模式有助于解耦各个微服务之间的通信来增加应用程序的弹性。我们可以将这些队列用于各种目的,比如核心微服务之间的交互、微服务的解耦、实现故障转移机制,以及通过消息代理发送电子邮件通知。
无论在哪里,只要有两个或两个以上的核心模块需要相互通信,我们就不应该进行直接的HTTP调用,因为它们会使核心层产生紧耦合,并且当每个核心模块有更多实例时将很难管理。而且每当服务宕机时,HTTP调用模式就会失败,因为在服务重启之后,我们将无法跟踪旧的HTTP请求调用。这就产生了对RabbitMQ的需求。
探索解析微服务下的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
bjectMapper().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调用,并消除核心微服务的紧密耦合。这将帮助您在更高级别上实现微服务的可伸缩性,并在微服务之间添加故障转移机制。
探索解析微服务下的RabbitMQ的更多相关文章
- Nepxion Discovery【探索】微服务企业级解决方案
Nepxion Discovery[探索]微服务企业级解决方案] Nepxion Discovery[探索]使用指南,基于Spring Cloud Greenwich版.Finchley版和Hoxto ...
- AspNetCore微服务下的网关-Kong(一)
Kong是Mashape开源的高性能高可用API网关和API服务管理层.它基于OpenResty,进行API管理,并提供了插件实现API的AOP.Kong在Mashape 管理了超过15,000 个A ...
- 微服务下的契约测试(CDC)解读
1. 前言 有近两周没有在公众号中发表文章了,看过我之前公众号的读者都知道,公众号中近期在连载<RobotFramework接口自动化系列课程>,原本计划每周更新一篇,最近由于博主在带一个 ...
- 小D课堂-SpringBoot 2.x微信支付在线教育网站项目实战_4-2.微服务下登录检验解决方案 JWT讲解
笔记 2.微服务下登录检验解决方案 JWT讲解 简介:微服务下登录检验解决方案 JWT讲解 json wen token 1.JWT 是一个开放标准,它定义了一种用于简洁,自包含的用于通信双方 ...
- 小D课堂 - 新版本微服务springcloud+Docker教程_2_04微服务下电商项目基础模块设计
笔记 4.微服务下电商项目基础模块设计 简介:微服务下电商项目基础模块设计 分离几个模块,课程围绕这个基础项目进行学习 小而精的方式学习微服务 1.用户服务 ...
- CODING DevOps 系列第五课:微服务测试——微服务下展开体系化的微服务测试
微服务测试的痛点与挑战 这张图可以形象地展示单体服务和微服务的对比,单体应用就像左边巨大的集装箱,软件模块和应用都包括其中:而微服务就像是由一个小集装箱组成,微小的服务组成一个庞大.完整的系统.单体服 ...
- 【智简联接,万物互联】华为云·云享专家董昕:Serverless和微服务下, IoT的变革蓄势待发
摘要:Serverless.微服务,这些新技术和IoT有什么关系?纵观IoT行业的发展,云服务又扮演了什么角色? IoT并不是一个新名词.新技术,很长一段时间,它甚至给人一种"下工地&quo ...
- 微服务下前后端分离的统一认证授权服务,基于Spring Security OAuth2 + Spring Cloud Gateway实现单点登录
1. 整体架构 在这种结构中,网关就是一个资源服务器,它负责统一授权(鉴权).路由转发.保护下游微服务. 后端微服务应用完全不用考虑权限问题,也不需要引入spring security依赖,就正常的 ...
- Spring Cloud微服务下的权限架构调研
随着微服务架构的流行,系统架构调整,项目权限系统模块开发提上日程,需要对权限架构进行设计以及技术选型.所以这段时间看了下相关的资料,做了几个对比选择. 一.架构图 初步设想的架构如下,结构很简单:eu ...
随机推荐
- 模拟退火算法(run away poj1379)
http://poj.org/problem?id=1379 Run Away Time Limit: 3000MS Memory Limit: 65536K Total Submissions: ...
- 【php】---mysql语法增、删、改、查---【巷子】
1.mysql基本语法 001.增 语法: insert into 表名 (列1,列2,列3) values(值1,值2,值3) 批量插入:插入insert-插入多行 语 ...
- CH1402 后缀数组【Hash】【字符串】【二分】
1402 后缀数组 0x10「基本数据结构」例题 描述 后缀数组 (SA) 是一种重要的数据结构,通常使用倍增或者DC3算法实现,这超出了我们的讨论范围.在本题中,我们希望使用快排.Hash与二分实现 ...
- 解决ORA-29857:表空间中存在域索引和/或次级对象 & ORA-01940:无法删除当前连接的用户问题 分类: oracle sde 2015-07-30 20:13 8人阅读 评论(0) 收藏
今天ArcGIS的SDE发生了一点小故障,导致系统表丢失,所以需要重建一下SDE数据库,在删除SDE用户和所在的表空间过程中遇到下面两个ORA错误,解决方法如下: 1)删除表空间时报错:ORA-298 ...
- Django之urls.py详解
urls.py:URL分发器(路由配置文件)URL配置(URLconf)就像是Django所支撑网站的目录.它的本质是URL模式以及要为该URL模式调用的视图函数之间的映射表.你就是以这种方式告诉Dj ...
- 【css flex】将多个<div>放在同一行
使用style里的flex属性 默认情况下,一个div独占一行 使用css选择器给外层div加上以下flex属性,则该div的子div可以在同一行中显示, .runs-paginator-flex-c ...
- linux/Mac使用du查看目录占用的磁盘大小
[1]du命令用来查看目录或文件所占用磁盘空间的大小.常用选项组合为: du -sh [2]若要查看一个目录下每个文件和文件夹的磁盘占用空间,使用如下命令: du -ah --max-depth=1 ...
- (转) SpringBoot非官方教程 | 第一篇:构建第一个SpringBoot工程
简介 spring boot 它的设计目的就是为例简化开发,开启了各种自动装配,你不想写各种配置文件,引入相关的依赖就能迅速搭建起一个web工程.它采用的是建立生产就绪的应用程序观点,优先于配置的惯例 ...
- uva 1048 最短路的建图 (巧,精品)
大白书 P341这题说的是给了NT种飞机票,给了价钱和整个途径,给了nI条要旅游的路线.使用飞机票都必须从头第一站开始坐,可以再这个路径上的任何一点下飞机一但下飞机了就不能再上飞机,只能重新买票,对于 ...
- Underscore-逐行分析
标签: // Underscore.js 1.8.3// http://underscorejs.org// (c) 2009-2015 Jeremy Ashkenas, DocumentCloud ...