RabbitMQ 教程 | 第2章 RabbitMQ 入门

news2024/11/18 8:34:44

👨🏻‍💻 热爱摄影的程序员
👨🏻‍🎨 喜欢编码的设计师
🧕🏻 擅长设计的剪辑师
🧑🏻‍🏫 一位高冷无情的编码爱好者
大家好,我是 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 服务器、使用交换机和队列、发送和消费消息等。

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

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

相关文章

1,复杂度和简单排序算法【p2-p3】

复杂度和简单排序算法 1,时间复杂度1.1选择排序1.2冒泡排序1.3异或运算1.3.1性质:1.3.2案例例1例2 1.4插入排序1.5二分法1.5.1在一个有序数组中,找某个数是否存在1.5.2在一个有序数组中,找>某个数最左侧的位置1.5.3局部最小值问…

linux系统编程重点复习--守护进程和线程

复习目标 说出守护进程的特点独立完成守护进程的创建独立实现多个线程的创建独立实现线程的退出和资源回收理解线程同步的思想 1 守护进程 1.1 守护进程介绍 Daemon(精灵)进程,是Linux中的后台服务进程,通常独立于控制终端并且周期性地执行某种任务或…

通向架构师的道路之Apache整合Tomcat

一、先从J2EE工程的通用架构说起 这是一个通用的Web即B/S工程的架构,它由: Web Server App Server DB Server 三大部分组成,其中: Web Server 置于企业防火墙外,这个防火墙,大家可以认为是…

hugging face下载数据集

开始直接执行这个,下载下来的图片打不开 git clone https://huggingface.co/datasets/diffusers/dog-example 解决办法: 安装git lfs 1. curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | sudo bash 2. sudo apt…

论文笔记:Adjusting for Autocorrelated Errors in Neural Networks for Time Series

2021 NIPS 原来的时间序列预测任务是根据预测论文提出用一阶自回归误差预测 一阶差分,类似于ResNet的残差思路?记为pred,最终的预测结果

zore-shot,迁移学习和多模态学习

1.zore-shot 定义:在ZSL中,某一类别在训练样本中未出现,但是我们知道这个类别的特征,然后通过语料知识库,便可以将这个类别识别出来。概括来说,就是已知描述,对未知类别(未在训练集中…

Qsys介绍

文章目录 前言一、为什么需要Qsys1、简化了系统的设计流程2、Qsys涉及的技术 二、Qsys真身1、一种系统集成工具2、何为Nios II1、内核架构2、Nios II选型 三、Qsys设计涉及到的软件&工具四、总结五、参考资料 前言 Qsys是Altera下的一个系统集成工具,可用于搭建…

代码随想录算法训练营第三十天 | 单调栈系列复习

单调栈系列复习 每日温度未看解答自己编写的青春版重点题解的代码日后再次复习重新写 下一个更大元素 I未看解答自己编写的青春版重点题解的代码日后再次复习重新写 下一个更大元素II未看解答自己编写的青春版重点题解的代码日后再次复习重新写 接雨水未看解答自己编写的青春版…

idea模块的pom.xml被划横线,不识别的解决办法

目录 问题: 解决办法: 1.打开设置 2. 取消勾选 3.点击确认 4.解决 问题提出: 写shi山的过程中,给模块取错名字了,改名的时候不知道点到了什么,一个模块的pom.xml变成灰色了&#xff0…

3ds MAX粒子系统演示

其他各案例可以在视频中看到: 从左向右依次是: 粒子流源、喷射、雪、超级喷射、暴风雪、粒子阵列、粒子云 粒子系统

小研究 - JVM 垃圾回收方式性能研究(一)

本文从几种JVM垃圾回收方式及原理出发,研究了在 SPEC jbb2015基准测试中不同垃圾回收方式对于JVM 性能的影响,并通过最终测试数据对比,给出了不同应用场景下如何选择垃圾回收策略的方法。 目录 1 引言 2 垃圾回收算法 2.1 标记清除法 2.2…

iOS开发-实现获取下载主题配置动态切换主题

iOS开发-实现获取下载主题配置动态切换主题 iOS开发-实现获取下载主题配置更切换主题,主要是通过请求服务端配置的主题配置、下载主题、解压保存到本地。通知界面获取对应的图片及颜色等。 比如新年主题风格,常见的背景显示红色氛围图片、tabbar显示新…

Visual Studio 设置默认编码格式为 UTF-8

1.添加高级保存选项 2.更改编码格式

客户端服务器通过Socket API通信流程 通过源码角度分析 三握手四挥手都过程的状态改变 及 例如accept()connect()具体做了什么

首先我们先说下网络编程API: 数据在网络上通信,通信的双方一个是 客户端, 一个是 服务器 更具体来说,不是 客户端和服务器这两个机器在 经由互联网 进行通信, 而是 客户端上的某一进程 与 服务器端的某一进程 进…

Java 单链表

链表基本介绍 链表在内存中的实际存储结构 链表的逻辑结构 单链表应用实例 代码实现 // 英雄节点,存储了英雄的信息 class HeroNode {public int id; // 英雄编号public String name; // 英雄名字public String nickName; // 英雄昵称public HeroNode next; // 指…

【系统软件01】devtoolset离线安装gcc

【系统软件01】devtoolset离线安装gcc 一、SCL简介二、SCL源安装三、离线下载devtoolset1、Developer Toolset2、下载devtoolset-93、压缩devtoolset-9 三、离线安装devtoolset-9(gcc9.3)1、解压devtoolset-9.tar.gz2、安装devtoolset-9 四、设置环境变量(使用gcc9.3)1、当前窗…

LeetCode547.Number-Of-Provinces<省份问题>

题目: 思路: 连通的部分加起来,然后总的 减去连通的部分。 但是很可惜 只能通过部分 似乎将st[i][j] st[j][i] 改变之后是可行的 但是实际上 1 2 连通后 2 1 确实是不会再加。 但是 2 3却还是在加一遍。 好吧。答案的思路是使用并查集。将…

lc209.长度最小的子数组

暴力破解:二次for循环遍历num[i]...num[j],记录满足条件的最小长度 前缀和二分:前缀和降低计算num[i]...num[j]的时间复杂度 对前缀和数组中的每个数进行遍历,找到距离这个数满足条件的最小长度 前缀和数组单调递增,此…

蓝海卓越计费管理系统任意文件读取下载

……人哪,活着是这么的苦!一旦你从幸福的彼岸被抛到苦难的此岸,你真是处处走头无路;而现在你才知道,在天堂与地狱之间原来也只有一步之遥! 漏洞描述 蓝海卓越计费管理系统存在任意文件读取漏洞&#xff0…

pycharm写scrapy遇到的问题

目录 背景创建scrapy难受的开始指定类型修改模板并指定使用运行scrapy 背景 居然还有万能的pycharm解决不了的python程序??? 创建scrapy 由于PyCharm中没有直接创建Scrapy项目的选项,所以使用命令行创建一个项目 安装scrapy pip install…