当前位置: 首页 > news >正文

MessageQueue --- RabbitMQ

MessageQueue --- RabbitMQ

  • RabbitMQ Intro
  • RabbitMQ 核心概念
  • RabbitMQ 分发类型
  • Dead letter (死信)
  • 保证消息的可靠传递

RabbitMQ Intro

  • 2007年发布,是一个在AMQP(高级消息队列协议)基础上完成的,可复用的企业消息系统,是当前最主流的消息中间件之一。
  • 低延迟:RabbitMQ 提供了低延迟的消息传递,可以在毫秒级别内将消息从生产者传递到消费者。
  • 高吞吐量:RabbitMQ 能够处理大量的消息并实现高吞吐量。它使用多线程和预取机制来提高消息处理的效率。
  • 可扩展性:RabbitMQ 可以通过水平扩展来处理更多的消息流量。可以通过添加更多的节点、使用集群和队列分区等方式来扩展 RabbitMQ。
  • 持久化支持:RabbitMQ 支持将消息和队列持久化到磁盘,以确保消息的可靠性和持久性。这意味着即使在 RabbitMQ 重启后,消息仍然可以保留,不会丢失。
  • 多种消息传递模式:RabbitMQ 支持多种消息传递模式,如点对点、发布/订阅和请求/响应等。这使得 RabbitMQ 在各种场景下都能够灵活应用。
  • 负载均衡:RabbitMQ 提供了负载均衡机制,可以将消息均衡地分发给多个消费者,以实现更好的资源利用和处理能力。
  • 可靠性保证:通过使用确认机制、持久化和事务等特性,RabbitMQ 提供了可靠性保证,确保消息的可靠传递和处理。

RabbitMQ 核心概念

在这里插入图片描述
消息的路由过程如下:

  • 生产者发布消息时,将消息和指定的 Routing Key 一起发送到交换机。
  • 交换机根据 Binding Key 和 Routing Key 的匹配规则,将消息路由到一个或多个绑定的队列。
  • 绑定 Key 和 Routing Key 的匹配规则可以根据交换机的类型而有所不同。
  • 在直接交换机(Direct Exchange)中,Binding Key 必须与 Routing Key 完全匹配。
  • 在主题交换机(Topic Exchange)中,Binding Key 与 Routing Key 使用通配符进行模式匹配。
  • 在扇形交换机(Fanout Exchange)中,Binding Key 不起作用,消息会被广播到所有绑定的队列。
  • Routing Key(路由键):
  • Routing Key 是在消息发布时与消息一起发送的属性。
  • 在发布消息时,生产者可以指定一个 Routing Key,用于描述消息的特性或目标。
  • Routing Key 可以是任意的字符串,通常是由一些特定的标识符或关键词组成,以便用于消息的过滤和路由。
  • Binding Key(绑定键):
  • Binding Key 是用于绑定队列和交换机的属性。
  • 在 RabbitMQ 中,通过创建绑定(Binding)将队列和交换机关联起来,以便消息能够正确地路由到队列。
  • 绑定是基于 Binding Key 进行的,它定义了交换机将消息路由到哪些队列。
  • Binding Key 可以是一个或多个单词组成的字符串,也可以是符号“#”和“*”的组合,用于匹配 Routing Key。

名词解释:

  • 生产者(Producer):发送消息的应用。
  • 消费者(Consumer):接收消息的应用。
  • 队列(Queue):存储消息的缓存。
  • 消息(Message):由生产者通过RabbitMQ发送给消费者的信息。
  • 连接(Connection):连接RabbitMQ和应用服务器的TCP连接。
  • 信道(Channel):连接里的一个虚拟通道,通过消息队列发送或者接收消息时,都是通过信道进行的。
  • 交换机(Exchange):交换机负责从生产者那里接收消息,并根据交换类型分发到对应的消息队列里。
  • 代理(Broker):接收和分发消息的应用,RabbitMQ Server就是Message Broker。
  • 虚拟主机(Virtual host):出于多租户和安全因素设计的,把AMQP的基本组件划分到一个虚拟的分组中,类似于网络中的namespace概念。当多个不同的用户使用同一个RabbitMQ server提供的服务时,可以划分出多个vhost,每个用户在自己的vhost创建exchange/queue 等.
  • Example:每个环境配置一个virtual host

RabbitMQ 分发类型

Direct Exchange

  • Direct exchange使用完全匹配的方式进行消息路由
  • 当一个消息发送到Direct exchange时,它会将消息的路由键与绑定到交换机上的队列的绑定键(binding key)进行比较。如果路由键与某个队列的绑定键完全匹配,那么该消息将被路由到该队列

在这里插入图片描述

  • exchange :pdf_events
    Queue A:create_pdf_queue
    交换机(pdf_events)和队列 A(create_pdf_queue)之间的绑定键:pdf_create
  • exchange :pdf_events
    Queue B:pdf_log_queue
    交换机(pdf_events)和队列 B(pdf_log_queue)之间的绑定键:pdf_log
  • 示例:
  • 例如,一个带有routing key为 pdf_log 的消息被发送到交换机 pdf_events
  • 该消息会被路由到 pdf_log_queue,因为routing key(pdf_log)与binding key(pdf_log)匹配
  • 如果消息的路由键与任何绑定键都不匹配,那么该消息将被丢弃。

Topic Exchange

  • 在 Topic Exchange 中,消息的路由键和绑定键都使用通配符来进行匹配。路由键是消息的属性,而绑定键是在创建绑定时指定的。通配符可以帮助实现更灵活的消息路由,使得消息可以根据特定的模式进行匹配和分发。
  • 通配符符号:
  • *(星号):表示匹配一个单词(单词由点号分隔)
  • #(井号):表示匹配零个或多个单词(单词由点号分隔)

在这里插入图片描述

  • Consumer A is interested in all the agreements in Berlin.
  • Exchange: agreements
  • Queue A name: berlin_agreements
  • Binding key: agreements.eu.berlin.#
  • Example of message routing key that matches:
  • agreements.eu.berlin
  • agreements.eu.berlin.store
  • Consumer B is interested in all the agreements.
  • Exchange: agreements
  • Queue B name: all_agreements
  • Binding key: agreements.#
  • Example of message routing key that matches:
  • agreements.eu.berlin
  • agreements.us
  • Consumer C is interested in all agreements for European head stores.
  • Exchange: agreements
  • Queue C name: store_agreements
  • binding key: agreements.eu.*.store
  • Example of message routing keys that will match:
  • agreements.eu.berlin.store
  • agreements.eu.stockholm.store

Fanout exchange

  • Fanout Exchange(广播交换机)是 RabbitMQ 中的一种交换机类型。它的工作原理是将消息广播到与之绑定的所有队列,无论绑定键的匹配情况如何。
  • Fanout Exchange 不关心消息的路由键,它会简单地将收到的消息复制并发送到所有与之绑定的队列

在这里插入图片描述

Header exchange

  • Header Exchange(头交换机)是 RabbitMQ 中的一种交换机类型。它使用消息的头部属性(Header)来匹配与之绑定的队列,而不依赖于路由键或绑定键。
  • 在 Header Exchange 中,消息的头部属性是消息的一部分,它包含了一组键值对,用于描述消息的特征和属性。与其他类型的交换机不同,Header Exchange 不关心消息的路由键,而是根据消息头部属性的匹配情况来确定消息的路由。
  • 绑定到 Header Exchange 的队列可以定义一个或多个匹配规则,这些规则由键值对的匹配条件组成。当消息的头部属性与队列的匹配规则完全匹配时,消息会被路由到对应的队列。

在这里插入图片描述

  • Message 1 is published to the exchange with header arguments (key = value): “format = pdf”, “type = report”.
  • Message 1 is delivered to Queue A because all key/value pairs match, and Queue B since “format = pdf” is a match (binding rule set to “x-match =any”).
  • Message 2 is published to the exchange with header arguments of (key = value): “format = pdf”.
  • Message 2 is only delivered to Queue B. Because the binding of Queue A requires both “format = pdf” and “type = report” while Queue B is configured to match any key-value pair (x-match = any) as long as either “format = pdf” or “type = log” is present.
  • Message 3 is published to the exchange with header arguments of (key = value): “format = zip”, “type = log”.
  • Message 3 is delivered to Queue B since its binding indicates that it accepts messages with the key-value pair “type = log”, it doesn’t mind that “format = zip” since “x-match = any”.
  • Queue C doesn’t receive any of the messages since its binding is configured to match all of the headers (“x-match = all”) with “format = zip”, “type = pdf”. No message in this example lives up to these criterias.
  • It’s worth noting that in a header exchange, the actual order of the key-value pairs in the message is irrelevant.

配置RabbitMQ 示例代码

import com.rabbitmq.client.*;import java.io.IOException;
import java.nio.charset.StandardCharsets;public class DirectExchangeExample {private static final String EXCHANGE_NAME = "direct_logs";private static final String QUEUE_NAME = "my_queue";private static final String ROUTING_KEY = "info";public static void main(String[] args) throws Exception {ConnectionFactory factory = new ConnectionFactory();factory.setHost("localhost");try (Connection connection = factory.newConnection();Channel channel = connection.createChannel()) {// 声明一个 Direct Exchangechannel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.DIRECT);// 声明一个队列channel.queueDeclare(QUEUE_NAME, false, false, false, null);// 绑定队列到 Direct Exchange,并指定绑定键channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, ROUTING_KEY);// 定义消息处理函数DeliverCallback deliverCallback = (consumerTag, delivery) -> {String message = new String(delivery.getBody(), StandardCharsets.UTF_8);System.out.println("Received message: " + message);};// 消费消息channel.basicConsume(QUEUE_NAME, true, deliverCallback, consumerTag -> {});System.out.println("Press any key to exit.");System.in.read();}}
}

Dead letter (死信)

  • 死信(Dead Letter)是指在消息队列中无法被正常消费和处理的消息。当消息满足一定的条件时,它们可以被标记为死信并被发送到专门的死信队列中,以便进一步处理或分析
  • 死信来源
  • 消息 TTL 过期
  • 队列达到最大长度(队列满了,无法再添加数据到 mq 中)
  • 消息被拒绝(basic.reject 或 basic.nack)并且 requeue=false(不再重新入队)
  • 死信队列(Dead Letter Queue)是一个特殊的队列,用于接收死信消息。一旦消息被发送到死信队列,就可以根据需要进行进一步的处理,例如重新投递、持久化、记录日志或者进行分析。
  • 使用死信机制的好处包括:
  • 错误处理:当消息无法被正常处理时,可以将其发送到死信队列,以便进一步处理错误情况,例如记录日志或者通知管理员。
  • 重试机制:如果消息在一定时间内未能被消费成功,可以将其发送到死信队列,并设置重试策略,例如延时重试或者指数退避重试。
  • 延迟消息:通过结合延迟队列和死信队列,可以实现延迟消息的功能。当消息的延迟时间到达时,将其发送到死信队列,然后再从死信队列中重新投递到目标队列,实现延迟消息的效果。

在这里插入图片描述

import com.rabbitmq.client.*;import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;public class DeadLetterExample {private static final String EXCHANGE_NAME = "normal_exchange";private static final String QUEUE_NAME = "normal_queue";private static final String DLX_EXCHANGE_NAME = "dlx_exchange";private static final String DLX_QUEUE_NAME = "dlx_queue";private static final String DLX_ROUTING_KEY = "dlx_routing_key";public static void main(String[] args) throws Exception {ConnectionFactory factory = new ConnectionFactory();factory.setHost("localhost");try (Connection connection = factory.newConnection();Channel channel = connection.createChannel()) {// 创建普通交换机和队列channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.DIRECT);channel.queueDeclare(QUEUE_NAME, false, false, false, null);channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "");// 创建死信交换机和队列channel.exchangeDeclare(DLX_EXCHANGE_NAME, BuiltinExchangeType.DIRECT);channel.queueDeclare(DLX_QUEUE_NAME, false, false, false, null);channel.queueBind(DLX_QUEUE_NAME, DLX_EXCHANGE_NAME, DLX_ROUTING_KEY);// 设置普通队列的死信参数Map<String, Object> arguments = new HashMap<>();arguments.put("x-dead-letter-exchange", DLX_EXCHANGE_NAME);arguments.put("x-dead-letter-routing-key", DLX_ROUTING_KEY);channel.queueDeclare(QUEUE_NAME, false, false, false, arguments);// 定义消息处理函数DeliverCallback deliverCallback = (consumerTag, delivery) -> {String message = new String(delivery.getBody(), StandardCharsets.UTF_8);System.out.println("Received message: " + message);// 手动确认消息channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);};// 消费消息channel.basicConsume(QUEUE_NAME, false, deliverCallback, consumerTag -> {});System.out.println("Press any key to exit.");System.in.read();}}
}

保证消息的可靠传递

要确保消息的可靠传递,可以采取以下几个步骤:

  • 持久化消息:将消息和队列都设置为持久化。这样,在 RabbitMQ 重启后,持久化的队列和消息会被恢复,避免消息丢失。可以在消息的发布端设置消息的持久化属性,以及在队列声明时设置队列的持久化属性。
  • 使用确认机制(Acknowledgement):在消费者处理消息后,发送确认消息给 RabbitMQ,告知消息已经成功处理。RabbitMQ 收到确认后才会将消息从队列中删除,确保消息不会丢失。确认机制可以通过在消费者端手动发送确认消息(basicAck)或使用自动确认模式(autoAck)来实现。
  • 使用发布者确认(Publisher Confirms):在消息的发布端启用发布者确认模式。通过将 confirm.select 设置为 true,可以让发布者等待 RabbitMQ 发送确认消息,表示消息已经成功到达交换机。如果没有收到确认消息,发布者可以选择重新发送消息,确保消息的可靠传递。
  • 设置合适的消息 TTL(Time-to-Live):可以为消息设置 TTL,即消息的存活时间。如果消息在指定的时间内没有被消费,RabbitMQ 可以将其标记为过期并进行相应的处理,例如发送到死信队列或丢弃。
  • 使用事务(Transactions):可以通过开启事务来确保消息的可靠传递。在事务中,可以将消息的发布和确认操作包裹在一个事务中,如果事务提交成功,表示消息已经成功到达 RabbitMQ,否则可以进行回滚。
  • 备份交换机(Alternate Exchange):可以配置备份交换机,当消息无法路由到指定的交换机时,它将被发送到备份交换机,从而避免消息丢失。
  • 监控和错误处理:建立监控机制,定期检查消息队列的状态,以及消费者的消费情况。在出现错误或异常情况时,根据具体情况进行错误处理,例如重试发送消息、记录日志、发送警报等。

发布者确认机制Example

import com.rabbitmq.client.*;import java.io.IOException;
import java.util.concurrent.TimeoutException;public class ReliableMessagingExample {private static final String QUEUE_NAME = "my_queue";private static final String EXCHANGE_NAME = "my_exchange";private static final String ROUTING_KEY = "my_routing_key";public static void main(String[] args) throws IOException, TimeoutException {// 创建连接和信道ConnectionFactory factory = new ConnectionFactory();factory.setHost("localhost");Connection connection = factory.newConnection();Channel channel = connection.createChannel();// 声明队列和交换机channel.queueDeclare(QUEUE_NAME, true, false, false, null);channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.DIRECT);channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, ROUTING_KEY);// 启用发布者确认模式channel.confirmSelect();// 添加发布者确认监听器channel.addConfirmListener(new ConfirmListener() {@Overridepublic void handleAck(long deliveryTag, boolean multiple) throws IOException {System.out.println("Message confirmed, delivery tag: " + deliveryTag);}@Overridepublic void handleNack(long deliveryTag, boolean multiple) throws IOException {System.out.println("Message not confirmed, delivery tag: " + deliveryTag);// 可以在这里进行相应的处理,例如重新发送消息}});// 发布消息String message = "Hello, RabbitMQ!";channel.basicPublish(EXCHANGE_NAME, ROUTING_KEY, MessageProperties.PERSISTENT_TEXT_PLAIN, message.getBytes());try {// 等待发布者确认channel.waitForConfirmsOrDie();} catch (InterruptedException e) {// 可以在这里进行相应的处理,例如重新发送消息e.printStackTrace();}// 关闭信道和连接channel.close();connection.close();}
}

事务保证消息可靠性Example

import com.rabbitmq.client.*;import java.io.IOException;
import java.util.concurrent.TimeoutException;public class ReliableMessagingExample {private static final String QUEUE_NAME = "my_queue";private static final String EXCHANGE_NAME = "my_exchange";private static final String ROUTING_KEY = "my_routing_key";public static void main(String[] args) throws IOException, TimeoutException {// 创建连接和信道ConnectionFactory factory = new ConnectionFactory();factory.setHost("localhost");Connection connection = factory.newConnection();Channel channel = connection.createChannel();try {// 开启事务channel.txSelect();// 声明队列和交换机channel.queueDeclare(QUEUE_NAME, true, false, false, null);channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.DIRECT);channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, ROUTING_KEY);// 发布消息String message = "Hello, RabbitMQ!";channel.basicPublish(EXCHANGE_NAME, ROUTING_KEY, MessageProperties.PERSISTENT_TEXT_PLAIN, message.getBytes());// 提交事务channel.txCommit();System.out.println("Transaction committed successfully.");} catch (IOException e) {// 发生异常,回滚事务channel.txRollback();System.out.println("Transaction rolled back due to an exception.");e.printStackTrace();} finally {// 关闭信道和连接channel.close();connection.close();}}
}

相关文章:

MessageQueue --- RabbitMQ

MessageQueue --- RabbitMQ RabbitMQ IntroRabbitMQ 核心概念RabbitMQ 分发类型Dead letter (死信)保证消息的可靠传递 RabbitMQ Intro 2007年发布&#xff0c;是一个在AMQP&#xff08;高级消息队列协议&#xff09;基础上完成的&#xff0c;可复用的企业消息系统&#xff0c;…...

WordPress作者页面链接的用户名自动变成16位字符串串插件Smart User Slug Hider

WordPress默认的作者页面URL链接地址格式为“你的域名/author/admin”&#xff0c;其中admin就是你的用户名&#xff0c;这样的话就会暴露我们的用户名。 为了解决这个问题&#xff0c;前面boke112百科跟大家分享了『如何将WordPress作者存档链接中的用户名改为昵称或ID』一文…...

Nvidia 携手 RTX 推出的本地运行 AI 聊天机器人

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…...

年假作业day2

1.打印字母图形 #include<stdio.h> #include<string.h> int main(int argc, const char *argv[]) { int i,j; char k; for(i1;i<7;i) { for(j1;j<i;j) { printf("%c",_); } for(j0,…...

HTML-多媒体嵌入-MDN文档学习笔记

HTML-多媒体与嵌入 查看更多学习笔记&#xff1a;GitHub&#xff1a;LoveEmiliaForever MDN中文官网 HTML-中的图片 将图片放入网页 可以使用<img/>来将图片嵌入网页&#xff0c;它是一个空元素&#xff0c;最少只需src属性即可工作 <img src"图片链接"…...

openJudge | 距离排序 C语言

总时间限制: 1000ms 内存限制: 65536kB 描述 给出三维空间中的n个点&#xff08;不超过10个&#xff09;,求出n个点两两之间的距离,并按距离由大到小依次输出两个点的坐标及它们之间的距离。 输入 输入包括两行&#xff0c;第一行包含一个整数n表示点的个数&#xff0c;第二…...

【教程】MySQL数据库学习笔记(三)——数据定义语言DDL(持续更新)

写在前面&#xff1a; 如果文章对你有帮助&#xff0c;记得点赞关注加收藏一波&#xff0c;利于以后需要的时候复习&#xff0c;多谢支持&#xff01; 【MySQL数据库学习】系列文章 第一章 《认识与环境搭建》 第二章 《数据类型》 第三章 《数据定义语言DDL》 文章目录 【MyS…...

[leetcode]买卖股票的最佳时机 (动态规划)

121. 买卖股票的最佳时机 给定一个数组 prices &#xff0c;它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。 你只能选择 某一天 买入这只股票&#xff0c;并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。 返回你可以从…...

隐函数的求导【高数笔记】

1. 什么是隐函数&#xff1f; 2. 隐函数的做题步骤&#xff1f; 3. 隐函数中的复合函数求解法&#xff0c;与求导中复合函数求解法有什么不同&#xff1f; 4. 隐函数求导的过程中需要注意什么&#xff1f;...

SG3225EEN晶体振荡器规格书

SG3225EEN 晶振是EPSON/爱普生的一款额定频率25 MHz至500 MHz的石英晶体振荡器&#xff0c;6脚贴片&#xff0c;LV-PECL输出&#xff0c;3225封装常规有源晶振&#xff0c;具有小尺寸&#xff0c;轻薄型&#xff0c;高稳定性&#xff0c;低相位抖动&#xff0c;低电源电压&…...

ESP8266 常用AT指令

一、ESP8266的AT指令要点、常见错误 AT指令要大写;以"\r\n"作结尾;串口通信&#xff0c;115200-None-8-1;支持2.4G频段&#xff0c;不支持5G频段 &#xff08;如果用手机创建热点&#xff0c;注意选择2.4G&#xff09;不支持中文的wifi名称工作模式&#xff0c;上电…...

esbuild 构建工具为什么很快?

esbuild 构建工具之所以很快&#xff0c;主要有以下几个原因&#xff1a; Go语言编写&#xff1a;esbuild 是用 Go 语言编写的&#xff0c;Go 语言以其高效的并发模型和编译速度而闻名。与一些其他构建工具相比&#xff0c;Go 语言在并发处理和内存管理方面表现出色&#xff0c…...

解决vscode报错,在赋值前使用了变量“XXX“

问题&#xff1a;如图所示 解决方法&#xff1a; 法一&#xff1a; 补全函数使其完整 法二&#xff1a; 使用断言...

python自动定时任务schedule库的使用方法

当你需要在 Python 中定期执行任务时&#xff0c;schedule 库是一个非常实用的工具。它可以帮助你自动化定时任务。以下是一些使用示例&#xff1a; 基本使用&#xff1a; import schedule import timedef job():print("Im working...")schedule.every(10).minutes.d…...

用机器学习方法重构期货商品板块

用机器学习方法重构期货商品板块 阿岛格 参考专栏:低门槛搭建个人量化平台 https://www.zhihu.com/column/c_1441014235068944386 摘 要 金融市场商品期货的板块分类,通常根据不同交易所、监管机构和证券商标准,按照期货标的属性、或产业链关系等进行分类,各自分类略有差…...

51单片机项目(29)——基于51单片机的避障跟随小车

1.功能设计 按键模式&#xff1a;按下按键&#xff0c;小车可以前后左右地运动 自动模式&#xff1a;根据红外传感器的状态&#xff0c;自行决定运动状态。检测到前方有物体时&#xff0c;车子移动&#xff0c;起到一个跟随的效果。 演示视频如下&#xff1a; 51单片机智能避障…...

人工智能学习与实训笔记(六):百度飞桨套件使用方法

目录 八、百度飞桨套件使用 8.1 飞桨预训练模型套件PaddleHub 8.1.1 一些本机CPU可运行的飞桨预训练简单模型&#xff08;亲测可用&#xff09; 8.1.1.1 人脸检测模型 8.1.1.2 中文分词模型 8.1.2 预训练模型Fine-tune 8.2 飞桨开发套件 8.2.1 PaddleSeg - 图像分割 8…...

Linux第一个小程序-进度条

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言 一、回车和换行 二、行缓冲区概念 三、倒计时 四、进度条代码 版本一&#xff1a; ​编辑 版本二&#xff1a; 总结 前言 世上有两种耀眼的光芒&#xff0c;一…...

YoloV8改进策略:Block改进|Mamba-UNet改进YoloV8,打造全新的Yolo-Mamba网络

摘要 本文尝试使用Mamba的VSSBlock替换YoloV8的Bottleneck,打造最新的Yolo-Mamba网络。 论文:《Mamba-UNet:用于医学图像分割的类似UNet的纯视觉Mamba网络》 在医学图像分析的最新进展中,卷积神经网络(CNN)和视觉转换器(ViT)都取得了显著的基准成绩。前者通过其卷积…...

数据分析基础之《pandas(8)—综合案例》

一、需求 1、现在我们有一组从2006年到2016年1000部最流行的电影数据 数据来源&#xff1a;https://www.kaggle.com/damianpanek/sunday-eda/data 2、问题1 想知道这些电影数据中评分的平均分&#xff0c;导演的人数等信息&#xff0c;我们应该怎么获取&#xff1f; 3、问题…...

(17)Hive ——MR任务的map与reduce个数由什么决定?

一、MapTask的数量由什么决定&#xff1f; MapTask的数量由以下参数决定 文件个数文件大小blocksize 一般而言&#xff0c;对于每一个输入的文件会有一个map split&#xff0c;每一个分片会开启一个map任务&#xff0c;很容易导致小文件问题&#xff08;如果不进行小文件合并&…...

define和typedef

目录 一、define 二、typedef 三、二者之间的区别 一、define 在我们写代码的日常中&#xff0c;经常会用到define去配合数组的定义使用 #define N 10 arr[N]{0}; define不仅仅能做这些 #define是一种宏&#xff0c;我们首先来了解一下宏定义。 宏定义一般作用在C语言的预…...

SpringCloud之Nacos用法笔记

SpringCloud之Nacos注册中心 Nacos注册中心nacos启动服务注册到Nacosnacos服务分级模型NacosRule负载均衡策略根据集群负载均衡加权负载均衡Nacos环境隔离-namespace Nacos与eureka的对比临时实例与非临时实例设置 Nacos配置管理统一配置管理微服务配置拉取配置自动刷新远端配置…...

【c++】拷贝构造函数

1.特征 1.拷贝构造函数是构造函数的一个重载形式。 2.若显示定义了拷贝构造函数&#xff0c;编译器就不会自动生成构造函数了。 3.拷贝构造函数的参数只有一个且必须是类型对象的引用&#xff0c;使用传值方式编译器直接报错&#xff0c;因为会引发无穷递归调用。 4.若未显…...

17.3.1.2 曝光

版权声明&#xff1a;本文为博主原创文章&#xff0c;转载请在显著位置标明本文出处以及作者网名&#xff0c;未经作者允许不得用于商业目的。 基本算法&#xff1a;先定义一个阈值&#xff0c;通常取得是128 原图像&#xff1a;颜色值color&#xff08;R&#xff0c;G&#…...

【Win10 触摸板】在插入鼠标时禁用触摸板,并在没有鼠标时自动启用触摸板。取消勾选连接鼠标时让触摸板保持打开状态,但拔掉鼠标后触摸板依旧不能使用

出现这种问题我的第一反应就是触摸板坏了&#xff0c;但是无意间我换了一个账户发现触摸板可以用&#xff0c;因此推断触摸板没有坏&#xff0c;是之前的账户问题&#xff0c;跟系统也没有关系&#xff0c;不需要重装系统。 解决办法&#xff1a;与鼠标虚拟设备有关 然后又从知…...

排序算法---桶排序

原创不易&#xff0c;转载请注明出处。欢迎点赞收藏~ 桶排序&#xff08;Bucket Sort&#xff09;是一种排序算法&#xff0c;它将待排序的数据分到几个有序的桶中&#xff0c;每个桶再分别进行排序&#xff0c;最后将各个桶中的数据按照顺序依次取出&#xff0c;即可得到有序序…...

FPGA_工程_基于rom的vga显示

一 框图 二 代码修改 module Display #(parameter H_DISP 1280,parameter V_DISP 1024,parameter H_lcd 12d150,parameter V_lcd 12d150,parameter LCD_SIZE 15d10_000 ) ( input wire clk, input wire rst_n, input wire [11:0] lcd_xpos, //lcd horizontal coo…...

代码随想录算法训练营第31天|● 理论基础 ● 455.分发饼干 ● 376. 摆动序列 ● 53. 最大子序和

文章目录 理论基础分发饼干思路&#xff1a;代码&#xff1a; 摆动序列思路一 贪心算法&#xff1a;代码&#xff1a; 思路二&#xff1a;动态规划&#xff08;想不清楚&#xff09;代码&#xff1a; 最大子序和思路&#xff1a;代码&#xff1a; 理论基础 贪心算法其实就是没…...

无人机地面站技术,无人机地面站理论基础详解

地面站作为整个无人机系统的作战指挥中心&#xff0c;其控制内容包括:飞行器的飞行过程&#xff0c;飞行航迹&#xff0c; 有效载荷的任务功能&#xff0c;通讯链路的正常工作&#xff0c;以及 飞行器的发射和回收。 无人机地面站总述 地面站作为整个无人机系统的作战指挥中心…...

2024.2.13

21.C 22.D 23.B 5先出栈表示1&#xff0c;2&#xff0c;3&#xff0c;4已经入栈了&#xff0c;5出后4出&#xff0c;但之后想出1得先让3&#xff0c;2先后出栈&#xff0c;所以 B 不可能 24.10&#xff0c;12&#xff0c;120 25.2&#xff0c;5 26.可能会出现段错误…...

论文阅读:四足机器人对抗运动先验学习稳健和敏捷的行走

论文&#xff1a;Learning Robust and Agile Legged Locomotion Using Adversarial Motion Priors 进一步学习&#xff1a;AMP&#xff0c;baseline方法&#xff0c;TO 摘要&#xff1a; 介绍了一种新颖的系统&#xff0c;通过使用对抗性运动先验 (AMP) 使四足机器人在复杂地…...

.NET Core WebAPI中封装Swagger配置

一、创建相关文件 创建一个Utility/SwaggerExt文件夹&#xff0c;添加一个类 二、在Program中找到Swagger相关配置信息 三、添加方法&#xff0c;在Program中调用 在SwaggerExt类中添加方法&#xff0c;将相关配置添写入 /// <summary> /// swagger配置 /// </sum…...

28. 找出字符串中第一个匹配项的下标

Problem: 28. 找出字符串中第一个匹配项的下标 文章目录 思路解题方法复杂度Code 思路 这个问题可以通过使用KMP&#xff08;Knuth-Morris-Pratt&#xff09;算法来解决。KMP算法是一种改进的字符串匹配算法&#xff0c;它的主要思想是当子串与目标字符串不匹配时&#xff0c;能…...

宿舍|学生宿舍管理小程序|基于微信小程序的学生宿舍管理系统设计与实现(源码+数据库+文档)

学生宿舍管理小程序目录 目录 基于微信小程序的学生宿舍管理系统设计与实现 一、前言 二、系统功能设计 三、系统实现 1、管理员模块的实现 &#xff08;1&#xff09;学生信息管理 &#xff08;2&#xff09;公告信息管理 &#xff08;3&#xff09;宿舍信息管理 &am…...

CVE-2022-25487 漏洞复现

漏洞描述&#xff1a;Atom CMS 2.0版本存在远程代码执行漏洞&#xff0c;该漏洞源于/admin/uploads.php 未能正确过滤构造代码段的特殊元素。攻击者可利用该漏洞导致任意代码执行。 其实这就是一个文件上传漏洞罢了。。。。 打开之后&#xff0c;/home路由是个空白 信息搜集&…...

C#面:强类型和弱类型

强类型 强类型是指在编程语言中&#xff0c;变量必须明确声明其数据类型&#xff0c;并且在编译时会进行类型检查的特性。它可以提高代码的可读性和可维护性&#xff0c;但有时需要显式地进行类型转换。换句话说&#xff0c;强类型语言要求变量的类型在编译时就要确定&#xf…...

nodejs和npm和vite

Nodejs 简单的说 Node.js 就是运行在服务端的 JavaScript。 Node.js 是一个基于 Chrome JavaScript 运行时建立的一个平台。 Node.js 是一个事件驱动 I/O 服务端 JavaScript 环境 用途&#xff1a; Node.js 可以被看作是一个 JavaScript 运行时环境&#xff0c;专门用于在服务…...

相机图像质量研究(24)常见问题总结:CMOS期间对成像的影响--摩尔纹

系列文章目录 相机图像质量研究(1)Camera成像流程介绍 相机图像质量研究(2)ISP专用平台调优介绍 相机图像质量研究(3)图像质量测试介绍 相机图像质量研究(4)常见问题总结&#xff1a;光学结构对成像的影响--焦距 相机图像质量研究(5)常见问题总结&#xff1a;光学结构对成…...

Redis -- 数据库管理

目录 前言 切换数据库(select) 数据库中key的数量&#xff08;dbsize&#xff09; 清除数据库&#xff08;flushall flushdb&#xff09; 前言 MySQL有一个很重要的概念&#xff0c;那就是数据库database&#xff0c;一个MySQL里面有很多个database&#xff0c;一个datab…...

蓝桥杯(Web大学组)2023省赛真题:视频弹幕

思路&#xff1a; 主要是要仔细阅读题目以及理解给出的已有代码&#xff0c;进行函数间的调用、定时器的使用、元素移除、清除定时器等&#xff0c;注意细节。 笔记&#xff1a; height不要写成hight设置left时,记得加单位px可以获取left的值进行计算&#xff0c;但要注意sp…...

真假难辨 - Sora(OpenAI)/世界模拟器的技术报告

目录 引言技术报告汉译版英文原版 引言 Sora是OpenAI在2024年2月15日发布的世界模拟器&#xff0c;功能是通过文本可以生成一分钟的高保真视频。由于较高的视频质量&#xff0c;引起了巨大关注。下面是三个示例&#xff0c;在示例之后给出了其技术报告&#xff1a; tokyo-wal…...

Linux第52步_移植ST公司的linux内核第4步_关闭内核模块验证和log信息时间戳_编译_并通过tftp下载测试

1、采用程序配置关闭“内核模块验证” 默认配置文件“stm32mp1_atk_defconfig”路径为“arch/arm/configs”; 使用VSCode打开默认配置文件“stm32mp1_atk_defconfg”&#xff0c;然后将下面的4条语句屏蔽掉&#xff0c;如下&#xff1a; CONFIG_MODULE_SIGy CONFIG_MODULE_…...

ctfshow-web21~28-WP

爆破(21-28) web21 题目给了一个zip文件,打开后解压是爆破的字典,我们抓包一下网址看看 发现账号和密码都被base64了,我们发送到intruder模块,给爆破的位置加上$符圈住 去base64解码一下看看格式...

鸿蒙开发系列教程(二十四)--List 列表操作(3)

列表编辑 1、新增列表项 定义列表项数据结构和初始化列表数据&#xff0c;构建列表整体布局和列表项。 提供新增列表项入口&#xff0c;即给新增按钮添加点击事件。 响应用户确定新增事件&#xff0c;更新列表数据。 2、删除列表项 列表的删除功能一般进入编辑模式后才可…...

线性代数笔记2--矩阵消元

0. 简介 矩阵消元 1. 消元过程 实例方程组 { x 2 y z 2 3 x 8 y z 12 4 y z 2 \begin{cases} x2yz2\\ 3x8yz12\\ 4yz2 \end{cases} ⎩ ⎨ ⎧​x2yz23x8yz124yz2​ 矩阵化 A [ 1 2 1 3 8 1 0 4 1 ] X [ x y z ] A \begin{bmatrix} 1 & 2 & 1 \\ 3 & …...

透光力之珠——光耦固态继电器的独特特点解析

光耦固态继电器作为现代电子控制领域中的重要组件&#xff0c;以其独特的特点在工业、通信、医疗等多个领域得到广泛应用。本文将深入剖析光耦固态继电器的特点&#xff0c;揭示其在电子控制中的卓越性能。 光耦固态继电器的光电隔离技术 光耦固态继电器以其光电隔离技术而脱颖…...

C#系列-​​​​​​​EntityFrameworkCore.Transactions.Abstractions应用场景+实例(38)

EntityFrameworkCore.Transactions.Abstractions应用场景 EntityFrameworkCore.Transactions.Abstractions 并不是一个官方的或广泛认可的 NuGet 包名称。在 Entity Framework Core (EF Core) 中&#xff0c;事务管理通常是通过 DbContext 的内置方法来实现的&#xff0c;如 Sa…...

PMDG 737

在Simbrief中生成计划后下载两个文件 放到C:\Users\32497\AppData\Local\Packages\Microsoft.FlightSimulator_8wekyb3d8bbwe\LocalState\packages\pmdg-aircraft-737(微软商店版本) 加油 先在飞行计划中查看计划燃油数量 MCDU中, AIRPLANE SEVICE 第二页, REQUEST FUEL TR…...

深入探索Midjourney:领航人工智能的新征程

深入探索Midjourney&#xff1a;领航人工智能的新征程 引言 在这个数据驱动、以技术创新为核心的时代&#xff0c;Midjourney以其独特的特性在人工智能领域中崭露头角。作为一款前沿的人工智能工具&#xff0c;它不仅重新定义了人机交互的方式&#xff0c;而且为各行各业提供…...