RabbitMQ 集群与高可用性

news2024/11/15 13:35:04

目录

单节点与集群部署

1.1. 单节点部署

1.2. 集群部署

 镜像队列

1.定义与工作原理

2. 配置镜像队列

3.应用场景

4. 优缺点

5. Java 示例

分布式部署

1. 分布式部署的主要目标

2. 典型架构设计

3. RabbitMQ 分布式部署的关键技术

4. 部署策略和实践

5. 分布式部署的挑战和解决方案

6.使用Docker Compose 实现分布式部署

总结


前言

RabbitMQ 是一个广泛使用的消息队列系统,具有强大的集群和高可用性特性。以下是有关 RabbitMQ 集群与高可用性方面的详细解析,涵盖了单节点与集群部署、镜像队列、以及分布式架构的部署策略和最佳实践。

单节点与集群部署

1.1. 单节点部署

定义
RabbitMQ 的单节点部署是指在一台服务器上运行一个 RabbitMQ 实例。它适用于开发、测试环境或对高可用性要求不高的场景。

工作原理
在单节点中,所有消息和队列都集中在一个 RabbitMQ 实例上。如果该实例出现故障,则会导致消息服务不可用。

优缺点

  • 优点

    • 简单易用,部署和管理成本低。
    • 适合小规模应用和开发测试场景。
  • 缺点

    • 没有冗余,存在单点故障风险。
    • 扩展性差,难以应对高并发和大流量需求。

应用场景

  • 开发和测试环境。
  • 对消息丢失或短暂服务中断容忍度较高的生产环境。

配置方式

  • 在单台服务器上安装 RabbitMQ。
  • 通过管理插件或命令行工具进行简单的管理和监控。

示例

  • 使用 Docker 启动单节点 RabbitMQ:
docker run -d --name rabbitmq -p 5672:5672 -p 15672:15672 rabbitmq:management

详细可参考之前的文章:

RabbitMQ入门基础及使用Docker安装

1.2. 集群部署

定义
RabbitMQ 集群由多个 RabbitMQ 节点组成,这些节点协同工作以提供更高的可用性和可扩展性。

工作原理
集群中的各个节点共享元数据,但消息存储在单个节点上(默认配置)。当一个节点出现故障时,集群中的其他节点仍然可以继续提供服务。

优缺点

  • 优点

    • 提高了系统的可靠性,减少单点故障。
    • 支持横向扩展,能够处理更多的消息和更高的并发量。
  • 缺点

    • 部署和管理相对复杂。
    • 需要额外的网络和存储资源。

应用场景

  • 高可用性要求高的生产环境。
  • 大流量、大并发的分布式系统。

配置方式一

1. 创建网络

docker network create rabbitmq-network

创建一个 Docker 自定义网络,名为 rabbitmq-network。此网络用于让各个 RabbitMQ 容器节点能够相互通信。Docker 网络确保节点之间的容器可以通过容器名互相访问,这对于集群的节点发现和通信至关重要

2. 启动节点1(磁盘节点)

# rabbitmq:3.12-management 镜像名:版本
docker run -d --hostname rabbit1 --name rabbit1 --network rabbitmq-network -e RABBITMQ_ERLANG_COOKIE='my_cookie' -e RABBITMQ_NODENAME=rabbit@rabbit1 -p 15672:15672 -p 5672:5672 rabbitmq:3.12-management
  • -d:后台运行容器。
  • --hostname rabbit1:设置容器的主机名为 rabbit1,这是 RabbitMQ 节点的名称标识。
  • --name rabbit1:设置容器的名称为 rabbit1,用于 Docker 内部管理。
  • --network rabbitmq-network:将容器连接到前面创建的 rabbitmq-network 网络中。
  • -e RABBITMQ_ERLANG_COOKIE='my_cookie':设置 Erlang Cookie,用于节点间的身份验证,确保集群的安全性。
  • -e RABBITMQ_NODENAME=rabbit@rabbit1:设置 RabbitMQ 节点的名称为 rabbit@rabbit1,这个名称在集群中是唯一的。
  • -p 15672:15672-p 5672:5672:分别映射管理界面和 AMQP 协议的端口到宿主机上,允许外部访问。

这是一个磁盘节点(默认),数据会保存在磁盘上。

3.启动节点2(RAM节点)

docker run -d --hostname rabbit2 --name rabbit2 --network rabbitmq-network -e RABBITMQ_ERLANG_COOKIE='my_cookie' -e RABBITMQ_NODENAME=rabbit@rabbit2 rabbitmq:3.12-management

 与启动节点1类似,但不暴露端口,并且这个节点稍后会加入到集群中并设置为 RAM 节点。RAM 节点的数据存储在内存中,适合对性能要求高的场景。

4.将节点2加入集群

docker exec -it rabbit2 bash
rabbitmqctl stop_app
rabbitmqctl join_cluster rabbit@rabbit1
rabbitmqctl start_app
exit
  • docker exec -it rabbit2 bash:进入 rabbit2 容器的交互式终端。
  • rabbitmqctl stop_app:停止 RabbitMQ 应用,准备加入集群。
  • rabbitmqctl join_cluster rabbit@rabbit1:将 rabbit2 节点加入到 rabbit1 节点所在的集群中。
  • rabbitmqctl start_app:启动 RabbitMQ 应用,使节点成为集群的一部分。
  • exit:退出容器的交互式终端。

5.启动节点3(RAM节点)

docker run -d --hostname rabbit3 --name rabbit3 --network rabbitmq-network -e RABBITMQ_ERLANG_COOKIE='my_cookie' -e RABBITMQ_NODENAME=rabbit@rabbit3 rabbitmq:3.12-management

 启动另一个 RAM 节点 rabbit3,与启动节点2类似。

6.将节点3加入集群

docker exec -it rabbit3 bash
rabbitmqctl stop_app
rabbitmqctl join_cluster rabbit@rabbit1
rabbitmqctl start_app
exit

与节点2的加入过程相同,将 rabbit3 加入到集群中,使其成为集群的一部分

  • 这组指令搭建了一个包含一个磁盘节点(rabbit1)和两个 RAM 节点(rabbit2 和 rabbit3)的 RabbitMQ 集群。
  • 磁盘节点负责持久化数据,RAM 节点利用内存加快消息的处理速度。
  • 每个节点通过指定的网络相互通信,并通过 Erlang Cookie 进行身份验证。
     

7.启动并访问

注:由于本次启动时并没有指定用户与密码,所以使用默认的guest/guest进行登录即可,也可以自己基于之前的文章 进行添加用户:
RabbitMQ日常运维指令集

 配置方式二

使用 Docker Compose 部署一个简单的 RabbitMQ 集群是一种便捷的方法,可以轻松管理多个 RabbitMQ 节点。以下是详细的步骤,包括如何编写 docker-compose.yml 文件以及配置、启动集群的过程。

1. 准备 docker-compose.yml 文件

首先,创建一个名为 docker-compose.yml 的文件,该文件定义了 RabbitMQ 集群的服务配置:

version: '3.8'
services:
  rabbit1:
    image: rabbitmq:3.12-management
    container_name: rabbit1
    hostname: rabbit1
    environment:
      RABBITMQ_ERLANG_COOKIE: 'my_cookie'
      RABBITMQ_NODENAME: 'rabbit@rabbit1'
    ports:
      - "15672:15672"  # 管理界面端口
      - "5672:5672"    # AMQP 协议端口
    networks:
      - rabbitmq_network
    volumes:
      - rabbit1_data:/var/lib/rabbitmq

  rabbit2:
    image: rabbitmq:3.12-management
    container_name: rabbit2
    hostname: rabbit2
    environment:
      RABBITMQ_ERLANG_COOKIE: 'my_cookie'
      RABBITMQ_NODENAME: 'rabbit@rabbit2'
    networks:
      - rabbitmq_network
    volumes:
      - rabbit2_data:/var/lib/rabbitmq

  rabbit3:
    image: rabbitmq:3.12-management
    container_name: rabbit3
    hostname: rabbit3
    environment:
      RABBITMQ_ERLANG_COOKIE: 'my_cookie'
      RABBITMQ_NODENAME: 'rabbit@rabbit3'
    networks:
      - rabbitmq_network
    volumes:
      - rabbit3_data:/var/lib/rabbitmq

networks:
  rabbitmq_network:

volumes:
  rabbit1_data:
  rabbit2_data:
  rabbit3_data:

docker-compose.yml 文件说明

  • version: 3.8 指定了 Docker Compose 文件的版本。
  • services: 定义了三个 RabbitMQ 服务 rabbit1rabbit2rabbit3,分别对应三个节点。
  • image: 使用 rabbitmq:3-management 镜像,包含 RabbitMQ 和管理插件。
  • container_name: 每个服务对应的容器名称。
  • hostname: 指定每个 RabbitMQ 节点的主机名,这对于集群中的节点名称是必要的。
  • environment: 配置环境变量:
    • RABBITMQ_ERLANG_COOKIE: Erlang Cookie,用于节点间的通信和认证。
    • RABBITMQ_NODENAME: 节点名称,必须唯一。
  • ports: 将 RabbitMQ 的管理界面和 AMQP 端口映射到宿主机上。
  • networks: 使用自定义的 rabbitmq_network 网络,以确保各节点之间可以互相通信。
  • volumes: 为每个节点配置持久化存储,以便重启后数据不会丢失。

2.启动集群

在包含 docker-compose.yml 文件的目录下,运行以下命令以启动集群:

docker-compose up -d

 此命令将在后台启动所有定义的 RabbitMQ 节点,并且这些节点将自动连接到同一个 Docker 网络 rabbitmq_network

验证集群

要验证集群是否正常运行,可以通过以下步骤:

检查服务状态

查看所有运行的容器,确保三个 RabbitMQ 容器都在运行:

docker ps

检查集群状态

进入 rabbit1 容器并检查集群状态:

docker exec -it rabbit1 bash
rabbitmqctl cluster_status

停止和删除集群

要停止并删除容器及其相关的网络和卷,运行以下命令:

docker-compose down -v

-v 选项将删除创建的卷,确保数据被清除。

 镜像队列

1.定义与工作原理

镜像队列是指将主节点的队列内容同步到集群中的其他节点上。当消费者从队列消费消息时,消息会从主节点发送,镜像节点会同步地更新其状态。如果主节点出现故障,RabbitMQ 会自动将其中一个镜像节点提升为新的主节点,从而继续处理队列中的消息。

工作原理

  • 主队列(Master Queue):在集群中的某个节点上维护的队列。
  • 镜像节点(Mirror Nodes):集群中的其他节点,它们会保持主队列的完整副本。
  • 故障切换(Failover):当主队列所在节点宕机时,RabbitMQ 自动选择一个镜像节点作为新的主队列,并继续处理消息。
2. 配置镜像队列

镜像队列可以通过 RabbitMQ 的策略(Policy)来配置。在 RabbitMQ 中,策略通过正则表达式匹配队列名称,然后应用指定的配置项来控制镜像队列的行为。

配置镜像队列的步骤:

  1. 连接到 RabbitMQ 管理界面或通过命令行执行操作。

  2. 创建策略,指定要镜像的队列以及镜像的规则:

    通过 RabbitMQ 管理界面:

    • 进入 "Admin" 选项卡,选择 "Policies"。
    • 创建新的策略,指定名称、匹配队列的正则表达式(如 ^mirrored.*)、配置镜像参数。

    通过命令行:

rabbitmqctl set_policy ha-all "^mirrored.*" '{"ha-mode":"all"}'
  • 以上命令的含义:

    • ha-all:策略名称。
    • ^mirrored.*:匹配队列名称的正则表达式,所有以 mirrored 开头的队列都会应用该策略。
    • {"ha-mode":"all"}:指定将队列镜像到集群中的所有节点。
  • 验证配置

    • 使用 RabbitMQ 管理界面查看队列状态,确认队列已被镜像。
    • 或使用以下命令行查看队列详细信息:
rabbitmqctl list_queues name policy slave_pids
3.应用场景

镜像队列特别适用于以下场景:

  • 高可用性要求高的系统:如金融、医疗等行业,需要保证消息不丢失且系统持续可用。
  • 灾备系统:需要容灾功能,保证在某个节点宕机时,系统仍然可以正常运行。
  • 关键任务应用:不能容忍消息丢失的业务逻辑。
4. 优缺点

优点

  • 高可用性:在节点故障时,自动故障切换确保队列的持续可用性。
  • 数据冗余:消息会在多个节点上存储,有助于防止单点故障导致的数据丢失。

缺点

  • 性能开销:每条消息的操作都需要在多个节点间进行同步,可能会影响吞吐量和延迟。
  • 资源消耗:由于数据在多个节点间复制,需要更多的存储和网络资源。
  • 复杂性:配置和维护镜像队列相对复杂,特别是在集群规模较大时。
5. Java 示例

假设我们有一个需要镜像的队列,以下是使用 Java 和 Spring AMQP 创建并连接到一个镜像队列的示例。

import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.QueueBuilder;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RabbitConfig {

    @Bean
    public Queue mirroredQueue() {
        return QueueBuilder.durable("mirrored.queue")
                .withArgument("x-ha-policy", "all") // 配置为镜像队列
                .build();
    }

    @Bean
    public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
        return new RabbitTemplate(connectionFactory);
    }

    @Bean
    public RabbitAdmin rabbitAdmin(ConnectionFactory connectionFactory) {
        return new RabbitAdmin(connectionFactory);
    }
}

使用了 x-ha-policy 参数来配置队列为镜像队列

分布式部署

分布式部署意味着将 RabbitMQ 节点分布在不同的数据中心、地理位置或网络环境中。这种部署方式适用于需要跨多个地区或数据中心实现高可用性和容灾的场景。

1. 分布式部署的主要目标
  • 容灾:确保在一个数据中心或地理位置发生故障时,系统仍然能够正常运行。
  • 负载均衡:通过分布多个节点,均衡不同区域的请求负载。
  • 数据局部化:为不同区域的用户提供更低延迟的服务。
2. 典型架构设计

分布式部署通常包括以下几种架构模式:

  • 多集群架构:在不同的数据中心或地理位置各自运行一个独立的 RabbitMQ 集群,之间通过某种消息传递机制进行通信,如使用 ShovelFederation 插件。
  • 跨数据中心的集群:在不同的数据中心部署一个跨越数据中心的 RabbitMQ 集群,节点之间通过 WAN 网络进行同步。该方案适合低延迟且带宽足够的环境。
3. RabbitMQ 分布式部署的关键技术

3.1 Shovel 插件

Shovel 插件用于在两个不同的 RabbitMQ 实例或集群之间转发消息。它能有效地在跨网络的 RabbitMQ 实例之间传递消息。

示例配置

# 在 rabbit1 节点上安装并配置 Shovel 插件
rabbitmq-plugins enable rabbitmq_shovel
rabbitmq-plugins enable rabbitmq_shovel_management

# 创建 Shovel 配置
rabbitmqctl set_parameter shovel my-shovel \
    '{"src-uri": "amqp://user:pass@rabbit1/vhost", "src-queue": "queue1", "dest-uri": "amqp://user:pass@rabbit2/vhost", "dest-queue": "queue2"}'

Shovel 插件会从 queue1 拉取消息并转发到 queue2,实现不同 RabbitMQ 实例之间的消息传递。

3.2 Federation 插件

Federation 插件允许不同的 RabbitMQ 集群通过逻辑链接进行消息传递。与 Shovel 不同,Federation 更适合跨地理位置的集群之间建立动态连接。

示例配置

# 在 rabbit1 节点上启用 Federation 插件
rabbitmq-plugins enable rabbitmq_federation
rabbitmq-plugins enable rabbitmq_federation_management

# 配置 Federation Upstream
rabbitmqctl set_parameter federation-upstream my-upstream '{"uri":"amqp://user:pass@rabbit2/vhost"}'

# 配置 Federation Policy
rabbitmqctl set_policy my-federation ".*" \
    '{"federation-upstream-set":"all"}'

Federation 插件会将消息从一个集群传递到另一个集群。

4. 部署策略和实践

4.1 地理分布式集群

在每个主要地区或数据中心部署一个 RabbitMQ 集群,使用 Federation 或 Shovel 在这些集群之间转发消息。这种策略可以为每个地区的用户提供低延迟服务,并且在一个地区发生故障时,其他地区的服务不受影响。

4.2 多租户架构

在分布式部署中,可以通过虚拟主机(vhost)隔离不同租户的数据和操作。不同租户可以在不同的数据中心有各自的 RabbitMQ 集群,Shovel 或 Federation 可以实现租户数据的跨区域同步。

4.3 数据局部化

根据用户地理位置,将用户请求路由到最近的数据中心。使用分布式 RabbitMQ 结构可以有效减少延迟,提升用户体验。

5. 分布式部署的挑战和解决方案
  • 网络延迟:跨数据中心的通信会受到网络延迟的影响。解决方案包括在低延迟网络上部署节点,或使用本地缓存。
  • 数据一致性:保证跨节点或集群的数据一致性是一个挑战。可以通过消息的持久化和确认机制来减少不一致的风险。
  • 运维复杂性:分布式部署增加了运维的复杂性,需要更复杂的监控、报警和自动化工具来管理。

通过合理的架构设计和技术手段,可以有效地在不同网络环境下实现 RabbitMQ 的分布式部署,从而实现系统的高可用性、容灾和低延迟服务。

6.使用Docker Compose 实现分布式部署

在每个服务器上,创建一个 docker-compose.yml 文件,用于定义 RabbitMQ 服务的配置。假设我们有两台服务器 server1server2

Server 1 的 docker-compose.yml:

version: '3.7'
services:
  rabbitmq1:
    image: rabbitmq:3.12-management
    container_name: rabbitmq1
    hostname: rabbit1
    environment:
      - RABBITMQ_ERLANG_COOKIE=my_cookie
      - RABBITMQ_DEFAULT_USER=user
      - RABBITMQ_DEFAULT_PASS=password
    ports:
      - "15672:15672" # 管理界面
      - "5672:5672"   # AMQP 端口
    networks:
      - rabbitmq-network

networks:
  rabbitmq-network:
    driver: bridge

Server 2docker-compose.yml:

version: '3.7'
services:
  rabbitmq2:
    image: rabbitmq:3.12-management
    container_name: rabbitmq2
    hostname: rabbit2
    environment:
      - RABBITMQ_ERLANG_COOKIE=my_cookie
      - RABBITMQ_DEFAULT_USER=user
      - RABBITMQ_DEFAULT_PASS=password
    ports:
      - "15672:15672" # 管理界面
      - "5672:5672"   # AMQP 端口
    networks:
      - rabbitmq-network

networks:
  rabbitmq-network:
    driver: bridge

部署 RabbitMQ 实例

server1server2 上分别运行以下命令来启动 RabbitMQ 服务:

docker-compose up -d

这将在每个服务器上启动一个 RabbitMQ 实例。

4. 配置 Shovel 插件或 Federation 插件

接下来,使用 ShovelFederation 插件来连接这两个分布式的 RabbitMQ 实例。

使用 Shovel 插件配置消息传递

server1 上:

docker exec -it rabbitmq1 bash
rabbitmq-plugins enable rabbitmq_shovel
rabbitmq-plugins enable rabbitmq_shovel_management
rabbitmqctl set_parameter shovel my-shovel \
    '{"src-uri": "amqp://user:password@rabbit1/vhost", "src-queue": "queue1", "dest-uri": "amqp://user:password@rabbit2/vhost", "dest-queue": "queue2"}'

server2 上:

docker exec -it rabbitmq2 bash
rabbitmq-plugins enable rabbitmq_shovel
rabbitmq-plugins enable rabbitmq_shovel_management
rabbitmqctl set_parameter shovel my-shovel \
    '{"src-uri": "amqp://user:password@rabbit2/vhost", "src-queue": "queue2", "dest-uri": "amqp://user:password@rabbit1/vhost", "dest-queue": "queue1"}'

使用 Federation 插件配置消息传递

server1 上:

docker exec -it rabbitmq1 bash
rabbitmq-plugins enable rabbitmq_federation
rabbitmq-plugins enable rabbitmq_federation_management
rabbitmqctl set_parameter federation-upstream my-upstream \
    '{"uri":"amqp://user:password@rabbit2/vhost"}'
rabbitmqctl set_policy my-federation ".*" \
    '{"federation-upstream-set":"all"}'

 在 server2 上:

docker exec -it rabbitmq2 bash
rabbitmq-plugins enable rabbitmq_federation
rabbitmq-plugins enable rabbitmq_federation_management
rabbitmqctl set_parameter federation-upstream my-upstream \
    '{"uri":"amqp://user:password@rabbit1/vhost"}'
rabbitmqctl set_policy my-federation ".*" \
    '{"federation-upstream-set":"all"}'

总结

  • 单节点与集群部署:单节点适用于开发和测试环境,集群部署用于生产环境,提高了系统的可靠性和可扩展性。
  • 镜像队列:为关键业务场景提供高可用性,确保消息在节点故障时不会丢失。
  • 分布式架构:通过 Federation 和 Shovel 插件,RabbitMQ 可以在不同地理位置的集群间实现消息的传递,适用于复杂的分布式系统。

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

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

相关文章

图像变换——等距变换、相似变换、仿射变换、投影变换

%%图像变换 % I imread(cameraman.tif); I imread(F:\stitching\imagess\or\baiyun2.jpg); figure; imshow(I); title(原始图像); [w,h]size(I); thetapi/4;%旋转角 t[200,80];%平移tx,ty s0.3;%缩放尺度 %% 等距变换平移变换旋转变换 H_eprojective2d([cos(theta) sin(theta…

体育风尚杂志体育风尚杂志社体育风尚编辑部2024年第8期目录

体讯 体育产业“破圈” 3-7 成都大运会获2023年度最佳体育赛事媒体设施奖 8-10 斯巴达勇士赛 2024斯巴达勇士赛深圳站漫威主题赛在深圳光明欢乐田园揭幕 11-15 篮球 CBA季后赛 深圳马可波罗挺进季后赛八强 16-24 游泳 周六福2024年全国游泳冠军赛4月深圳激…

集成电路与电路基础之-二极管

二极管是什么 二极管,又称肖特基二极管或晶体二极管,是一种最基本的半导体器件之一。它由半导体材料(如硅、硒、锗等)制成,其内部结构是一个PN结,即由一个P型半导体区和一个N型半导体区组成。这种结构赋予…

【freeDiameter】服务端和客户端的连接流程

连接流程详解 进程启动时,先使用main_cmdline解析命令行参数,比如使用-c就会使用指定路径的配置文件,使用-d就会启用后台进程。 之后使用fd_core_initialize初始化核心库。具体会先使用fd_conf_init初始化配置,比如设置各项的默…

Android活动(activity)与服务(service)进行通信

文章目录 Android活动(activity)与服务(service)进行通信活动与服务进行通信服务的生命周期 Android活动(activity)与服务(service)进行通信 活动与服务进行通信 上一小节中我们学…

国产3A大作《黑神话:悟空》,各类MOD+修改器+皮肤等资源大合集(附安装教程)

《黑色神话:悟空》的引擎让你可以修改角色的伤害、防御和各种物资数量,大大降低了游戏的难度,让动作游戏的玩家更容易享受到体验。但是,请注意,使用作弊引擎会大大降低游戏体验,因此请明智地使用它&#xf…

各种探针卡介绍

探针卡(Probe Card)是一种在半导体测试过程中至关重要的设备,主要用于晶圆测试阶段,通过探针与芯片上的焊垫或凸块直接接触,完成测试信号的传输和反馈。探针卡的种类多样,各有其特点和应用场景。以下是几种常见的探针卡类型详细介绍: 1. 刀片探针卡(Blade Probe Card)…

<Rust>egui学习之小部件(五):如何在窗口中添加图像部件?

前言 本专栏是关于Rust的GUI库egui的部件讲解及应用实例分析,主要讲解egui的源代码、部件属性、如何应用。 环境配置 系统:windows 平台:visual studio code 语言:rust 库:egui、eframe 概述 本文是本专栏的第五篇博…

【Qt】垂直布局管理器QVBoxLayout

垂直布局管理器QVBoxLayout 在之前学习Qt的过程中,将控件放在界面上,都是依靠“手动”的方式来布局的,但是手动调整的方式是不科学的。 手动布局的方式非常复杂,而且不精确无法对窗口大小进行自适应 因此Qt引入布局管理器来解决…

2-79 基于matlab的卷积稀疏的形态成分分析的医学图像融合

基于matlab的卷积稀疏的形态成分分析的医学图像融合,基于卷积稀疏性的形态分量分析 (CS-MCA) 的稀疏表示 (SR) 模型,用于像素级医学图像融合。通过 CS-MCA 模型使用预先学习的字典获得其卡通和纹理组件的 CSR。然后,合并所有源图像的稀疏系数…

13-springcloud gateway集成nacos实现负载均衡

网关作为访问系统的入口,负载均衡是必选项而不是可选项,本文介绍gateway与nacos集成,实现负载均衡的过程。关于springcloud gateway的基本用法,同学可以看看上篇文章: 12-使用gateway作为网关。 0、环境 jdk:1.8spri…

【GIT】idea中实用的git操作,撤回commit,撤回push、暂存区使用

IDEA中最常见的UI操作:【GIT】Idea中的git命令使用-全网最新详细(包括现象含义) 文章目录 问题一: idea撤回仅commit错误的代码(仅本地仓库,因为还没推送到远程)问题二: idea撤回Com…

【提示学习论文】CoCoLe:Conceptual Codebook Learning for Vision-Language Models

Conceptual Codebook Learning for Vision-Language Models(ECCV 2024) CPL的改进暂无代码 CPL 详见CPL论文 CoCoLe a:手工概念缓存的建立过程b:制作提示的过程,将图像输入Ev,得到image features v 作…

【C++ Primer Plus习题】6.4

问题: 解答: #include <iostream> using namespace std;const int strsize 40; const int usersize 40;typedef struct _Bop {char fullname[strsize];char title[strsize];char bopname[strsize];int preference; }Bop;Bop bop_user[usersize] {{"Wimp Macho&q…

SpringBoot多环境日志配置

SpringBoot 默认使用 LogBack 日志系统 默认情况下&#xff0c;SpringBoot项目的日志只会在控制台输入。 如果想查询历史日志则无法找到&#xff0c;我们需要一个日志系统来统一管理日志。 一般正式项目会有单独日志系统&#xff0c;将日志操作存入数据库。 第一种方式是 在 ap…

如何理解select(1)、select(*)、select(column)背后的差异?

先说结论 select&#xff08;1&#xff09;、select&#xff08;*&#xff09;都是基于结果集进行的行数统计&#xff0c;统计到NULL行select&#xff08;column&#xff09;则受到索引设置的影响&#xff0c;默认会排除掉NULL行 在数据库查询中&#xff0c;SELECT语句用于从数…

第 7 章 B+树索引的使用

7.1 索引的代价 空间上的代价 每建立一个索引都要为它建立一棵B树&#xff0c;B树的每一个节点都是一个数据页&#xff0c;一个页默认占用16KB的空间。 时间上的代价 每次对表中的数据进行增、删、改操作时&#xff0c;都需要去修改各个B树索引。 一个表上的索引越多&#x…

从零上手CV竞赛Task2 # Datawhale AI夏令营

文章目录 平台参赛平台云平台 Task 1 从零上手CV竞赛下载baseline相关文件一键运行baseline&#xff01;&#xff08;大约需要25分钟&#xff09;赛题解析数据集提交结果违法标准注意事项 下载生成的文件结果如图最后要记得关机 不然一直消耗算力 Task 2 建模方案解读与进阶物体…

光性能 -- OMA(光调制幅度)

基本概念 OMA&#xff08;Optical Modulation Amplitude&#xff09;&#xff1a;光调制幅度&#xff0c;是光信号测试中的一项指标。是指光模块接收到的信号”1”的光功率和信号“0”的光功率的差值。即&#xff1a; Pavg&#xff08;average optical power&#xff09;&#…

WxPython可视化编辑器

作者&#xff1a;陈炳强 WxPython是python的一个用来写桌面程序的模块,目前只写了小部分功能跟组件, 用Python写中文&#xff0c;非常方便&#xff01; 下载地址&#xff1a;https://pan.quark.cn/s/ba19b2472246