概览

  本文主要介绍如何使用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的更多相关文章

  1. Nepxion Discovery【探索】微服务企业级解决方案

    Nepxion Discovery[探索]微服务企业级解决方案] Nepxion Discovery[探索]使用指南,基于Spring Cloud Greenwich版.Finchley版和Hoxto ...

  2. AspNetCore微服务下的网关-Kong(一)

    Kong是Mashape开源的高性能高可用API网关和API服务管理层.它基于OpenResty,进行API管理,并提供了插件实现API的AOP.Kong在Mashape 管理了超过15,000 个A ...

  3. 微服务下的契约测试(CDC)解读

    1. 前言 有近两周没有在公众号中发表文章了,看过我之前公众号的读者都知道,公众号中近期在连载<RobotFramework接口自动化系列课程>,原本计划每周更新一篇,最近由于博主在带一个 ...

  4. 小D课堂-SpringBoot 2.x微信支付在线教育网站项目实战_4-2.微服务下登录检验解决方案 JWT讲解

    笔记 2.微服务下登录检验解决方案 JWT讲解     简介:微服务下登录检验解决方案 JWT讲解 json wen token 1.JWT 是一个开放标准,它定义了一种用于简洁,自包含的用于通信双方 ...

  5. 小D课堂 - 新版本微服务springcloud+Docker教程_2_04微服务下电商项目基础模块设计

    笔记 4.微服务下电商项目基础模块设计     简介:微服务下电商项目基础模块设计 分离几个模块,课程围绕这个基础项目进行学习             小而精的方式学习微服务 1.用户服务       ...

  6. CODING DevOps 系列第五课:微服务测试——微服务下展开体系化的微服务测试

    微服务测试的痛点与挑战 这张图可以形象地展示单体服务和微服务的对比,单体应用就像左边巨大的集装箱,软件模块和应用都包括其中:而微服务就像是由一个小集装箱组成,微小的服务组成一个庞大.完整的系统.单体服 ...

  7. 【智简联接,万物互联】华为云·云享专家董昕:Serverless和微服务下, IoT的变革蓄势待发

    摘要:Serverless.微服务,这些新技术和IoT有什么关系?纵观IoT行业的发展,云服务又扮演了什么角色? IoT并不是一个新名词.新技术,很长一段时间,它甚至给人一种"下工地&quo ...

  8. 微服务下前后端分离的统一认证授权服务,基于Spring Security OAuth2 + Spring Cloud Gateway实现单点登录

    1.  整体架构 在这种结构中,网关就是一个资源服务器,它负责统一授权(鉴权).路由转发.保护下游微服务. 后端微服务应用完全不用考虑权限问题,也不需要引入spring security依赖,就正常的 ...

  9. Spring Cloud微服务下的权限架构调研

    随着微服务架构的流行,系统架构调整,项目权限系统模块开发提上日程,需要对权限架构进行设计以及技术选型.所以这段时间看了下相关的资料,做了几个对比选择. 一.架构图 初步设想的架构如下,结构很简单:eu ...

随机推荐

  1. 微信小程序 --- 缓存数据

    保存数据  /  读取数据  /  删除数据  /  数据异步操作 每一个微信小程序都可以有自己的本地缓存,可以通过wx.setStorage( wx.setStorageSync) ,wx.getS ...

  2. org.apache.log4j日志级别

    日志记录器(Logger)是日志处理的核心组件.log4j具有7种级别(Level).日志记录器(Logger)的可用级别Level (不包括自定义级别 Level)优先级从高到低:OFF.FATAL ...

  3. Java项目工程化之项目构建工具Maven

    欢迎查看Java开发之上帝之眼系列教程,如果您正在为Java后端庞大的体系所困扰,如果您正在为各种繁出不穷的技术和各种框架所迷茫,那么本系列文章将带您窥探Java庞大的体系.本系列教程希望您能站在上帝 ...

  4. js数组转成对象

    $scope.addalerts = []; $scope.addalertsString = JSON.stringify($scope.addalerts); 全部教程http://each.si ...

  5. Python开发【笔记】:为什么pymysql重连后才能查到新添加的数据

    PyMysql操控 问题描述: 之前做数据库模块的时候用到了pymysql,测试中发现了一个问题,创建两个程序,select.py从数据库中不断的读取,insert.py在数据库中插入多条数据,但是s ...

  6. linux 的nohup & 和daemon 总结(转)

    add by zhj:守护进程貌似跟nohup + &方式启动的进程差不多.都可以实现与终端的无关联.   原文:http://blog.csdn.net/lovemdx/article/de ...

  7. java 调用静态方法和构造函数和静态块执行的先后顺序

    构造方法是只有你在new对象的时候才会执行,静态语句块和静态方法在类加载到内存的时候就已经执行了,另外,静态语句块只能给静态变量赋值,里面不能出现方法,同样,静态方法里面也不能出现静态语句块 追问: ...

  8. mysql 数据操作 单表查询 group by 分组 目录

    mysql 数据操作 单表查询 group by 介绍 mysql 数据操作 单表查询 group by 聚合函数 mysql 数据操作 单表查询 group by 聚合函数 没有group by情况 ...

  9. Django—Form两种保留用户提交数据的方法

    用户在网页上进行表单填写时,有可能出现某项填写错误.一般情况下,用户在未发觉错误的情况下点击提交,则此表单的内容会清空,用户不得不再重新填写,这样的用户体验是及其糟糕的. 在此,我们有2种方法将用户的 ...

  10. VMware跨电脑移动Linux虚拟机

    环境:VMware-Workstation-12-Pro,Windows-10,CentOS-6.9-x86_64,Xshell5 概况 vmware自带的快照,克隆功能,都可以实现备份虚拟机的功能, ...