程序员必须掌握的消息中间件-RabbitMQ

news2024/11/16 5:43:02

一、Rabbit 概述

RabbitMQ 是一个开源的消息代理和队列服务器,用来通过普通协议在完全不同的应用中间共享数据,RabbitMQ 是使用 Erlang 语言来编写的,并且 RabbitMQ 是基于 AMQP 协议的。

特点:

  • 开源、性能优秀

    Erlang 语言最初用在交换机的架构模式,这样使得 RabbitMQ 在 Broker 之间进行数据交互的性能时非常优秀的。Erlang 的优点:Erlang 有着和原生 Socket 一样的延迟。

  • 可靠性

    提供可靠性消息投递模式(confirm)、返回模式(return)。

  • 扩展性

    多个RabbitMQ 节点可以组成一个集群,也可以根据实际业务情况动态地扩展集群中节点。

  • 与 SpringAOP 完美的整合、API 丰富

  • 保证数据不丢失的前提做到高可靠性、可用性

二、AMQP 协议

AMQP (Advanced Message Queuing Protocol) 即高级消息队列协议,是一个进程间传递异步消息网络协议

AMQP 模型

alt

工作过程如下:首先发布者(Publisher)发布消息(Message),经由交换机 Exchange。交换机根据路由规则将收到的消息分发给与该交换机绑定的 Queue。最后 AMQP 代理会将消息投递给订阅了此队列的消费者,或者消费者按照需求自行获取。

关于 AMQP 模型的几点说明:

  • 发布者、交换机、队列、消费者都可以有多个。AMQP 是一个网络协议,所以这个过程中的发布者,消费者,消息代理可以分别存在于不同的设备上。
  • 布者发布消息时可以给消息指定各种消息属性(Message Meta-data)。有些属性有可能会被消息代理(Brokers)使用,然而其他的属性则是完全不透明的,它们只能被接收消息的应用所使用。
  • 从安全角度考虑,网络是不可靠的,又或是消费者在处理消息的过程中意外挂掉,这样没有处理成功的消息就会丢失。基于此原因,AMQP 模块包含了一个消息确认机制:当一个消息从队列中投递给消费者后,不会立即从队列中删除,直到它收到来自消费者的确认回执(Acknowledgement)后,才完全从队列中删除。
  • 在某些情况下,例如当一个消息无法被成功路由时(无法从交换机分发到队列),消息或许会被返回给发布者并被丢弃。或者,如果消息代理执行了 延期操作,消息会被放入一个 死信队列中。此时,消息发布者可以选择某些参数来处理这些特殊情况。

Producer & Consumer

消息生产者(Producer),向 Broker 发送消息的客户端。

消息消费者(Consumer),从 Broker 消费消息的客户端。

Broker

一个 RabbitMQ Broker 可以简单地看作一个 RabbitMQ 服务节点,或者 RabbitMQ 服务实例。大多数情况下可以将一个 RabbitMQ Broker 看作一台 RabbitMQ 服务器。

Exchange

Exchange 即交换器,是用来发送消息的 AMQP 实体。Exchange 拿到一个消息之后将它路由给一个或零个队列。Exchange 使用哪种路由算法是由交换机类型绑定(Bindings)规则所决定的。

Binding

Producer 将消息发给 Exchange 时,一般会指定一个 RoutingKey (路由键),用来指定这个消息的路由规则,而这个 RoutingKey 需要与交换器类型和 BindingKey (绑定键) 联合使用才能最终生效

RabbitMQ 中通过 Binding (绑定) 将 Exchange 与 Queue(消息队列) 关联起来,在绑定时一般会指定一个 BindingKey,这样 RabbitMQ 就知道如何正确将消息路由到 Queue 中。一个绑定就是基于路由键将交换器和消息队列连接起来的路由规则。

生产者将消息发送给交换器,当 BindingKey 和 RoutingKey 相匹配时,消息会被路由到对应的队列中。注意BindingKey 并不是在所有的情况下都生效,它依赖于交换器类型,比如 fanout 类型的交换器就会无视,而是将消息路由到所有绑定到该交换器的队列中。

Exchange 类型

Exchange 有以下 4 种类型,不同的类型对应着不同的路由策略:

direct

Exchange 默认类型。路由规则是把消息路由到 Bindingkey 与 RoutingKey 完全匹配的 Queue 中。direct 类型常用在处理有优先级的任务,根据任务的优先级把消息发送到对应的队列,这样可以指派更多的资源去处理高优先级的队列。

alt

以上图为例,如果发送消息的时候 RoutingKey="booking",那么消息会路由到 Queue1 和 Queue2。如果在发送消息的时候设置 RoutingKey="create" 或 "confirm",消息只会路由到Queue2。如果以其他的 RoutingKey 发送消息,则消息不会路由到这两个队列中。

fanout

路由规则是把所有发送到该 Exchange 的消息路由到所有与它绑定的 Queue 中,不需要做任何判断操作,所以 fanout 类型是所有的交换机类型里面速度最快的。fanout 类型常用来广播消息

topic

direct 类型的 Exchange 路由规则是完全匹配 BindingKey 和 RoutingKey ,但是这种严格的匹配方式在很多情况下不能满足实际业务的需求。

topic 类型的 Exchange 在匹配规则上进行了扩展,它与 direct 类型的 Exchange 相似,也是将消息路由到 BindingKey 和 RoutingKey 相匹配的队列中,但这里的匹配规则有些不同,它约定:

  • RoutingKey 为一个点号 .分隔的字符串,其中 .分隔开的每一段独立的字符串称为一个单词
  • BindingKey 和 RoutingKey 一样也是点号 . 分隔的字符串;
  • BindingKey 中可以存在两种特殊字符串 *#,用于做模糊匹配,其中 * 用于匹配一个单词, # 用于匹配零个或多个单词。
alt

以上图为例,如果发送消息的时候 RoutingKey 为

  • "com.rabbitmq.client",那么消息会路由到 Queue1 和 Queue2
  • "com.hidden.client",那么消息只会路由到 Queue2 中
  • "com.hidden.demo",那么消息只会路由到 Queue2 中
  • "java.rabbitmq.demo",那么消息只会路由到 Queue1 中
  • "java.util.concurrent",那么消息将会被丢弃或者返回给生产者,因为它没有匹配任何路由键。

headers

headers 类型的 Exchange 不依赖于路由键的匹配规则来路由消息,而是根据发送的消息内容中的 headers 属性进行匹配。在绑定队列和交换器时指定一组键值对,当发送消息到交换器时,RabbitMQ 会获取到该消息的 headers(也是一个键值对的形式),对比其中的键值对是否完全匹配队列和交换器绑定时指定的键值对,如果完全匹配则消息会路由到该队列,否则不会路由到该队列。headers 类型的 Exchange 性能会很差,不推荐使用。

Queue

Queue 其实是 Message Queue 即消息队列,保存消息并将它们转发给消费者。Queue 是消息的容器,也是消息的终点。一个消息可投入一个或多个队列。消息一直在队列里面,等待消费者连接到这个队列将其消费。

RabbitMQ 中消息只能存储在队列中,而 Kafka 将消息存储在 Topic 中,即该 Topic 对应的 Partition 中。RabbitMQ 的生产者生产消息并最终投递到队列中,消费者可以从队列中获取消息并消费。

当多个消费者订阅同一个队列时,队列中的消息会被平均分摊(Round-Robin,即轮询)给多个消费者进行处理,而不是每个消费者都收到所有的消息并处理,这样避免消息被重复消费。

队列属性

Queue 跟 Exchange 共享某些属性,但是队列也有一些另外的属性:

  • Name
  • Durable:消息代理重启后,队列依旧存在
  • Exclusive:只被一个连接使用,而且当连接关闭后队列即被删除
  • Auto-delete:当最后一个消费者退订后即被删除
  • Arguments:一些消息代理用他来完成类似与 TTL 的某些额外功能

队列创建

队列在声明(declare)后才能被使用。

如果一个队列尚不存在,声明一个队列会创建它。如果声明的队列已经存在,并且属性完全相同,那么此次声明不会对原有队列产生任何影响。如果声明中的属性与已存在队列的属性有差异,那么一个错误代码为 406 的通道级异常就会被抛出。

队列持久化

持久化队列(Durable Queues)会被存储在磁盘上,当消息代理(Broker)重启的时候,它依旧存在。没有被持久化的队列称作暂存队列(Transient Queues)。并不是所有的场景和案例都需要将队列持久化。

持久化的队列并不会使得路由到它的消息也具有持久性。倘若消息代理挂掉了,重新启动,那么在重启的过程中持久化队列会被重新声明,无论怎样,只有经过持久化的消息才能被重新恢复

消息机制

消息确认

AMQP 代理在什么时候删除消息才是正确的?AMQP 0-9-1 规范给我们两种建议:

  • 自动确认模式:当消息代理(Broker)将消息发送给应用后立即删除。(使用 AMQP 方法:basic.deliver 或 basic.get-ok)

  • 显示确认模式:待 Consumer 发送一个确认回执(acknowledgement)后再删除消息。(使用 AMQP 方法:basic.ack)

    如果一个消费者在尚未发送确认回执的情况下挂掉了,那 AMQP 代理会将消息重新投递给另一个消费者。如果当时没有可用的消费者了,消息代理会死等下一个注册到此队列的消费者,然后再次尝试投递。

拒绝消息

当拒绝某条消息时,应用可以告诉消息代理销毁该条消息或者重新将该条消息放入队列。

当此队列只有一个消费者时,有可能存在拒绝消息并将消息重新放入队列的行为而引起消息在同一个消费者身上无限循环的情况。

预取消息

在多个消费者共享一个队列时,明确指定在收到下一个确认回执前每个消费者一次可以接受多少条消息是非常有用的。这可以在试图批量发布消息的时候起到简单的负载均衡和提高消息吞吐量的作用。

消息属性

AMQP 模型中的消息(Message)对象是带有属性(Attributes)的:

属性说明
Content type内容类型
Content encoding内容编码
Routing key路由键
Delivery mode (persistent or not)投递模式(持久化 或 非持久化)
Message priority消息优先权
Message publishing timestamp消息发布的时间戳
Expiration period消息有效期
Publisher application id发布应用的 ID

有些属性是被 AMQP 代理所使用的,但是大多数是开放给接收它们的应用解释器用的。有些属性是可选的也被称作消息头(headers)。和 HTTP 协议的 X-Headers 很相似,消息属性需要在消息被发布的时候定义。

消息主体

AMQP 的消息除属性外,也含有一个有效载荷 Payload(消息实际携带的数据),它被 AMQP 代理当作不透明的字节数组来对待。

消息代理不会检查或者修改 Payload,消息可以只包含属性而不携带有效载荷,它通常会使用类似 JSON 这种序列化的格式数据。

消息持久化

消息能够以持久化的方式发布,AMQP 代理会将此消息存储在磁盘上。如果服务器重启,系统会确认收到的持久化消息未丢失。

简单地将消息发送给一个持久化的交换机或者路由给一个持久化的队列,并不会使得此消息具有持久化性质:它完全取决与消息本身的持久模式(persistence mode)。将消息以持久化方式发布时,会对性能造成一定的影响(就像数据库操作一样,健壮性的存在必定造成一些性能损失)。

三、RabbitMQ 命令行操作

alt

启动 & 停止服务器

  • 启动服务器

    rabbitmq-server start &
  • 停止服务器

    rabbitmqctl stop_app

查看管控台

http://localhost:15672/

# 用户名 guest
# 密码 guest

命令行基础操作

1. 应用

  • 关闭应用

    rabbitmqctl stop_app
  • 启动应用

    rabbitmqctl start_app
  • 查看节点状态

    rabbitmqctl status

2. 用户

  • 添加用户

    rabbitmqctl add_user username password
  • 删除用户

    rabbitmqctl delete_user username
  • 列出所有用户

    rabbitmqctl list_users
  • 清除用户权限

    rabbitmqctl clear_permissions -p vhostpath username
  • 列出用户权限

    rabbitmqctl list_user_permissions username
  • 修改密码

    rabbitmqctl change_password username newpassword
  • 设置用户权限

    rabbitmqctl set_permissions -p vhostpath username ".*" ".*" ".*"

3. 虚拟主机

  • 创建虚拟主机

    rabbitmqctl add_vhost vhostpath
  • 删除虚拟主机

    rabbitmqctl delete_vhost vhostpath
  • 列出所有虚拟主机

    rabbitmqctl list_vhosts
  • 列出虚拟主机上所有权限

    rabbitmqctl list_permissions -p vhostpath

4. 队列

  • 查看所有队列信息

    rabbitmqctl list_queues
  • 清除队列里的消息

    rabbitmqctl -p vhostpath purge_queue blue

命令行高级操作

  • 移除所有数据

    rabbitmqctl reset
    # 要在 rabbitmqctl stop_app 之后使用
  • 组成集群命令

    rabbitmqctl join_cluster <clusternode> [--ram]
  • 查看集群状态

    rabbitmq cluster_status
  • 修改集群节点的存储形式

    rabbitmqctl change_cluser_node_type disc | ram
  • 摘除节点(忘记节点)

    rabbitmqctl forget_cluster_node [--offline]
  • 修改节点名称

    rabbitmqctl rename_cluster_node oldnode1 newnode1 [oldnode2] [newnode2]

四、RabbitMQ 高级特性

消息100%可靠性投递的解决方案

生产端可靠性投递

  • 保障消息成功发出
  • 保障 MQ 节点的成功接收
  • 发送端收到 MQ 节点(Broker)确认应答
  • 完善的消息补偿机制

解决方案1:消息落库

消息落库,对消息状态进行打标。

alt

解决方案2:二次确认,回调检查

消息的延迟投递,做二次确认,回调检查。

alt

消费端幂等性操作

  • 唯一 ID + 指纹码 机制,利用数据库主键去重

    优点:实现简单

    缺点:高并罚下有数据库写入的性能瓶颈

    解决方案:根据 ID 进行分库分表进行算法路由

  • 利用 Redis 原子特性实现

Confirm 消息机制

消息的确认是指生产者投递消息后,如果 Broker 收到消息,则会给生产者一个应答,生产者进行接收应答,用来确定这条消息是否正常地发送到 Broker。

alt

实现机制:

  • 第一步:在 channel 上开启确认模式

    channel.confirmSelect()
  • 第二步:在 channel 上添加监听

    channel.addConfirmListener()

    监听成功和失败的返回结果,根据具体的结果对消息进行重新发送或记录日志等后续处理。

Return 消息机制

消息生产者通过制动一个 Exchange 和 routing key,把消息送达到某一个队列中去,然后消费者监听队列,进行消费处理操作。

在某些情况下,如果我们在发送消息的时候,当前的 Exchange 不存在或者指定的 routing key路由不到,此时我们需要监听这种不可达的消息,就要使用 Return Listener。

基础 API 有一个配置项 mandatory

  • 如果为 true,那么监听器会接收到路由不可达的消息,然后进行后续处理
  • 如果为 false, 那么 Broker 端自动删除该消息
alt

消费端限流

RabbitMQ 提供了一种 QoS(服务质量保证) 功能,在非自动确认消息的前提下,如果一定数目的消息(通过基于 Consume 或者 Channel 设置 QoS 值)未被确认前,不进行消费新的消息。

涉及到的方法:

void BasicQoS(unit prefetchSize,ushort prefetchCount,bool global)
  • prefetchSize:0
  • prefetchCount:告知 RabbitMQ 不要同时给一个消费者推送多个 N 个消息,即一旦有 N 个消息还没有 ACK,则该 Consumer 将 block 掉,一直到有消息 ack
  • golbal:true 表示将上面设置应用于 Channel;true 表示将上面设置应用于 Consumer。

注意:

  • prefetchSize 和 global 这两项,RabbitMQ 没有实现,暂且不研究
  • prefetchCount 在 no_ask-false 的情况下生效,即在自动应答的情况下是不生效的

消费端 ACK 与重回队列

  • 消费端的手工 ACK 和 NACK

    消费端进行消费时:

    如果由于业务异常,我们可以进行日志的记录,然后进行补偿;

    如果由于服务器宕机等严重问题,那么需要手工进行 ACK 保障消费端消费成功

  • 消费端的重回队列

    消费端重回队列是为了对没有成功的消息, 消息会被重新投递给 Broker。一般在使用应用中,都会关闭重回队列,即设置为 false。

TTL

TTL(Time To Live)即生存时间。

  • RabbitMQ 支持 消息的过期时间,在消息发送时可以进行指定
  • RabbitMQ 支持 队列的过期时间,从消息如队列开始计算,只要超过了队列的超时时间配置,那么会自动清除消息

死信队列(DLX,Dead-Letter-Exchange )

利用 DLX,当消息在一个队列中变成死信(dead message)之后,其能被重新 publish 到另一个 Exchange,这个 Exchange 就是 DLX。

消息变成死信的几种情况:

  • 消息被拒绝(basic.reject / basic.nack),并且 requeue=false
  • 消息 TTL 过期
  • 队列达到最大长度

注意:

  • DLX 也是一个正常的 Exchange,和一般的 Exchange 没有区别,它能在任何队列上被指定,实际上就是设置某个队列的属性。

  • 当这个队列中有死信时,RabbitMQ 就会自动的将这个消息重新发布到设置的 Exchange 上去,进而被路由到另一个队列。

  • 死信队列设置需要设置 Exchange 和 队列,然后绑定

    channel.exchangeDeclare("dlx.exchange""topic"truefalsenull);
    channel.queueDeclare("dlx.queue"truefalsefalsenull);
    channel.queueBind("dlx.queue""dlx.exchange""#");

    然后我们进行正常声明 Exchange、队列和绑定,此时需要在队列上加上参数 arguments

    Map<String, Object> agruments = new HashMap<String, Object>();
    agruments.put("x-dead-letter-exchange""dlx.exchange");
    //这个agruments属性,要设置到声明队列上
    channel.queueDeclare(queueName, truefalsefalse, agruments);

本文由 mdnice 多平台发布

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

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

相关文章

【ChatGPT+XMind超级详细的保姆级思维导图教程】

&#x1f680; AI &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;CSDN…

Spring Boot 异常报告器解析

基于Spring Boot 3.1.0 系列文章 Spring Boot 源码阅读初始化环境搭建Spring Boot 框架整体启动流程详解Spring Boot 系统初始化器详解Spring Boot 监听器详解Spring Boot banner详解Spring Boot 属性配置解析Spring Boot 属性加载原理解析Spring Boot 异常报告器解析 创建自定…

怎么查投票人画展投票链接怎么做微信链接投票

近些年来&#xff0c;第三方的微信投票制作平台如雨后春笋般络绎不绝。随着手机的互联网的发展及微信开放平台各项基于手机能力的开放&#xff0c;更多人选择微信投票小程序平台&#xff0c;因为它有非常大的优势。 1.它比起微信公众号自带的投票系统、传统的H5投票系统有可以图…

C语言入门万字笔记

C语言一经出现就以其功能丰富、表达能力强、灵活方便、应用面广等特点迅速在全世界普及和推广。C语言不但执行效率高而且可移植性好&#xff0c;可以用来开发应用软件、驱动、操作系统等。C语言也是其它众多高级语言的鼻祖语言&#xff0c;所以说学习C语言是进入编程世界的必修…

机器学习、计算机视觉和深度学习

机器学习、计算机视觉和深度学习 1 什么是机器学习&#xff1f;2 机器学习的类型3 什么是计算机视觉&#xff1f;4 计算机视觉的机器学习应用5 总结参考 这篇博客将简要介绍&#xff1a;机器学习和用于计算机视觉的机器学习。 想象一下&#xff1a;你可以使用人脸检测算法在图…

【后端】SSM框架下REST风格代码注释详解

前言 最近学习了一下SSM&#xff0c;不得不说&#xff0c;spring不用注解真的是天打雷劈&#xff0c;就那个bean真的就是折磨人。 下面是我总结的spring注解。 Value 此注解可以用来获取导入的jdbc.properties文件的值。 Value("${jdbc.driver}")private String…

【C++】C++11新特性重点:可变参数+lambda

C11新特性第二篇重点 文章目录 上一篇的补充一、可变参数模板二、lambda函数总结 前言 上一篇我们重点讲解了右值引用移动语义&#xff0c;关于移动构造和移动赋值还有一些需要补充的知识&#xff1a; 如果你没有自己实现移动构造函数&#xff0c;且没有实现析构函数 、拷贝构…

dubbo 3.2.0 的filterChain 简要分析

dubbo 3.2.0 的filterChain 的核心类是DefaultFilterChainBuilder 。 Builder public class DefaultFilterChainBuilder implements FilterChainBuilder {的buildInvokerChain函数 对于consumer refer Overridepublic <T> Invoker<T> buildInvokerChain(final I…

Java自动化测试(web自动化测试框架 )

测试数据 测试地址 http://120.78.128.25:8765/ 投资人 13323234545 lemon123456 借款人 13323234444 lemonbest 后台地址 http://120.78.128.25:8765/Admin/Index/login.html lemon7 lemonbest Page Object PO简介 https://www.selenium.dev/documentation/en/g…

如何把在线K歌“玩起来”——专访撕歌音视频架构师程乐

编者按&#xff1a;在线K歌的业务已经发展了十年&#xff0c;程乐在音视频领域也闯荡了十年&#xff0c;甚至更久。为什么选择在线K歌领域&#xff1f;如何走过“漫长的季节”&#xff0c;迎来新的风景&#xff1f;如何在“在线K歌”这块难啃的骨头里分点肉&#xff1f;在这一连…

【存储】cache memory、primary memory and secondary memory

一、提要二、计算机的存储结构三、高速缓存&#xff1a;cache memory四、主存&#xff1a;Primary memory4.1 RAM4.11 SRAM 和 DRAM的概念4.12 SRAM 和 DRAM的应用场景 4.2 ROM4.21 PROM4.22 EPROM▶ EEPROM▶ UVEPROM 五、辅助存储器&#xff1a;secondary memory六、单片机的…

redis的4种模式,单机,哨兵、主从复制、集群

为了redis叫做redis服务器&#xff1f; 因为在运行时&#xff0c;在进行工作时是一个被注册一个进程(服务)&#xff0c;我们把他叫做一个redis服务器。(就是个应用程序而已。) 1.单机模式 我们安装redi,启动服务之后&#xff0c;默认就这个&#xff0c;只有一个redis服务器(…

编译原理笔记(哈工大编译原理)(持续更新)

文章目录 前言概论语言与文法基本概念字母表串字母表与串的联系 文法语言推导和规约句型与句子语言与字母表 文法的分类CFG的分析树 前言 说实话&#xff0c;我不是很想上这门课&#xff0c;确实没什么大用&#xff0c;虽然我觉得这门课学一学也挺好&#xff0c;但是我觉得弄8…

架构师必备项目管理方法-关键路径法

在《架构思维的六要素》中提到成本、规划、需求、维护、人员和质量是要考量的留个维度。咱们在日常工作中多少都会接触一些相关的管理方法&#xff0c;但是似乎是不知道也不影响干活&#xff0c;所以很多人也没有去深究。但实际上很可能知道了做事就更能抓住重点。 关键路径法是…

预测神经胶质瘤基因型的多模态学习

文章目录 Multi-modal learning for predicting the genotype of glioma摘要本文方法多模态数据生成Brain networks construction via self-supervised NNsMulti-modal learning for image, geometrics and brain networksBi-level multi-modal contrastive loss Population gr…

html实现好看的个人介绍,个人主页模板3(附源码)

文章目录 1.设计来源1.1 主界面1.2 关于我界面1.3 教育成就界面1.4 项目演示界面1.5 联系我界面 2.效果和源码2.1 动态效果2.2 源代码2.2 源代码目录 源码下载 作者&#xff1a;xcLeigh 文章地址&#xff1a;https://blog.csdn.net/weixin_43151418/article/details/131263195 …

新手Maven入门(一)

Mavenue介绍和基本概念 一、什么是Maven1.1 Maven的组成1.2 安装和配置Maven1.2.1 下载1.2.2 安装 二、Maven 的基本概念2.1 标准的目录结构2.2 POM 大纲2.2.1 pom大纲展示 2.3 构件2.3.1 什么是maven的构建 2.4 POM 文件的用例2.5 GAV 坐标 三、依赖 一、什么是Maven Maven 是…

2023年前端面试汇总-计算机网络

1. HTTP协议 1.1. GET和POST的请求的区别 Post 和 Get 是 HTTP 请求的两种方法&#xff0c;其区别如下&#xff1a; 1. 应用场景 GET 请求是一个幂等的请求&#xff0c;一般 Get 请求用于对服务器资源不会产生影响的场景&#xff0c;比如说请求一个网页的资源。而 Post 不是…

如何在Ubuntu上安装MongoDB?

一、Ubuntu安装MongoDB MongoDB安装很简单&#xff0c;无需下载源文件&#xff0c;可以直接用apt-get命令进行安装。 打开终端&#xff0c;输入以下命令 sudo apt-get install mongodb这时装好以后应该会自动运行mongod程序&#xff0c;通过命令查看进程是否已经启动 pgrep …

Spring 实现AOP常见的两种方式(注解或者自定义注解)

第一种 导入AOP相关坐标(依赖冲突解决办法&#xff0c;将依赖中版本号删除&#xff0c;springboot会自动匹配合适的版本 ) <dependencies><!--spring核心依赖&#xff0c;会将spring-aop传递进来--><dependency><groupId>org.springframework</gr…