RabbitMQ 教程 | 第2章 RabbitMQ 入门

👨🏻‍💻 热爱摄影的程序员
👨🏻‍🎨 喜欢编码的设计师
🧕🏻 擅长设计的剪辑师
🧑🏻‍🏫 一位高冷无情的编码爱好者
大家好,我是 DevOps 工程师
欢迎分享 / 收藏 / 赞 / 在看!

这篇 RabbitMQ 教程为学习者提供了全面的内容,从 RabbitMQ 的简介开始,涵盖了消息中间件的概念、RabbitMQ 的安装与使用,以及交换机、队列、路由键等相关概念的介绍。进一步深入,教程探讨了 AMQP 协议、客户端开发向导,以及消息的发送和消费方式。同时,学习者还可以了解消息传输保障、高级特性如死信队列、延迟队列、优先级队列、RPC 实现等。此外,教程还涵盖了 RabbitMQ 的管理、配置、运维、监控和集群管理等重要主题,帮助学习者充分掌握 RabbitMQ 的应用。整篇教程丰富内容详实,适合初学者和有经验的开发者参考学习。

全篇共 11 章,9 万余字。本文:第2章 RabbitMQ 入门。

第2章 RabbitMQ 入门

2.1 相关概念介绍

在本节中,我们将介绍与 RabbitMQ 相关的一些重要概念,这些概念对于理解 RabbitMQ 的工作原理非常重要。

2.1.1 生产者和消费者

在 RabbitMQ 中,生产者和消费者是两个关键的角色,它们协同工作来实现消息的发布和消费。

生产者(Producer): 生产者是消息的发送者,负责向 RabbitMQ 发送消息。生产者将消息发布到交换机(Exchange),交换机再根据消息的路由键(Routing Key)将消息路由到一个或多个队列(Queue)。生产者不需要知道消息最终将被哪个消费者接收,它只关心将消息发送到正确的交换机,并指定合适的路由键。

在发送消息之前,生产者需要和 RabbitMQ 建立连接,并创建一个通道(Channel)来进行消息的发布。通道是在连接上打开的一个轻量级的会话,通过通道可以避免频繁地打开和关闭连接,从而提高消息的传输效率。

通常,生产者会向一个特定的交换机发送消息,交换机根据一定的规则将消息路由到队列中,然后消费者从队列中接收消息进行处理。生产者可以根据业务需求决定消息的发送频率和内容。

示例代码(使用 Python 的 pika 库):

import pika

# 建立连接
connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()

# 声明一个名为"hello"的队列
channel.queue_declare(queue='hello')

# 发送消息
channel.basic_publish(exchange='',
                      routing_key='hello',
                      body='Hello, RabbitMQ!')

print(" [x] Sent 'Hello, RabbitMQ!'")

# 关闭连接
connection.close()

消费者(Consumer): 消费者是消息的接收者,负责从队列中获取消息并进行处理。消费者需要与 RabbitMQ 建立连接,并订阅(Consume)一个或多个队列来接收消息。

一旦消息被发送到队列中,消费者就可以从队列中获取消息,并对消息进行处理。处理方式可以是执行一段代码、存储到数据库、发送到其他系统等,这取决于消费者的业务逻辑。

消费者在接收消息后,通常会给 RabbitMQ 发送一个确认(Ack)信号,告知 RabbitMQ 消息已经被成功处理,RabbitMQ 可以删除该消息。这样可以确保消息不会丢失,并保证消息传递的可靠性。

示例代码(使用 Python 的 pika 库):

import pika

def callback(ch, method, properties, body):
    print(" [x] Received %r" % body)
    # 消息处理逻辑,例如保存到数据库或执行其他操作
    ch.basic_ack(delivery_tag=method.delivery_tag)

# 建立连接
connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()

# 声明一个名为"hello"的队列
channel.queue_declare(queue='hello')

# 告诉RabbitMQ当收到消息后,调用callback函数进行处理
channel.basic_consume(queue='hello', on_message_callback=callback)

print(' [*] Waiting for messages. To exit press CTRL+C')
channel.start_consuming()

生产者和消费者的协作使得 RabbitMQ 能够在分布式系统中高效地传递消息,实现了解耦和异步处理,提高了系统的可扩展性和可靠性。

2.1.2 队列

在 RabbitMQ 中,队列(Queue)是消息的存储和传递单元,是 RabbitMQ 的核心组件之一。队列是一个有名字的管道,用于保存消息,生产者通过交换机(Exchange)将消息发送到队列,消费者则从队列中接收和处理消息。

以下是 RabbitMQ 队列的一些关键特性和介绍:

  1. 有名字:每个队列在 RabbitMQ 中都有一个唯一的名称,生产者和消费者通过名称来访问和使用队列。
  2. 持久性:队列可以被声明为持久化的,这意味着在 RabbitMQ 服务器重启后,队列依然存在,其中的消息也不会丢失。持久化可以确保消息的可靠传递。
  3. 非持久性:如果队列被声明为非持久化的,在 RabbitMQ 服务器重启后,该队列将会被删除,其中的消息也会丢失。
  4. 先进先出:队列中的消息按照先进先出(FIFO)的顺序进行处理,即最先进入队列的消息会最先被消费者接收。
  5. 自动删除:队列可以被声明为自动删除的,在最后一个消费者断开连接后,该队列将会被自动删除,用于临时队列的场景。
  6. 绑定到交换机:队列通过绑定到交换机来获取消息。交换机根据一定的规则(根据路由键)将消息路由到相应的队列。
  7. 消息确认:消费者接收到消息后,可以向 RabbitMQ 发送确认信号(ACK)来告知 RabbitMQ 消息已经被成功处理。如果消费者不发送 ACK,RabbitMQ 会认为消息没有被成功处理,并将其重新发送给其他消费者或者继续存储在队列中。
  8. 消息持久性:消息也可以被声明为持久化的,这样即使 RabbitMQ 服务器重启,消息也不会丢失。当消息被发送到持久化的队列中,同时消息本身也被声明为持久化时,才能保证消息的持久性。

在 RabbitMQ 中,队列是一种非常重要的组件,它实现了消息传递的核心功能。通过合理的使用队列的特性,可以确保消息的可靠传递和处理,构建高性能、可靠的消息传递系统。

2.1.3 交换机、路由键、绑定

在 RabbitMQ 中,交换机(Exchange)、路由键(Routing Key)和绑定(Binding)是实现消息路由的关键概念。它们一起协同工作,将生产者发送的消息从交换机路由到合适的队列中,供消费者进行处理。

  1. 交换机(Exchange): 交换机是消息的接收和路由中心,它接收生产者发送的消息,并根据消息的路由键将消息路由到一个或多个队列。RabbitMQ 支持多种类型的交换机,包括直接(Direct)交换机、扇形(Fanout)交换机、主题(Topic)交换机和头部(Headers)交换机。每种交换机根据不同的路由策略将消息路由到不同的队列。
  2. 路由键(Routing Key): 路由键是生产者在发送消息时指定的一个字符串值。生产者通过路由键告诉 RabbitMQ 消息的路由规则。不同类型的交换机使用路由键的方式不同。对于直接交换机,路由键与队列的绑定键(Binding Key)必须完全匹配;对于扇形交换机,路由键会被忽略,消息会被广播到所有绑定到该交换机的队列;而对于主题交换机,路由键可以使用通配符进行模糊匹配。
  3. 绑定(Binding): 绑定是交换机和队列之间的关联关系。在 RabbitMQ 中,消费者创建一个绑定,将队列绑定到特定的交换机,并指定绑定键(Binding Key)。绑定键的含义取决于交换机的类型。当一个消息发送到交换机时,交换机会根据消息的路由键和绑定的绑定键将消息路由到合适的队列。

综合起来,消息从生产者发送到交换机,交换机根据消息的路由键和绑定的绑定键将消息路由到相应的队列。消费者绑定到队列上,从队列中接收和处理消息。

下面是交换机、路由键和绑定之间的关系示意图:

Producer --> Message (with Routing Key) --> Exchange --> Binding (with Binding Key) --> Queue --> Consumer

总结: 交换机、路由键和绑定是 RabbitMQ 中实现消息路由的核心机制。生产者通过路由键指定消息的路由规则,交换机根据路由规则将消息路由到相应的队列中,供消费者进行处理。这种灵活的消息路由机制使得 RabbitMQ 能够适应不同的消息传递场景。

2.1.4 交换机类型

RabbitMQ 支持多种类型的交换机(Exchange),每种类型的交换机根据不同的路由策略将消息路由到绑定到它的队列中。下面介绍 RabbitMQ 中常见的交换机类型:

  1. 直接交换机(Direct Exchange): 直接交换机是最简单的交换机类型。它将消息的路由键与队列的绑定键(Binding Key)进行完全匹配,只有当路由键和绑定键完全相同时,才将消息路由到对应的队列中。可以理解为一种点对点的消息路由方式。如果消息的路由键没有与任何队列的绑定键匹配,那么消息将会被丢弃。直接交换机的路由规则是最严格的。

  1. 扇形交换机(Fanout Exchange): 扇形交换机是一种广播式的交换机。它会将收到的消息广播到所有绑定到它上面的队列,忽略消息的路由键。因此,使用扇形交换机时,无需指定绑定键。适用于需要将消息同时发送给多个消费者的场景。

  1. 主题交换机(Topic Exchange): 主题交换机是一种更加灵活的交换机类型。它将消息的路由键与队列的绑定键进行模糊匹配,支持通配符匹配。主题交换机的绑定键可以是一个由点号(.)分隔的单词列表,可以包含两种通配符:*表示匹配一个单词,#表示匹配零个或多个单词。使用主题交换机时,可以根据消息的路由键模式将消息路由到满足条件的队列中。

  1. 头部交换机(Headers Exchange): 头部交换机不使用路由键来路由消息,而是使用消息的头部信息进行匹配。它通过消息头部的键值对来决定消息是否路由到队列。头部交换机的匹配规则比较复杂,通常较少使用。

根据不同的业务场景和消息路由需求,可以选择合适的交换机类型。通过灵活地使用交换机和绑定,可以构建出强大的消息传递系统,实现消息的精确路由和广播传递。

2.1.5 RabbitMQ 运转流程

了解 RabbitMQ 的运转流程,包括生产者发送消息到交换机,交换机将消息路由到队列,消费者从队列中取出并处理消息。

以下是 RabbitMQ 的基本运转流程:

  1. 生产者发送消息:
    • 生产者(Producer)创建一个与 RabbitMQ 服务器的连接,并打开一个通道(Channel)。
    • 生产者声明一个交换机(Exchange)并将消息发送给该交换机。生产者需要指定交换机的名称、类型和路由键(Routing Key)。
    • 交换机根据指定的路由键将消息路由到一个或多个队列(Queue)中。
  1. 消费者接收消息:
    • 消费者(Consumer)创建一个与 RabbitMQ 服务器的连接,并打开一个通道。
    • 消费者声明一个队列,并将队列绑定到指定的交换机。消费者需要指定队列的名称、交换机的名称、绑定键(Binding Key)以及其他可选的参数。
    • 消费者通过订阅(Consume)队列来接收消息。
  1. 消息路由和传递:
    • 当生产者发送消息时,交换机根据消息的路由键和绑定的绑定键将消息路由到相应的队列中。
    • 队列中的消息将按照先进先出(FIFO)的顺序被消费者接收和处理。
  1. 消息确认:
    • 消费者在接收到消息并处理完成后,可以向 RabbitMQ 发送确认信号(ACK),告知 RabbitMQ 消息已经被成功处理。
    • 如果消费者不发送 ACK,RabbitMQ 会将消息重新发送给其他消费者或继续存储在队列中。
  1. 持久性和高可用性:
    • RabbitMQ 支持队列和消息的持久化,确保消息在服务器重启后不会丢失。
    • 可以通过设置镜像队列和集群等机制来实现 RabbitMQ 的高可用性。
  1. 其他特性:
    • RabbitMQ 还支持消息的过期时间(TTL)、死信队列、延迟队列、优先级队列等高级特性。

在 RabbitMQ 中,一个生产者与 RabbitMQ 建立连接后,通常会创建多个 Channel 信道。每个 Channel 是一个独立的会话通道,用于进行消息的发送和接收。通过创建多个 Channel,生产者可以并行发送多个消息(在不同的 Channel 上发送不同的消息,或者在同一个 Channel 上发送多条消息),从而提高消息的处理效率和吞吐量。

每个连接可以创建多个 Channel,而每个 Channel 只属于一个连接。这样的设计可以在一个连接上同时进行多个操作,而不需要等待之前的操作完成。同时,每个 Channel 之间是相互独立的,一个 Channel 的异常不会影响其他 Channel 的正常运行。

生产者与 RabbitMQ 建立的连接可以对应一个或多个 Virtual Host (vhost)。

Virtual Host 是 RabbitMQ 中用于进行逻辑隔离的概念,它允许在单个 RabbitMQ 服务器上创建多个独立的逻辑消息环境。每个 Virtual Host 类似于一个独立的消息代理,拥有自己的交换机、队列、绑定等资源。这样可以使不同的应用或服务在同一台 RabbitMQ 服务器上运行,互相之间不会干扰。

当生产者与 RabbitMQ 建立连接时,可以选择连接到指定的 Virtual Host。如果没有指定 Virtual Host,默认情况下生产者连接到名为 "/" 的默认 Virtual Host。然后,生产者可以在该 Virtual Host 中进行消息的生产和发送。

在一个 RabbitMQ 服务器上可以配置多个 Virtual Host,因此生产者可以建立多个连接,并分别连接到不同的 Virtual Host,以便将消息发送到不同的逻辑环境中。

消费者与 RabbitMQ 建立连接后,消费消息通常是根据队列名称直接与队列进行交互,而不是直接与交换机交互。在 RabbitMQ 中,生产者将消息发送到交换机,然后交换机根据绑定规则将消息路由到相应的队列。消费者需要消费队列中的消息,因此它会与特定的队列建立连接,并从队列中取出消息进行消费。

消费者通过创建一个或多个 Channel 信道,然后通过这些 Channel 与指定的队列建立连接。然后,消费者可以通过消费队列的操作来从队列中取出消息,并进行处理。

通过与队列直接交互,消费者可以按照自己的消费速率从队列中获取消息,这样可以更好地控制消息的消费过程,避免消息的丢失或堆积。同时,队列还可以作为消息的缓冲区,帮助消费者处理可能出现的瞬时流量高峰。这样的设计使得消息的消费过程更加灵活和可靠。

总结: RabbitMQ 通过交换机、队列和绑定的灵活组合,实现了高效可靠的消息传递。生产者将消息发送到交换机,交换机根据消息的路由键将消息路由到队列中,然后消费者从队列中接收消息进行处理。通过消息确认机制,确保消息的可靠处理。同时,RabbitMQ 支持多种高级特性,使得消息传递更加灵活和强大。

2.2 AMQP 协议介绍

AMQP(Advanced Message Queuing Protocol,高级消息队列协议)是一种开放标准的消息传递协议,旨在实现跨网络的高性能、高可靠性的消息传递。它提供了一种灵活的消息传递模型,适用于各种异步消息传递场景,如消息队列、消息中间件和消息路由。

以下是 AMQP 协议的主要特点和介绍:

  1. 高度可扩展:AMQP 协议支持多种交换机和队列类型,以及灵活的路由规则,可以根据不同的业务需求进行定制和扩展。这使得 AMQP 协议适用于各种规模和复杂度的应用场景。
  2. 异步消息传递:AMQP 协议采用异步消息传递模型,生产者和消费者之间不需要直接建立连接,而是通过交换机和队列来中转消息。这样可以实现解耦和灵活的消息传递。
  3. 高可靠性:AMQP 协议支持消息的持久化,可以确保消息在服务器重启后不会丢失。同时,它提供了消息确认机制,消费者可以向服务器发送确认信号,告知服务器消息已经被成功处理。
  4. 跨平台支持:AMQP 协议是一种开放标准,得到了众多厂商和社区的支持。因此,它可以在不同的编程语言和操作系统上进行实现,实现跨平台的消息传递。
  5. 安全性:AMQP 协议支持身份验证和加密传输,可以确保消息在传输过程中的安全性。
  6. 多种消息传递模式:AMQP 协议支持多种消息传递模式,包括点对点(Point-to-Point)和发布-订阅(Publish-Subscribe)等。这使得它可以适应不同的消息传递需求。
  7. 灵活的路由规则:AMQP 协议支持多种交换机类型,可以根据消息的路由键和绑定键将消息路由到相应的队列中。这使得消息传递更加灵活和精确。

AMQP 协议是一种非常强大和通用的消息传递协议,它在分布式系统中广泛应用于异步消息传递场景。RabbitMQ 作为 AMQP 协议的实现之一,提供了高性能、高可靠性的消息传递服务,并支持丰富的特性和灵活的消息传递模型。

2.2.1 AMQP 生产者流转过程

AMQP 生产者(Producer)流转过程描述了生产者如何将消息发送到 RabbitMQ 服务器的过程。以下是 AMQP 生产者流转过程的详细步骤:

  1. 建立连接:生产者首先与 RabbitMQ 服务器建立一个网络连接。这是通过 TCP/IP 连接到 RabbitMQ 服务器的默认端口(5672)来实现的。
  2. 创建通道:在建立连接后,生产者需要在该连接上创建一个通道(Channel)。通道是在连接上打开的一个轻量级会话,所有的消息传递操作都是在通道上进行的。通道的创建可以通过 AMQP 协议中的 channel.open 命令实现。
  3. 声明交换机(Exchange):生产者需要声明一个交换机,用于发送消息。交换机是消息的接收和路由中心,它根据消息的路由键将消息路由到一个或多个队列。交换机的声明可以通过 AMQP 协议中的 exchange.declare 命令实现。
  4. 发布消息:生产者使用 channel.basicPublish 方法将消息发送到交换机。在消息中,生产者需要指定交换机的名称、路由键以及消息的主体(Payload)。
  5. 路由规则:交换机根据消息的路由键将消息路由到相应的队列。具体的路由规则取决于交换机的类型。如果找不到与消息路由键匹配的队列,根据交换机的规则,消息可能会被丢弃或存储在交换机中。
  6. 消息持久化(可选):生产者可以选择将消息设置为持久化的。通过在消息的属性中设置 deliveryMode 为 2,可以确保消息在服务器重启后不会丢失。
  7. 关闭通道和连接:当生产者完成消息发送后,可以选择关闭通道和连接,释放资源。关闭通道和连接是通过 AMQP 协议中的 channel.close 和 connection.close 命令来实现的。

AMQP 生产者流转过程包括建立连接、创建通道、声明交换机、发布消息等步骤。生产者通过交换机将消息发送到 RabbitMQ 服务器,并根据消息的路由键将消息路由到相应的队列中。生产者可以选择设置消息的持久性,确保消息在服务器重启后不会丢失。完成消息发送后,生产者可以选择关闭通道和连接,释放资源。

2.2.2 AMQP 消费者流转过程

AMQP 消费者(Consumer)流转过程描述了消费者如何从 RabbitMQ 服务器接收和处理消息的过程。以下是 AMQP 消费者流转过程的详细步骤:

  1. 建立连接:消费者首先与 RabbitMQ 服务器建立一个网络连接。这是通过 TCP/IP 连接到 RabbitMQ 服务器的默认端口(5672)来实现的。
  2. 创建通道:在建立连接后,消费者需要在该连接上创建一个通道(Channel)。通道是在连接上打开的一个轻量级会话,所有的消息传递操作都是在通道上进行的。通道的创建可以通过 AMQP 协议中的 channel.open 命令实现。
  3. 声明队列:消费者需要声明一个队列,用于接收消息。队列的声明可以通过 AMQP 协议中的 queue.declare 命令实现。消费者需要指定队列的名称、是否持久化、是否独占等参数。
  4. 绑定队列和交换机:消费者需要将队列绑定到一个或多个交换机上,以便从交换机接收消息。绑定可以通过 AMQP 协议中的 queue.bind 命令实现。消费者需要指定交换机的名称、绑定键(Binding Key)等参数。
  5. 订阅队列:消费者使用 channel.basicConsume 方法订阅队列,开始接收消息。在订阅时,消费者可以指定消费者标签(Consumer Tag)和消息回调函数。
  6. 消息回调:当队列中有消息到达时,RabbitMQ 服务器会将消息传递给消费者的消息回调函数。消费者可以在回调函数中处理收到的消息。
  7. 消息确认(可选):消费者在成功处理消息后,可以选择向 RabbitMQ 服务器发送确认信号(ACK),告知服务器消息已经被成功处理。消息确认可以通过 AMQP 协议中的 basic.ack 命令实现。如果消费者没有发送确认信号,RabbitMQ 会认为消息没有被成功处理,并将其重新发送给其他消费者或者继续存储在队列中。
  8. 关闭通道和连接:当消费者不再需要接收消息时,可以选择关闭通道和连接,释放资源。关闭通道和连接是通过 AMQP 协议中的 channel.close 和 connection.close 命令来实现的。

AMQP 消费者流转过程包括建立连接、创建通道、声明队列、绑定队列和交换机、订阅队列、消息回调等步骤。消费者通过订阅队列接收消息,当队列中有消息到达时,RabbitMQ 服务器将消息传递给消费者的消息回调函数。消费者可以选择发送确认信号来确认消息的处理结果。完成消息接收和处理后,消费者可以选择关闭通道和连接,释放资源。

2.2.3 AMQP命令概览

AMQP(Advanced Message Queuing Protocol)是一个复杂的协议,用于在消息传递系统中传输消息。它包含许多不同的命令和方法,用于管理连接、通道、交换机、队列以及消息的传递等操作。以下是 AMQP 命令的概览,列出了一些常见的AMQP命令和方法:

  1. 连接管理命令:
    • connection.start:启动连接,用于协商协议版本和进行身份验证。
    • connection.secure:在安全连接上进行身份验证。
    • connection.open:打开一个新的连接。
    • connection.close:关闭当前连接。
  1. 通道管理命令:
    • channel.open:打开一个新的通道。
    • channel.close:关闭当前通道。
  1. 交换机管理命令:
    • exchange.declare:声明一个交换机。
    • exchange.delete:删除一个交换机。
  1. 队列管理命令:
    • queue.declare:声明一个队列。
    • queue.bind:将队列绑定到一个交换机上。
    • queue.unbind:解绑队列和交换机的绑定关系。
    • queue.purge:清空队列中的所有消息。
    • queue.delete:删除一个队列。
  1. 消息传递命令:
    • basic.publish:将消息发送到交换机。
    • basic.consume:订阅队列,接收消息。
    • basic.get:从队列中获取单个消息,非订阅方式。
    • basic.ack:确认收到消息,告知服务器消息已被处理。
    • basic.nack:否定消息,告知服务器消息未被成功处理。
    • basic.reject:拒绝消息,告知服务器不接受消息。
  1. 事务命令:
    • tx.select:开启事务。
    • tx.commit:提交事务。
    • tx.rollback:回滚事务。
  1. 其他命令:
    • confirm.select:启用发布确认模式,用于确认消息是否被正确接收和处理。
    • confirm.select-ok:确认发布确认模式已经启用。

以上仅列出了一部分 AMQP 命令和方法,实际上 AMQP 协议有更多的命令和参数,用于支持复杂的消息传递和系统管理操作。在使用 AMQP 的客户端库时,这些命令和方法会被封装成相应的API函数,开发者可以通过这些API函数来实现对 RabbitMQ 服务器的操作。

2.3 小结

本章介绍了 RabbitMQ 的入门知识,包括相关概念的介绍和 AMQP 协议的简要介绍。在下一章中,我们将学习 RabbitMQ 客户端的开发向导,包括如何连接 RabbitMQ 服务器、使用交换机和队列、发送和消费消息等。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

02 笔记本电脑m.2硬盘更换

1 工具展示 SN570的2T硬盘。够用了。 对于这台华为,使用的螺丝刀批头是4或5毫米的六边形批头。如果出现打滑的情况,请不要用蛮力哦。 2 更换过程 使用螺丝刀拧走后盖的螺丝(为了避免会出问题要再次打开,我到现在还没有把螺丝拧回…

每日一题8.2 2536

2536. 子矩阵元素加 1 给你一个正整数 n ,表示最初有一个 n x n 、下标从 0 开始的整数矩阵 mat ,矩阵中填满了 0 。 另给你一个二维整数数组 query 。针对每个查询 query[i] [row1i, col1i, row2i, col2i] ,请你执行下述操作:…

minio-分布式文件存储系统

minio-分布式文件存储系统 minio的简介 MinIO基于Apache License v2.0开源协议的对象存储服务,可以做为云存储的解决方案用来保存海量的图片,视频,文档。由于采用Golang实现,服务端可以工作在Windows,Linux, OS X和FreeBSD上。配置…

Stable Diffusion 硬核生存指南:WebUI 中的 CodeFormer

本篇文章聊聊 Stable Diffusion WebUI 中的核心组件,强壮的人脸图像面部画面修复模型 CodeFormer 相关的事情。 写在前面 在 Stable Diffusion WebUI 项目中,源码 modules 目录中,有一个有趣的目录叫做 CodeFormer,它就是本文的…

P3855 [TJOI2008] Binary Land(BFS)(内附封面)

[TJOI2008] Binary Land 题目背景 Binary Land是一款任天堂红白机上的经典游戏,讲述的是两只相爱的企鹅Gurin和Malon的故事。两只企鹅在一个封闭的迷宫中,你可以控制他们向上下左右四个方向移动。但是他们的移动有一个奇怪的规则,即如果你按…

【点云处理教程】00计算机视觉的Open3D简介

一、说明 Open3D 是一个开源库,使开发人员能够处理 3D 数据。它提供了一组用于 3D 数据处理、可视化和机器学习任务的工具。该库支持各种数据格式,例如 .ply、.obj、.stl 和 .xyz,并允许用户创建自定义数据结构并在程序中访问它们。 Open3D 广…

Python——调用webdriver.Chrome() 报错

今天运行脚本&#xff0c;报错内容如下&#xff1a; collecting ... login_case.py:None (login_case.py) login_case.py:11: in <module> dr webdriver.Chrome() D:\Program Files (x86)\Python\Python39\Lib\site-packages\selenium\webdriver\chrome\webdriver.p…

uniapp使用视频地址获取视频封面

很多时候我们都需要使用视频的第一帧当作视频的封面&#xff0c;今天我们从uni-app的安卓app这个环境来实现下这个需求。 uniapp 安卓APP端&#xff08;ios未测试&#xff09; 方法&#xff1a;使用renderjs实现对DOM元素的操作&#xff0c;创建video元素获取视频转第一帧&am…

图论-简明导读

计算机图论是计算机科学中的一个重要分支&#xff0c;它主要研究图的性质和结构&#xff0c;以及如何在计算机上有效地存储、处理和操作这些图。本文将总结计算机图论的核心知识点。 一、基本概念 计算机图论中的基本概念包括图、节点、边等。图是由节点和边构成的数据结构&am…

APP外包开发的iOS开发框架

在开发APP时需要用到各种框架&#xff0c;这些框架提供了基础的软件功能&#xff0c;可以减轻开发工作量&#xff0c;因此在APP项目开发中熟练运用常见的框架是开发者需要掌握的技能。每个框架都有其特点和适用场景&#xff0c;开发者可以根据项目的需求选择合适的框架进行开发…

kv键值对快速转换为json串(字典类型) | 批量添加双引号

从浏览器中复制的以下数据, 并不能直接使用 refresh:0 start:0 count:20 selected_categories:%7B%7D uncollect:false playable:true tags:在python中需转为字典类型 {refresh: 0,start: 0,count: 20,selected_categories: %7B%7D,uncollect: false,playable: true,tags: , …

docker push 报错:unauthorized: unauthorized to access repository: library/xx处理方法

rootmaster:/home/data/harbor# sudo docker login 49.0.241.2 admin Harbor12345 1.报错原因分析 rootmaster:/home/data/harbor# docker push 49.0.241.2/library/nginx:latest #这种报错 The push refers to repository [49.0.241.2/library/nginx] Get "https://49.…

【网络】网络层(IP协议)

目录 一、基本概念 二、协议头格式 三、网段划分 四、特殊的IP地址 五、IP地址的数量限制 六、私有IP地址和公网IP地址 七、路由 一、基本概念 IP协议&#xff1a;提供一种能力&#xff0c; 将数据从A主机送到B主机&#xff0c;&#xff08;TCP协议&#xff1a;确保IP协议…

数据分析 VS 数据可视化:决战时刻

数据分析和数据可视化是数据科学领域中两个重要的组成部分&#xff0c;很多人不明白两者之间的关系&#xff0c;会误认为是一个东西&#xff0c;其实不然。本文就带大家简单了解一下它们的区别与联系吧&#xff01; 数据分析是指通过收集、处理和解释数据来获取有关特定问题或…

Jenkins 节点该如何管理?

Jenkins 拥有分布式构建(在 Jenkins 的配置中叫做节点)&#xff0c;分布式构建能够让同一套代码在不同的环境(如&#xff1a;Windows 和 Linux 系统)中编译、测试等 Jenkins 的任务可以分布在不同的节点上运行 节点上需要配置 Java 运行时环境&#xff0c;JDK 版本大于 1.5 节…

今年嵌入式行情怎么样?

我不了解其它行业可能描述有些片面&#xff0c;但总的来说&#xff0c;我对嵌入式是很看好的&#xff0c;因为你可以感受到你能实际的做出产品而不是类似前端和互联网只是数字数据。 并且嵌入式的学习过程充满乐趣&#xff0c;你可以接触到从沙子到开关管到逻辑门到芯片架构到…

图文档数字化:实现高效管理的几大步骤

在当今数字化时代&#xff0c;企业越来越意识到数字化管理对于图文档的重要性。传统的纸质文件管理往往效率低下&#xff0c;容易出现丢失和混乱的情况。为了提高工作效率、降低成本并确保数据安全&#xff0c;许多企业选择采用PDM&#xff08;产品数据管理&#xff09;系统来实…

JVM内存模型【入门】

计算机结构简图 JVM内存模型 详细说明&#xff1a;https://blog.csdn.net/m0_71777195/article/details/126247090 什么是JVM&#xff1f; JVM是Java Virtual Machine&#xff08;Java虚拟机&#xff09;的缩写&#xff0c;JVM是一个虚构出来的计算机&#xff0c;有着自己完善…

【触觉智能Purple Pi OH开发板体验】开箱体验:开源主板Purple Pi RK3566 上手指北

前言 前段时间收到来自【电子发烧友】的一款开发板&#xff0c;名叫&#xff1a;PurplePi&#xff0c;216G售价仅249元。它使用的芯片是rk3566&#xff0c;适配的OpenHarmony版本为3.2 Release 是目前最便宜的OpenHarmony标准系统开源开发板&#xff0c;并且软硬件全部开源&am…

SpringCloud之断路器聚合监控

一、Hystrix Turbine简介 看单个的Hystrix Dashboard的数据并没有什么多大的价值&#xff0c;要想看这个系统的Hystrix Dashboard数据就需要用到Hystrix Turbine。Hystrix Turbine将每个服务Hystrix Dashboard数据进行了整合。Hystrix Turbine的使用非常简单&#xff0c;只需要…