05-微服务-RabbitMQ-概述

RabbitMQ

1.初识MQ

1.1.同步和异步通讯

微服务间通讯有同步和异步两种方式:

同步通讯:就像打电话,需要实时响应。

异步通讯:就像发邮件,不需要马上回复。

image-20210717161939695

两种方式各有优劣,打电话可以立即得到响应,但是你却不能跟多个人同时通话。发送邮件可以同时与多个人收发邮件,但是往往响应会有延迟。

1.1.1.同步通讯

我们之前学习的Feign调用就属于同步方式,虽然调用可以实时得到结果,但存在下面的问题:

image-20210717162004285

总结:

同步调用的优点:

  • 时效性较强,可以立即得到结果

同步调用的问题:

  • 耦合度高
  • 性能和吞吐能力下降
  • 有额外的资源消耗
  • 有级联失败问题

1.1.2.异步通讯

异步调用则可以避免上述问题:

我们以购买商品为例,用户支付后需要调用订单服务完成订单状态修改,调用物流服务,从仓库分配响应的库存并准备发货。

在事件模式中,支付服务是事件发布者(publisher),在支付完成后只需要发布一个支付成功的事件(event),事件中带上订单id。

订单服务和物流服务是事件订阅者(Consumer),订阅支付成功的事件,监听到事件后完成自己业务即可。

为了解除事件发布者与订阅者之间的耦合,两者并不是直接通信,而是有一个中间人(Broker)。发布者发布事件到Broker,不关心谁来订阅事件。订阅者从Broker订阅事件,不关心谁发来的消息。

image-20210422095356088

Broker 是一个像数据总线一样的东西,所有的服务要接收数据和发送数据都发到这个总线上,这个总线就像协议一样,让服务间的通讯变得标准和可控。

好处:

  • 吞吐量提升:无需等待订阅者处理完成,响应更快速

  • 故障隔离:服务没有直接调用,不存在级联失败问题

  • 调用间没有阻塞,不会造成无效的资源占用

  • 耦合度极低,每个服务都可以灵活插拔,可替换

  • 流量削峰:不管发布事件的流量波动多大,都由Broker接收,订阅者可以按照自己的速度去处理事件

缺点:

  • 架构复杂了,业务没有明显的流程线,不好管理
  • 需要依赖于Broker的可靠、安全、性能

好在现在开源软件或云平台上 Broker 的软件是非常成熟的,比较常见的一种就是我们今天要学习的MQ技术。

1.2.技术对比:

MQ,中文是消息队列(MessageQueue),字面来看就是存放消息的队列。也就是事件驱动架构中的Broker。

比较常见的MQ实现:

  • ActiveMQ
  • RabbitMQ
  • RocketMQ
  • Kafka

几种常见MQ的对比:

RabbitMQActiveMQRocketMQKafka
公司/社区RabbitApache阿里Apache
开发语言ErlangJavaJavaScala&Java
协议支持AMQP,XMPP,SMTP,STOMPOpenWire,STOMP,REST,XMPP,AMQP自定义协议自定义协议
可用性一般
单机吞吐量一般非常高
消息延迟微秒级毫秒级毫秒级毫秒以内
消息可靠性一般一般

追求可用性:Kafka、 RocketMQ 、RabbitMQ

追求可靠性:RabbitMQ、RocketMQ

追求吞吐能力:RocketMQ、Kafka

追求消息低延迟:RabbitMQ、Kafka

2.快速入门

2.1.安装RabbitMQ

安装RabbitMQ,参考课前资料:

image-20210717162628635

MQ的基本结构:

image-20210717162752376

RabbitMQ中的一些角色:

  • publisher:生产者
  • consumer:消费者
  • exchange个:交换机,负责消息路由
  • queue:队列,存储消息
  • virtualHost:虚拟主机,隔离不同租户的exchange、queue、消息的隔离

2.2.RabbitMQ消息模型

RabbitMQ官方提供了5个不同的Demo示例,对应了不同的消息模型:

image-20210717163332646

2.3.导入Demo工程

课前资料提供了一个Demo工程,mq-demo:

image-20210717163253264

导入后可以看到结构如下:

image-20210717163604330

包括三部分:

  • mq-demo:父工程,管理项目依赖
  • publisher:消息的发送者
  • consumer:消息的消费者

2.4.入门案例

简单队列模式的模型图:

image-20210717163434647

官方的HelloWorld是基于最基础的消息队列模型来实现的,只包括三个角色:

  • publisher:消息发布者,将消息发送到队列queue
  • queue:消息队列,负责接受并缓存消息
  • consumer:订阅队列,处理队列中的消息

2.4.1.publisher实现

思路:

  • 建立连接
  • 创建Channel
  • 声明队列
  • 发送消息
  • 关闭连接和channel

代码实现:

package cn.itcast.mq.helloworld;import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import org.junit.Test;import java.io.IOException;
import java.util.concurrent.TimeoutException;public class PublisherTest {@Testpublic void testSendMessage() throws IOException, TimeoutException {// 1.建立连接ConnectionFactory factory = new ConnectionFactory();// 1.1.设置连接参数,分别是:主机名、端口号、vhost、用户名、密码factory.setHost("192.168.150.101");factory.setPort(5672);factory.setVirtualHost("/");factory.setUsername("root");factory.setPassword("root");// 1.2.建立连接Connection connection = factory.newConnection();// 2.创建通道ChannelChannel channel = connection.createChannel();// 3.创建队列String queueName = "simple.queue";channel.queueDeclare(queueName, false, false, false, null);// 4.发送消息String message = "hello, rabbitmq!";channel.basicPublish("", queueName, null, message.getBytes());System.out.println("发送消息成功:【" + message + "】");// 5.关闭通道和连接channel.close();connection.close();}
}

2.4.2.consumer实现

代码思路:

  • 建立连接
  • 创建Channel
  • 声明队列
  • 订阅消息

代码实现:

package cn.itcast.mq.helloworld;import com.rabbitmq.client.*;import java.io.IOException;
import java.util.concurrent.TimeoutException;public class ConsumerTest {public static void main(String[] args) throws IOException, TimeoutException {// 1.建立连接ConnectionFactory factory = new ConnectionFactory();// 1.1.设置连接参数,分别是:主机名、端口号、vhost、用户名、密码factory.setHost("192.168.150.101");factory.setPort(5672);factory.setVirtualHost("/");factory.setUsername("root");factory.setPassword("root");// 1.2.建立连接Connection connection = factory.newConnection();// 2.创建通道ChannelChannel channel = connection.createChannel();// 3.创建队列String queueName = "simple.queue";channel.queueDeclare(queueName, false, false, false, null);// 4.订阅消息channel.basicConsume(queueName, true, new DefaultConsumer(channel){@Overridepublic void handleDelivery(String consumerTag, Envelope envelope,AMQP.BasicProperties properties, byte[] body) throws IOException {// 5.处理消息String message = new String(body);System.out.println("接收到消息:【" + message + "】");}});System.out.println("等待接收消息。。。。");}
}

2.5.总结

基本消息队列的消息发送流程:

  1. 建立connection

  2. 创建channel

  3. 利用channel声明队列

  4. 利用channel向队列发送消息

基本消息队列的消息接收流程:

  1. 建立connection

  2. 创建channel

  3. 利用channel声明队列

  4. 定义consumer的消费行为handleDelivery()

  5. 利用channel将消费者与队列绑定

学习笔记,整理自黑马程序员教程

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/597376.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

canvas设置文字阴影

查看专栏目录 canvas示例教程100专栏,提供canvas的基础知识,高级动画,相关应用扩展等信息。canvas作为html的一部分,是图像图标地图可视化的一个重要的基础,学好了canvas,在其他的一些应用上将会起到非常重…

实现JavaScript中的数组排序功能

一、引言 在JavaScript中,数组是一种常用的数据结构,而排序是处理数组的常见任务。对于JavaScript中的数组排序,我们可以通过多种方式来实现。本篇博客将详细介绍如何使用JavaScript实现数组排序功能,并分享一些感悟。 二、实现…

SQL的一些基本语句

SQL(Structured Query Language)是一种用于管理关系型数据库的语言。下面是一些常用的SQL基本语句: 创建表格: CREATE TABLE table_name (column1 datatype,column2 datatype,column3 datatype,... );插入数据: INSERT…

详解C语言入门程序:HelloWorld.c

#include <stdio.h> // 头文件&#xff0c;使用<>编译系统会在系统头文件目录搜索在C语言中&#xff0c;#include 是预处理指令&#xff0c;用于将指定的头文件内容插入到当前源文件中。这里的 <stdio.h> 是一个标准库头文件&#xff0c;其中包含了与输入输出…

MySQL之CRUD、常见函数及union查询

目录 一. CRUD 1.1 什么是crud 1.2 SELECT(查询) 1.3 INSERT(新增) 1.4 UPDATE(修改) 1.5 DELETE(删除) 二. 函数 2.1 常见函数 2.2 流程控制函数 2.3 聚合函数 三. union与union all 3.1 union 3.2 union all 3.3 具体不同 3.4 结论 四. 思维导图 一. CRUD 1.1 什么是crud…

解析:Eureka的工作原理

Eureka是Netflix开源的一个基于REST的的服务发现注册框架&#xff0c;它遵循了REST协议&#xff0c;提供了一套简单的API来完成服务的注册和发现。Eureka能够帮助分布式系统中的服务提供者自动将自身注册到注册中心&#xff0c;同时也能够让服务消费者从注册中心发现服务提供者…

【愚公系列】2023年12月 HarmonyOS应用开发者高级认证(完美答案)

&#x1f3c6; 作者简介&#xff0c;愚公搬代码 &#x1f3c6;《头衔》&#xff1a;华为云特约编辑&#xff0c;华为云云享专家&#xff0c;华为开发者专家&#xff0c;华为产品云测专家&#xff0c;CSDN博客专家&#xff0c;CSDN商业化专家&#xff0c;阿里云专家博主&#xf…

express框架搭建后台服务

express 1. 使用express创建web服务器&#xff1a;2. 中间件中间件分类&#xff1a; 3.解决跨域问题&#xff1a;1. CORS2.JSONP 1. 使用express创建web服务器&#xff1a; 1. 导入express2. 创建web服务器3. 启动web服务器// 1. 导入express const express require(express)/…

6. Mybatis 缓存

6. Mybatis 缓存 MyBatis 包含一个非常强大的查询缓存特性,它可以非常方便地配置和定制。缓存可以极大的提升查询效率MyBatis系统中默认定义了两级缓存 一级缓存二级缓存 默认情况下&#xff0c;只有一级缓存&#xff08;SqlSession级别的缓存&#xff0c;也称为本地缓存&…

Transforer逐模块讲解

本文将按照transformer的结构图依次对各个模块进行讲解&#xff1a; 可以看一下模型的大致结构&#xff1a;主要有encode和decode两大部分组成&#xff0c;数据经过词embedding以及位置embedding得到encode的时输入数据 输入部分 embedding就是从原始数据中提取出单词或位置&…

ubuntu22.04配置双网卡绑定提升带宽

这里写自定义目录标题 Bonding简介配置验证参考链接 Bonding简介 bonding(绑定)是一种linux系统下的网卡绑定技术&#xff0c;可以把服务器上n个物理网卡在系统内部抽象(绑定)成一个逻辑上的网卡&#xff0c;能够提升网络吞吐量、实现网络冗余、负载均衡等功能&#xff0c;有很…

软件设计师考试的知识点

这里先总结一下考试的知识点。 上午的考试考题中只有单选题&#xff0c;涉及范围很广&#xff0c;但是考查不深。 上午的考试知识点以及分数比重&#xff1a; 知识点 分数 说明 比例 软件工程基础知识 13 开发方法与开发模型、数据流图与数据字典、结构化设计、测试方法…

2023年工作初体验

23年终于正式入职&#xff0c;参与了正式上线的电商平台、crm平台等项目的研发&#xff0c;公司规模较小&#xff0c;气氛融洽&#xff0c;没有任何勾心斗角、末位淘汰&#xff0c;几乎没什么压力。虽然是我的第一家公司&#xff0c;但实际是个适合养老的公司&#xff08;笑 总…

双击shutdown.bat关闭Tomcat报错:未设置关闭端口~

你们好&#xff0c;我是金金金。 场景 当我startup.bat启动tomcat之后&#xff0c;然后双击shutdown.bat关闭&#xff0c;结果报错了~ 排查 看报错信息很明显了&#xff0c;未配置关闭端口&#xff0c;突然想起来了我在安装的时候都选的是默认的配置&#xff0c;我还记得有这…

快速批量运行命令

Ansible 是 redhat 提供的自动化运维工具&#xff0c;它是 Python编写&#xff0c;可以通过 pip 安装。 pip install ansible 它通过任务(task)、角色(role)、剧本(playbook) 组织工作项目&#xff0c;适用于批量化系统配置、软件部署等需要复杂操作的工作。 但对于批量运行命…

简单罗列一下jdk常见的垃圾收集器

1. Serial Collector 类型&#xff1a;单线程收集器。工作模式&#xff1a;使用标记-压缩算法进行老年代的垃圾收集&#xff0c;标记-复制算法进行年轻代的垃圾收集。特点&#xff1a;简单高效&#xff0c;适用于单核处理器或小型堆内存。在进行垃圾收集时&#xff0c;会暂停所…

nginx日志目录详解

Nginx 默认会打印访问日志&#xff08;access log&#xff09;和错误日志&#xff08;error log&#xff09;。这些日志对于监控和调试网站非常有用。以下是关于如何配置和查看 Nginx 日志的一些基本信息&#xff1a; 配置 Nginx 日志 访问日志&#xff08;Access Log&#xf…

宝塔部署nuxt3项目问题解决

使用宝塔部署nuxt3项目一直没成功&#xff0c;网站502&#xff0c;要不就是资源加载不出来 测试使用宝塔版本8.0.4 添加node项目方式失败&#xff0c;项目更目录设置到server,无法设置运行目录为public, 导致网站资源加载不出来&#xff0c;设置到.output目录&#xff0c;会提…

继电器组开发控制

也是通过树莓派IO口的控制来实现继电器组的开发 继电器组有四根信号线&#xff0c;2根电源线。 通过gpio readall 查看树莓派各个端口的信息选择26 27 28 29 作为信号端口 编程可能会遇到的一些问题 1、通过键盘输入指令的时候&#xff0c;如果用scanf 会有bug&#xff0c;导…

JavaScript高级程序设计读书记录(一):语言基础,语法,变量,数据类型

1. 语法 很大程度上借鉴了 C 语言和其他类 C 语言&#xff0c;如 Java 和 Perl. 1.1 区分大小写 1.2 标识符 第一个字符必须是一个字母、下划线&#xff08;_&#xff09;或美元符号&#xff08;$&#xff09;&#xff1b; 剩下的其他字符可以是字母、下划线、美元符号或数…