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年发布,是一个在AMQP(高级消息队列协议)基础上完成的,可复用的企业消息系统,…...
WordPress作者页面链接的用户名自动变成16位字符串串插件Smart User Slug Hider
WordPress默认的作者页面URL链接地址格式为“你的域名/author/admin”,其中admin就是你的用户名,这样的话就会暴露我们的用户名。 为了解决这个问题,前面boke112百科跟大家分享了『如何将WordPress作者存档链接中的用户名改为昵称或ID』一文…...
Nvidia 携手 RTX 推出的本地运行 AI 聊天机器人
每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为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-多媒体与嵌入 查看更多学习笔记:GitHub:LoveEmiliaForever MDN中文官网 HTML-中的图片 将图片放入网页 可以使用<img/>来将图片嵌入网页,它是一个空元素,最少只需src属性即可工作 <img src"图片链接"…...
openJudge | 距离排序 C语言
总时间限制: 1000ms 内存限制: 65536kB 描述 给出三维空间中的n个点(不超过10个),求出n个点两两之间的距离,并按距离由大到小依次输出两个点的坐标及它们之间的距离。 输入 输入包括两行,第一行包含一个整数n表示点的个数,第二…...
【教程】MySQL数据库学习笔记(三)——数据定义语言DDL(持续更新)
写在前面: 如果文章对你有帮助,记得点赞关注加收藏一波,利于以后需要的时候复习,多谢支持! 【MySQL数据库学习】系列文章 第一章 《认识与环境搭建》 第二章 《数据类型》 第三章 《数据定义语言DDL》 文章目录 【MyS…...
[leetcode]买卖股票的最佳时机 (动态规划)
121. 买卖股票的最佳时机 给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。 你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。 返回你可以从…...
隐函数的求导【高数笔记】
1. 什么是隐函数? 2. 隐函数的做题步骤? 3. 隐函数中的复合函数求解法,与求导中复合函数求解法有什么不同? 4. 隐函数求导的过程中需要注意什么?...
SG3225EEN晶体振荡器规格书
SG3225EEN 晶振是EPSON/爱普生的一款额定频率25 MHz至500 MHz的石英晶体振荡器,6脚贴片,LV-PECL输出,3225封装常规有源晶振,具有小尺寸,轻薄型,高稳定性,低相位抖动,低电源电压&…...
ESP8266 常用AT指令
一、ESP8266的AT指令要点、常见错误 AT指令要大写;以"\r\n"作结尾;串口通信,115200-None-8-1;支持2.4G频段,不支持5G频段 (如果用手机创建热点,注意选择2.4G)不支持中文的wifi名称工作模式,上电…...
esbuild 构建工具为什么很快?
esbuild 构建工具之所以很快,主要有以下几个原因: Go语言编写:esbuild 是用 Go 语言编写的,Go 语言以其高效的并发模型和编译速度而闻名。与一些其他构建工具相比,Go 语言在并发处理和内存管理方面表现出色,…...
解决vscode报错,在赋值前使用了变量“XXX“
问题:如图所示 解决方法: 法一: 补全函数使其完整 法二: 使用断言...
python自动定时任务schedule库的使用方法
当你需要在 Python 中定期执行任务时,schedule 库是一个非常实用的工具。它可以帮助你自动化定时任务。以下是一些使用示例: 基本使用: import schedule import timedef job():print("Im working...")schedule.every(10).minutes.d…...
用机器学习方法重构期货商品板块
用机器学习方法重构期货商品板块 阿岛格 参考专栏:低门槛搭建个人量化平台 https://www.zhihu.com/column/c_1441014235068944386 摘 要 金融市场商品期货的板块分类,通常根据不同交易所、监管机构和证券商标准,按照期货标的属性、或产业链关系等进行分类,各自分类略有差…...
51单片机项目(29)——基于51单片机的避障跟随小车
1.功能设计 按键模式:按下按键,小车可以前后左右地运动 自动模式:根据红外传感器的状态,自行决定运动状态。检测到前方有物体时,车子移动,起到一个跟随的效果。 演示视频如下: 51单片机智能避障…...
人工智能学习与实训笔记(六):百度飞桨套件使用方法
目录 八、百度飞桨套件使用 8.1 飞桨预训练模型套件PaddleHub 8.1.1 一些本机CPU可运行的飞桨预训练简单模型(亲测可用) 8.1.1.1 人脸检测模型 8.1.1.2 中文分词模型 8.1.2 预训练模型Fine-tune 8.2 飞桨开发套件 8.2.1 PaddleSeg - 图像分割 8…...
Linux第一个小程序-进度条
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一、回车和换行 二、行缓冲区概念 三、倒计时 四、进度条代码 版本一: 编辑 版本二: 总结 前言 世上有两种耀眼的光芒,一…...
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部最流行的电影数据 数据来源:https://www.kaggle.com/damianpanek/sunday-eda/data 2、问题1 想知道这些电影数据中评分的平均分,导演的人数等信息,我们应该怎么获取? 3、问题…...
(17)Hive ——MR任务的map与reduce个数由什么决定?
一、MapTask的数量由什么决定? MapTask的数量由以下参数决定 文件个数文件大小blocksize 一般而言,对于每一个输入的文件会有一个map split,每一个分片会开启一个map任务,很容易导致小文件问题(如果不进行小文件合并&…...
define和typedef
目录 一、define 二、typedef 三、二者之间的区别 一、define 在我们写代码的日常中,经常会用到define去配合数组的定义使用 #define N 10 arr[N]{0}; define不仅仅能做这些 #define是一种宏,我们首先来了解一下宏定义。 宏定义一般作用在C语言的预…...
SpringCloud之Nacos用法笔记
SpringCloud之Nacos注册中心 Nacos注册中心nacos启动服务注册到Nacosnacos服务分级模型NacosRule负载均衡策略根据集群负载均衡加权负载均衡Nacos环境隔离-namespace Nacos与eureka的对比临时实例与非临时实例设置 Nacos配置管理统一配置管理微服务配置拉取配置自动刷新远端配置…...
【c++】拷贝构造函数
1.特征 1.拷贝构造函数是构造函数的一个重载形式。 2.若显示定义了拷贝构造函数,编译器就不会自动生成构造函数了。 3.拷贝构造函数的参数只有一个且必须是类型对象的引用,使用传值方式编译器直接报错,因为会引发无穷递归调用。 4.若未显…...
17.3.1.2 曝光
版权声明:本文为博主原创文章,转载请在显著位置标明本文出处以及作者网名,未经作者允许不得用于商业目的。 基本算法:先定义一个阈值,通常取得是128 原图像:颜色值color(R,G&#…...
【Win10 触摸板】在插入鼠标时禁用触摸板,并在没有鼠标时自动启用触摸板。取消勾选连接鼠标时让触摸板保持打开状态,但拔掉鼠标后触摸板依旧不能使用
出现这种问题我的第一反应就是触摸板坏了,但是无意间我换了一个账户发现触摸板可以用,因此推断触摸板没有坏,是之前的账户问题,跟系统也没有关系,不需要重装系统。 解决办法:与鼠标虚拟设备有关 然后又从知…...
排序算法---桶排序
原创不易,转载请注明出处。欢迎点赞收藏~ 桶排序(Bucket Sort)是一种排序算法,它将待排序的数据分到几个有序的桶中,每个桶再分别进行排序,最后将各个桶中的数据按照顺序依次取出,即可得到有序序…...
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. 最大子序和
文章目录 理论基础分发饼干思路:代码: 摆动序列思路一 贪心算法:代码: 思路二:动态规划(想不清楚)代码: 最大子序和思路:代码: 理论基础 贪心算法其实就是没…...
无人机地面站技术,无人机地面站理论基础详解
地面站作为整个无人机系统的作战指挥中心,其控制内容包括:飞行器的飞行过程,飞行航迹, 有效载荷的任务功能,通讯链路的正常工作,以及 飞行器的发射和回收。 无人机地面站总述 地面站作为整个无人机系统的作战指挥中心…...
2024.2.13
21.C 22.D 23.B 5先出栈表示1,2,3,4已经入栈了,5出后4出,但之后想出1得先让3,2先后出栈,所以 B 不可能 24.10,12,120 25.2,5 26.可能会出现段错误…...
论文阅读:四足机器人对抗运动先验学习稳健和敏捷的行走
论文:Learning Robust and Agile Legged Locomotion Using Adversarial Motion Priors 进一步学习:AMP,baseline方法,TO 摘要: 介绍了一种新颖的系统,通过使用对抗性运动先验 (AMP) 使四足机器人在复杂地…...
.NET Core WebAPI中封装Swagger配置
一、创建相关文件 创建一个Utility/SwaggerExt文件夹,添加一个类 二、在Program中找到Swagger相关配置信息 三、添加方法,在Program中调用 在SwaggerExt类中添加方法,将相关配置添写入 /// <summary> /// swagger配置 /// </sum…...
28. 找出字符串中第一个匹配项的下标
Problem: 28. 找出字符串中第一个匹配项的下标 文章目录 思路解题方法复杂度Code 思路 这个问题可以通过使用KMP(Knuth-Morris-Pratt)算法来解决。KMP算法是一种改进的字符串匹配算法,它的主要思想是当子串与目标字符串不匹配时,能…...
宿舍|学生宿舍管理小程序|基于微信小程序的学生宿舍管理系统设计与实现(源码+数据库+文档)
学生宿舍管理小程序目录 目录 基于微信小程序的学生宿舍管理系统设计与实现 一、前言 二、系统功能设计 三、系统实现 1、管理员模块的实现 (1)学生信息管理 (2)公告信息管理 (3)宿舍信息管理 &am…...
CVE-2022-25487 漏洞复现
漏洞描述:Atom CMS 2.0版本存在远程代码执行漏洞,该漏洞源于/admin/uploads.php 未能正确过滤构造代码段的特殊元素。攻击者可利用该漏洞导致任意代码执行。 其实这就是一个文件上传漏洞罢了。。。。 打开之后,/home路由是个空白 信息搜集&…...
C#面:强类型和弱类型
强类型 强类型是指在编程语言中,变量必须明确声明其数据类型,并且在编译时会进行类型检查的特性。它可以提高代码的可读性和可维护性,但有时需要显式地进行类型转换。换句话说,强类型语言要求变量的类型在编译时就要确定…...
nodejs和npm和vite
Nodejs 简单的说 Node.js 就是运行在服务端的 JavaScript。 Node.js 是一个基于 Chrome JavaScript 运行时建立的一个平台。 Node.js 是一个事件驱动 I/O 服务端 JavaScript 环境 用途: Node.js 可以被看作是一个 JavaScript 运行时环境,专门用于在服务…...
相机图像质量研究(24)常见问题总结:CMOS期间对成像的影响--摩尔纹
系列文章目录 相机图像质量研究(1)Camera成像流程介绍 相机图像质量研究(2)ISP专用平台调优介绍 相机图像质量研究(3)图像质量测试介绍 相机图像质量研究(4)常见问题总结:光学结构对成像的影响--焦距 相机图像质量研究(5)常见问题总结:光学结构对成…...
Redis -- 数据库管理
目录 前言 切换数据库(select) 数据库中key的数量(dbsize) 清除数据库(flushall flushdb) 前言 MySQL有一个很重要的概念,那就是数据库database,一个MySQL里面有很多个database,一个datab…...
蓝桥杯(Web大学组)2023省赛真题:视频弹幕
思路: 主要是要仔细阅读题目以及理解给出的已有代码,进行函数间的调用、定时器的使用、元素移除、清除定时器等,注意细节。 笔记: height不要写成hight设置left时,记得加单位px可以获取left的值进行计算,但要注意sp…...
真假难辨 - Sora(OpenAI)/世界模拟器的技术报告
目录 引言技术报告汉译版英文原版 引言 Sora是OpenAI在2024年2月15日发布的世界模拟器,功能是通过文本可以生成一分钟的高保真视频。由于较高的视频质量,引起了巨大关注。下面是三个示例,在示例之后给出了其技术报告: tokyo-wal…...
Linux第52步_移植ST公司的linux内核第4步_关闭内核模块验证和log信息时间戳_编译_并通过tftp下载测试
1、采用程序配置关闭“内核模块验证” 默认配置文件“stm32mp1_atk_defconfig”路径为“arch/arm/configs”; 使用VSCode打开默认配置文件“stm32mp1_atk_defconfg”,然后将下面的4条语句屏蔽掉,如下: CONFIG_MODULE_SIGy CONFIG_MODULE_…...
ctfshow-web21~28-WP
爆破(21-28) web21 题目给了一个zip文件,打开后解压是爆破的字典,我们抓包一下网址看看 发现账号和密码都被base64了,我们发送到intruder模块,给爆破的位置加上$符圈住 去base64解码一下看看格式...
鸿蒙开发系列教程(二十四)--List 列表操作(3)
列表编辑 1、新增列表项 定义列表项数据结构和初始化列表数据,构建列表整体布局和列表项。 提供新增列表项入口,即给新增按钮添加点击事件。 响应用户确定新增事件,更新列表数据。 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 & …...
透光力之珠——光耦固态继电器的独特特点解析
光耦固态继电器作为现代电子控制领域中的重要组件,以其独特的特点在工业、通信、医疗等多个领域得到广泛应用。本文将深入剖析光耦固态继电器的特点,揭示其在电子控制中的卓越性能。 光耦固态继电器的光电隔离技术 光耦固态继电器以其光电隔离技术而脱颖…...
C#系列-EntityFrameworkCore.Transactions.Abstractions应用场景+实例(38)
EntityFrameworkCore.Transactions.Abstractions应用场景 EntityFrameworkCore.Transactions.Abstractions 并不是一个官方的或广泛认可的 NuGet 包名称。在 Entity Framework Core (EF Core) 中,事务管理通常是通过 DbContext 的内置方法来实现的,如 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:领航人工智能的新征程 引言 在这个数据驱动、以技术创新为核心的时代,Midjourney以其独特的特性在人工智能领域中崭露头角。作为一款前沿的人工智能工具,它不仅重新定义了人机交互的方式,而且为各行各业提供…...