RabbitMQ入门(详细)

news2024/12/28 20:20:13

RabbitMQ入门(详细)

  • 初始消息队列
    • 消息队列初识
    • 为什么要使用消息队列?
    • 消息队列的特性
  • RabbitMQ介绍
    • 特点
    • 核心概念
  • Linux(CentOs7) 下安装:
    • 安装前配置:
    • Erlang下载安装
    • RabbitMQ下载安装
    • linux下安装rabbitmq可能会遇到的问题
  • Linux 常用命令
  • RabbitMQ Web 界面管理
    • 新增用户
    • 管理界面
  • Java 基础应用
    • 创建连接工厂
    • 设置 RabbitMQ 地址
    • 建立连接
    • 获得信道
    • 声明队列
    • 发布 或 消费(接收)消息
      • 发布消息:
      • 消费(接收)消息:
    • 关闭连接
  • 交换机工作模式
    • fanout 广播模式
    • direct 直接模式
    • topic 主题模式:
    • 应用:
      • 定义交换机:
      • 接收时需要绑定队列:
        • 广播模式完整案例:
  • 其他知识点
    • 消息分配
    • 按压力进行平均分配(公平派遣):
    • 临时队列

初始消息队列

消息队列初识

  • 消息队列∶接收并转发消息。类似于“快递公司”
  • producer :消息的发送者、生产者
  • consumer :消息的消费者,从队列获取消息,并且使用
  • queue∶先进先出的消息队列,一个queue可以对应多个 consumer

为什么要使用消息队列?

  • 代码解耦,提高系统稳定性。
  • 应对流量高峰,降低流量冲击。
  • 异步执行,提高系统响应速度。

消息队列的特性

  • 性能好。
  • 基础组件。(类似于mysql,是通用的系统)
  • 支持消息确认。(当断电了重启之后,可以对消息进行重新处理)保持了一致性。
  • 削峰(请求峰值)

RabbitMQ介绍

  • 官网:https://rabbitmq.com/

特点

  • 路由能力灵活强大
  • 开源免费
  • 支持编程语言多
  • 应用广泛,社区活跃
  • 有开箱即用的监控和管理后台

核心概念

在这里插入图片描述

Linux(CentOs7) 下安装:

官方安装指南:https://www.rabbitmq.com/install-rpm.html
我们将要安装的RabbitMQ的版本是3.8.2
https://packagecloud.io/rabbitmq/rabbitmq-server/packages/el/7/rabbitmq-server-3.8.2-1.el7.noarch.rpm
不需要单独安装Erlang环境。

安装前配置:

  • 前提:在一个新建的阿里云的Cent OS 7.6上安装,不要对yum换源,否则可能会安装失败。
  • echo “export LC_ALL=en_US.UTF-8” >> /etc/profile
  • source /etc/profile
    • 将编码格式设置为 UTF-8

Erlang下载安装

  • wget --content-disposition https://packagecloud.io/rabbitmq/erlang/packages/el/7/erlang-22.3.4.12-1.el7.x86_64.rpm/download.rpm

    • 先下载安装Erlang环境
  • 安装已下载的rpm包(可根据刚才自己选择的版本修改下面的版本号)

    • yum localinstall erlang-22.3.4.12-1.el7.x86_64.rpm
  • sudo yum install rabbitmq-server-3.8.2-1.el7.noarch
    在这里插入图片描述

RabbitMQ下载安装

  • wget --content-disposition https://packagecloud.io/rabbitmq/rabbitmq-server/packages/el/7/rabbitmq-server-3.8.13-1.el7.noarch.rpm/download.rpm
  • rpm --import https://www.rabbitmq.com/rabbitmq-release-signing-key.asc
    • 需要运行命令来将 Key 导入
  • 最后,使用 yum 进行本地安装(可根据自己选择的版本修改下面的版本号)
    • yum localinstall rabbitmq-server-3.8.13-1.el7.noarch.rpm
      在这里插入图片描述

    • 若报错:rabbitmq Unregistered Authentication Agent for unix- process:6485:746263

    • 执行以下命令:rpm -ivh --nodeps rabbitmq-server-3.8.13-1.el7.noarch.rpm

    • 再重试

  • journalctl -xe:可以查看 rabbitmq-server 日志
  • systemctl start rabbitmq-server:启动 rabbitmq 服务器
  • rabbitmqctl status:查看 状态信息。
  • systemctl enable rabbitmq-server:设置开机自启动

linux下安装rabbitmq可能会遇到的问题

相关博客:https://blog.csdn.net/m0_67402914/article/details/123972575

Linux 常用命令

  • 开启 web 管理界面:rabbitmq-plugins enable rabbitmq_management
  • 启动RabbitMQ:systemctl start rabbitmq-server
  • 设置开机启动:systemctl enable rabbitmq-server
  • 停止RabbitMQ:rabbitmqctl stop
  • 查看状态信息:rabbitmqctl status
  • 检查 RabbitMQ 服务器的状态:systemctl status rabbitmq-server

RabbitMQ Web 界面管理

  • 默认情况下,是没有安装web端的客户端插件,需要安装才可以生效。执行命令:
    • rabbitmq-plugins enable rabbitmq_management
  • 安装完毕以后,重启服务即可,执行命令:
    • systemctl restart rabbitmq-server
  • 在服务器上开放 15672 端口。
  • rabbitmq 有一个默认账号和密码是: guest
    • 默认情况只能在 localhost 本机下访问,因此想要远程访问就需要新增一个远程登录的用户。

新增用户

  • 将账号密码都设置为 admin:

    • rabbitmqctl add_user 账号 密码
  • 设置用户分配操作权限:

    • rabbitmqctl set_user_tags admin administrator:设置为管理员
  • 进入虚拟主机,添加允许访问的用户。
    在这里插入图片描述
    在这里插入图片描述

  • 访问 http://IP地址:15672 ,输入新增的用户
    在这里插入图片描述

    • 如果访问不了,看是否开放了防火墙,或阿里云服务器是否开启了安全组。

管理界面

  • amqp:5673:用于客户端连接

  • clustering:25672:用于集群

  • http:15672:用于http协议 登录管理后台
    在这里插入图片描述

  • exchanges:交换机,默认会有 7 个
    在这里插入图片描述

    • 每个交换机点进去,可以绑定队列、消息发送 等操作
  • admin:用户管理,可以用户进行 CURD 操作等。

  • 可以在右侧进入虚拟主机的管理页面
    在这里插入图片描述

    • 进入虚拟主机,可以进行 CURD 操作,添加允许访问的用户等

在这里插入图片描述

Java 基础应用

Maven:
<dependency>
    <groupId>com.rabbitmq</groupId>
    <artifactId>amqp-client</artifactId>
    <version>5.17.0</version>
</dependency>
<!-- rabbitmq要求的内部用于记录日志的 -->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-nop</artifactId>
    <version>2.0.7</version>
</dependency>

创建连接工厂

  • ConnectionFactory factory = new ConnectionFactory();

设置 RabbitMQ 地址

  • factory.setHost(String ip):设置发送对象 RabbitMQ服务器的 ip
  • factory.setUsername(String username):设置登录的用户
  • factory.setPassword(String password):密码
  • 需要在云服务器设置安全组,开启 5672 端口,授权对象为 0.0.0.0/0
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

建立连接

  • Connection connection = factory.newConnection();
  • 会抛出 IOException, TimeoutException

获得信道

  • Channel channel = connection.createChannel();
  • 会抛出 IOException

声明队列

  • channel.queueDeclare(String queue, boolean durable, boolean exclusive, boolean autoDelete,
    Map<String, Object> arguments) throws IOException
    • queue:队列名
    • durable:是否声明持久队列(该队列将在服务器重启后继续存在)。
    • exclusive:是否声明一个独占队列(仅限于此连接)。
    • autoDelete:是否声明一个自动删除队列(服务器将在不再使用时删除它)。
    • Map<String, Object> arguments:队列的其他属性(构造参数),没有则为 null。
channel.queueDeclare(QUEUE_NAME, false, false, false, null);

发布 或 消费(接收)消息

  • 消息发送之后会存储在队列里,当有其他消费者进行接收时,就会出队。
    在这里插入图片描述

发布消息:

  • channel.basicPublish(String exchange, String routingKey, BasicProperties props, byte[] body):发布消息
    • 发布到不存在的交换将导致通道级协议异常,从而关闭通道。如果资源驱动的警报生效,Channel#basicPublish 的调用将最终阻塞。
    • exchange:要将消息发布到的交换机。
      • 可置为空串 “”,代表默认的交换机,此时会使用 routingKey 进行 查找
    • routingKey:路由键,可以是队列名
    • props:消息的其他属性配置-路由头等,没有则置为 null
    • body:消息主体,需要声明编码方式;例如: msg.getBytes(StandardCharsets.UTF_8)
String msg = "Hello World";
channel.basicPublish("", QUEUE_NAME, null, msg.getBytes(StandardCharsets.UTF_8));

消费(接收)消息:

  • channel.basicConsume(String queue, boolean autoAck, Consumer callback):启动一个非本地的、非独占的消费者,一个服务器生成的消费者标签。
    • queue:队列名
    • autoAck:设置服务器是否 自动确认消息处理完毕。
      • 若为false,则需要在 callback 函数里,当消息处理完毕时使用 basicAck() 函数来确认。
      • channel.basicAck(long deliveryTag, boolean multiple):确认一个或多个接收到的消息。
        • deliveryTag:envelope.getDeliveryTag()。接收到的AMQP.Basic.GetOk或AMQP.Basic.Deliver的标签。
        • multiple:true确认所有到并包括所提供的交付标记的消息;false表示只确认所提供的交付标签。
    • callback:使用者处理对象的接口
      • 一般就是一个 DefaultConsumer 的匿名内部类,重写 handleDelivery() 方法
      • handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties,
        byte[] body):当接收到此使用者的 basic.deliver 时调用。
        • consumerTag:与消费者相关联的消费者标签。
        • envelope:打包消息的数据。
        • properties:消息的内容头数据
        • body:消息体(不透明的、特定于客户端的字节数组),转换为字符串时需要指定编码
channel.basicConsume(QUEUE_NAME, true, new DefaultConsumer(channel) {
    @Override
    public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties,
                               byte[] body) throws IOException {
        String msg = new String(body, "UTF-8");
        System.out.println("收到消息:" + msg);
    }
});

关闭连接

  • 接收消息时可以不用关闭,它就能一直处于待接收状态。
  • 秉承 先开后关 原则。
channel.close();
connection.close();

交换机工作模式

不会接收到 消费端启动的消息。

  • fanout:广播模式,将消息广播到所有与之绑定的队列,不需要设置路由键。
  • direct:直接模式,根据 RoutingKey 匹配消息路由到指定的队列。
  • topic:主题模式,生产者指定 RoutingKey 消息,根据消费端指定的队列通过模糊匹配的方式进行相应转发。
  • headers:根据发送消息内容中的 headers 属性来匹配(基本不用)。

fanout 广播模式

  • 将消息广播到所有与之绑定的队列,不需要设置路由键。
    在这里插入图片描述

direct 直接模式

  • 根据 RoutingKey 匹配消息路由到指定的队列。
    • 允许多个队列绑定相同的 RoutingKey。
      在这里插入图片描述

topic 主题模式:

  • direct 的升级。生产者指定 RoutingKey 消息,根据消费端指定的队列- 通过模糊匹配的方式进行相应转发。
  • * 可以代替一个单词。
  • # 可以替代零个或多个单词。
  • 注意:是单词,不是字符。
    在这里插入图片描述

应用:

定义交换机:

  • 发送和接收时都需要定义。
  • channel.exchangeDeclare(String exchange, BuiltinExchangeType type):主动声明一个不带额外参数的非自动删除、非持久的交换机。
    • exchange:交换机名字
    • type:交换机类型。
      • 其值是 BuiltinExchangeType 枚举类:DIRECT, FANOUT, TOPIC, HEADERS
channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.FANOUT);
- 注意:当已存在相同交换机名且类型不一致时,会报出 IOException。描述:received 'direct' but current is 'fanout'

接收时需要绑定队列:

  • channel.queueBind(String queue, String exchange, String routingKey):将队列绑定到交换机,不带额外参数。
    • routingKey:路由键。
    • 一个交换机可以绑定多个queue,甚至queueName也可以一至(同一个queue绑定了多个RoutingKey)
// 获取临时队列名
String queueName = channel.queueDeclare().getQueue();
channel.queueBind(queueName, EXCHANGE_NAME, "");

广播模式完整案例:

public class EmitLog {
    private static String EXCHANGE_NAME = "direct-logs";
    public static void main(String[] args) throws IOException, TimeoutException {
        // 创建工厂,建立连接,获取信道
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("192.168.65.128");
        factory.setUsername("admin");
        factory.setPassword("admin");
        Connection connection = factory.newConnection();
        Channel channel = connection.createChannel();
        channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.DIRECT);
        String msg1 = "info: Hello World";
        String msg2 = "warning: Hello World";
        String msg3 = "error: Hello World";
        channel.basicPublish(EXCHANGE_NAME, "info", null, msg1.getBytes(StandardCharsets.UTF_8));
        channel.basicPublish(EXCHANGE_NAME, "warning", null, msg2.getBytes(StandardCharsets.UTF_8));
        channel.basicPublish(EXCHANGE_NAME, "error", null, msg3.getBytes(StandardCharsets.UTF_8));
        System.out.println("发送了消息");
        channel.close();
        connection.close();
    }
}
public class ReceiveLogs {
    private static String EXCHANGE_NAME = "direct-logs";
    public static void main(String[] args) throws IOException, TimeoutException {
        // 创建工厂,建立连接,获取信道
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("192.168.65.128");
        factory.setUsername("admin");
        factory.setPassword("admin");
        Connection connection = factory.newConnection();
        Channel channel = connection.createChannel();
        channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.DIRECT);
        // 获取临时队列名
        String queueName = channel.queueDeclare().getQueue();
        channel.queueBind(queueName, EXCHANGE_NAME, "warning");
        channel.queueBind(queueName, EXCHANGE_NAME, "error");
        channel.basicConsume(queueName, true, new DefaultConsumer(channel) {
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties,
                                       byte[] body) throws IOException {
                System.out.println("收到消息:" + new String(body, "UTF-8"));
            }
        });
    }
}

其他知识点

消息分配

  • 默认 Rabbitmq 是按照消息的 数量来进行一次性平均分配 的。
  • 比如,有10个消息,2个消费者,则奇数位的消息都分配给第一个消费者,偶数位的消息分配给第二个消费者,而不考虑每个消息所需耗费的执行时间,(尽管可能某一个消费者的消息都是很费时的消息)

按压力进行平均分配(公平派遣):

  • 干完了手头上的工作,再分配得到第二个工作
    在这里插入图片描述

  • channel.basicQos(int prefetchCount):设置此通道最希望处理的消息数量。

    • 注意预取计数必须在 0到65535 之间(AMQP 0-9-1中的unsigned short)。
    • 在数量 < prefetchCount 之前,不会再接收下一个任务。
  • 关闭自动确认:

    • 置 channel.basicConsume(String queue, boolean autoAck, Consumer callback) 方法的 autoAck 参数为 false。
  • 在 basicConsume() 的 callback 函数里,当消息处理完毕时使用 basicAck() 函数来确认。

  • channel.basicAck(long deliveryTag, boolean multiple):确认一个或多个接收到的消息。

    • deliveryTag:envelope.getDeliveryTag()。接收到的AMQP.Basic.GetOk或AMQP.Basic.Deliver的标签。
    • multiple:true确认所有到并包括所提供的交付标记的消息;false表示只确认所提供的交付标签。
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
channel.basicQos(1);
// 接收消息并消费
channel.basicConsume(QUEUE_NAME, false, new DefaultConsumer(channel) {
    @Override
    public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties,
                               byte[] body) throws IOException {
        String msg = new String(body, "UTF-8");
        System.out.println("收到消息:" + msg);
        channel.basicAck(envelope.getDeliveryTag(), false);
    }
});

临时队列

  • 当接收者不存在时,临时队列就会自动删除,以节省空间。
  • channel.queueDeclare().getQueue();
String queueName = channel.queueDeclare().getQueue();

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

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

相关文章

泰安柒柒:国外问卷调查都有哪些题?

提到问卷调查我们并不陌生&#xff0c;它经常被用作调查市场、商品意见等多种调查中。不过&#xff0c;提到国外问卷调查&#xff0c;大家就比较陌生了。简单来说就是国外的一些企业或机构为了改进自己的商品或服务&#xff0c;会列出一些问题来让大众回答&#xff0c;并用付费…

配置 Ubuntu 的网络

一、三种联网的模式 1. 桥接 VMnet0------> 主机和 Ubuntu 都有一个 ip 地址 2. NAT 模式 VMnet8-------->Ubuntu 和主机是同一个 ip 地址 3. 主机模式 VMnet1-------> 只能和主机进行通信 二、网络配置 1. 虚拟机----->设置 2. 确保网络适配器是桥接模式或…

网络基础学习:osi网络七层模型

osi网络七层模型 什么是OSI&#xff0c;什么是ISO?为什么ISO要提出OSI网络七层模型&#xff1f;OSI七层的划分以及具体内容第七层 应用层第六层 表示层第五层 会话层第四层 传输层第三层 网络层第二层 数据链路层第一层 物理层 每一层与设备的对应关系 什么是OSI&#xff0c;什…

央国企专场培训:太极信创研习院第33期ITAIP信创精华班培训在常州成功举办

4月25-27日&#xff0c;由太极计算机股份有限公司&#xff08;太极信创研习院&#xff09;联合中国中车集团有限公司&#xff08;科技质量与信息化部&#xff09;、中车信息技术有限公司&#xff08;中车学习培训发展中心&#xff09;共同举办的“信息技术应用创新专业人员&…

Java并发编程实践学习笔记(三)——共享对象之可见性

目录 1 过期数据 2 非原子的64位操作 3 锁和可见性 4 Volatile变量&#xff08;Volatile Variables&#xff09; 在单线程环境中&#xff0c;如果向某个变量写入值&#xff0c;在没有其他写入操作的情况下读取这个变量&#xff0c;那么总能得到相同的值。然而&…

java状态机实现订单状态转移

一、状态机 状态机是状态模式的一种应用&#xff0c;相当于上下文角色的一个升级版。在工作流或游戏等各种系统中有大量使用&#xff0c;如各种工作流引擎&#xff0c;它几乎是状态机的子集和实现&#xff0c;封装状态的变化规则。状态机可以帮助开发者简化状态控制的开发过程…

APP界面设计都有哪些好用的软件推荐

基于APP界面的不同功能&#xff0c;所选择的APP界面设计软件也会有所不同。然而&#xff0c;并不是说所有的APP界面设计软件都非常精通&#xff0c;熟练地学习几个常用的APP界面设计软件。以下10个APP界面设计软件将为您的团队提供绘制APP界面所需的必要功能。 1.即时设计 即…

OpenCV-Python实战(7) —— OpenCV 实现抖音视频倒放效果

1. 需求分析 参考&#xff1a;十行Python代码制作一个视频倒放神器&#xff0c;由于最近在学习 OpenCV &#xff0c;因此试着使用 OpenCV 进行实现&#xff0c;学以致用&#xff08;胡乱折腾&#xff09;。 需要视频倒放&#xff0c;因此需要读取视频cv.VideoCapture&#xff1…

一键docker搭建mysql主从环境

一键docker搭建mysql主从环境 初衷准备阶段操作阶段注意事项 初衷 一开始为了玩一下shared-jdbc&#xff0c;要搭Mysql主从环境&#xff0c;这玩意虽然搭好&#xff0c;之后使用要是网络问题&#xff0c;或者sql执行出错&#xff0c;还得重新调Binlog位置&#xff0c;麻烦得很…

接口自动化测试之HTTP协议详解(敢称全网最全)

目录 协议 OSI模型 HTTP URL 报文 响应报文 HTTP扩展 协议 简单理解&#xff0c;计算机与计算机之间的通讯语言就叫做协议&#xff0c;不同的计算机之间只有使用相同的协议才能通信。所以网络协议就是为计算机网络中进行数据交换而建立的规则&#xff0c;标准或约定的集…

Node.js 使用RSA加密/解密

在本文中&#xff0c;我们将探讨如何在 Node.js 中使用 RSA 加密和解密。RSA 是一种非对称加密算法&#xff0c;它可以确保数据的安全传输。使用 RSA&#xff0c;我们可以在不直接传输密钥的情况下安全地加密和解密数据。 一、安装依赖 我们将使用 node-rsa 库来执行加密和解密…

2023 年Java经典面试题,基础篇01(持续更新)

本篇文章主要讲的是 2023 年Java最新面试题&#xff0c;持续更重中 基础概念与常识 原文地址&#xff1a;https://github.com/Snailclimb/JavaGuide Java 语言有哪些特点? 简单易学&#xff1b;面向对象&#xff08;封装&#xff0c;继承&#xff0c;多态&#xff09;&#…

《LeetCode》—— LeetCode刷题日记

本期&#xff0c;我给大家讲述的是关于 n数之和这类题目的讲解&#xff0c;我会给大家讲解两数之和&#xff0c;三数之和和四数之和这三道题目。 目录 &#xff08;一&#xff09;两数之和 &#xff08;二&#xff09;三数之和 &#xff08;三&#xff09;四数之和 &#xf…

NodeJs 最近各版本特性汇总

&#xff08;预测未来最好的方法就是把它创造出来——尼葛洛庞帝&#xff09; NodeJs 官方链接 github链接 V8链接 Node.js发布于2009年5月&#xff0c;由Ryan Dahl开发&#xff0c;是一个基于Chrome V8引擎的JavaScript运行环境&#xff0c;使用了一个事件驱动、非阻塞式I/O模…

对象应用:C++字符串和vector,对象的new与delete重构

对象应用 C字符串和vector字符串创建方式字符串拼接字符串追加 字符串截断autovector创建方式vector操作 new与delete重构new与delete的工作步骤new与delete重构应用只能生成栈对象只能生成堆对象 C字符串和vector C的字符串是一个对象&#xff0c;存在于std标准库中&#xff0…

Python基础入门(4)—— 什么是偷懒编程法?是类、对象和继承

文章目录 00 | &#x1f603;为什么学习类&#xff1f;&#x1f603;01 | &#x1f604;创建类&#x1f604;02 | &#x1f606;创建对象&#x1f606;03 | &#x1f609;访问对象属性和方法&#x1f609;04 | &#x1f60a;构造函数&#x1f60a;05 | &#x1f60b;继承&#…

Shell编程之数组

目录 一、数组的基本概念 二、定义数组的方法 方法一&#xff1a; ​编辑 方法二&#xff1a; 方法三&#xff1a; ​编辑 方法四&#xff1a; 三、 数组的输出&#xff0c;删除和长度统计 1&#xff09;数组元素的输出 2&#xff09;数组全部元素输出 3&#xff0…

一种用于提高无线传感器网络寿命的改进LEACH协议(Matlab代码实现)

目录 &#x1f4a5;1 概述 &#x1f4da;2 运行结果 &#x1f389;3 参考文献 &#x1f468;‍&#x1f4bb;4 Matlab代码 &#x1f4a5;1 概述 无线传感器网络具有网络灵活性强、网络规模可变等优点&#xff0c;广泛应用于军事、工业等领域。无线传感器网络的基本网络路由…

Mybatis一级缓存详解

目录 一级缓存 一级缓存的组织 一级缓存的生命周期 一级缓存的工作流程 Cache接口的设计以及CacheKey的定义 一级缓存的性能分析 一级缓存与Spring 事务一级缓存存在的弊端 官方文档分析 Spring通过Mybatis调用数据库的过程 一级缓存 对于会话&#xff08;Session&am…

Nacos-01-Nacos基本介绍

背景 ​ 服务发现是⼀个古老的话题&#xff0c;当应用开始脱离单机运行和访问时&#xff0c;服务发现就诞生了。目前的网络架构是每个主机都有⼀个独立的 IP 地址&#xff0c;那么服务发现基本上都是通过某种方式获取到服务所部署的 IP 地址。DNS 协议是最早将⼀个网络名称翻译…