RabbitMQ 消息模式实战:从简单队列到复杂路由(三)
精准投递:路由模式
路由模式详解
路由模式是 RabbitMQ 中一种功能强大且灵活的消息传递模式,它在发布订阅模式的基础上,引入了路由键(Routing Key)的概念,实现了消息的精准路由和分发 。在路由模式中,交换机同样扮演着关键角色,不过与发布订阅模式中使用的扇形交换机不同,路由模式通常使用直连交换机(Direct Exchange) 。
直连交换机的工作原理是基于路由键的精确匹配。当生产者将消息发送到直连交换机时,必须指定一个路由键,这个路由键就像是一个地址标签,标识着消息的目的地 。交换机在接收到消息后,会根据消息的路由键,在与自己绑定的队列中寻找匹配的队列。只有那些绑定键(Binding Key,队列与交换机绑定时指定的键)与消息路由键完全相同的队列,才会接收到该消息 。例如,假设有一个订单处理系统,有两个队列,分别是 “new_order_queue”(新订单队列)和 “urgent_order_queue”(紧急订单队列),与直连交换机绑定,绑定键分别为 “new_order” 和 “urgent_order” 。当生产者发送一条消息,路由键为 “new_order” 时,直连交换机就会将这条消息精准地路由到 “new_order_queue” 队列中;如果路由键为 “urgent_order”,则会被路由到 “urgent_order_queue” 队列 。这种精确匹配的机制,确保了消息能够被准确地发送到目标队列,满足了不同业务场景下对消息定向处理的需求 。
应用场景分析
路由模式在实际业务中有着广泛的应用场景。以日志处理系统为例,系统运行过程中会产生各种不同级别的日志,如错误日志(error)、信息日志(info)、警告日志(warning)等 。通过路由模式,可以将不同级别的日志消息发送到不同的队列进行处理 。将错误日志消息的路由键设置为 “error”,与绑定键为 “error” 的错误日志队列绑定,当错误日志产生时,就会被精准地路由到该队列,由专门的错误处理模块进行处理,例如将错误信息记录到数据库、发送告警通知等 ;而信息日志消息的路由键设置为 “info”,路由到信息日志队列,可能进行简单的记录和统计分析 。这样,通过路由模式,能够对不同类型的日志进行分类处理,提高日志处理的效率和针对性 。
在电商系统的订单分类处理场景中,路由模式也发挥着重要作用 。订单可以根据不同的属性进行分类,如普通订单、团购订单、跨境订单等 。将普通订单消息的路由键设置为 “normal_order”,与绑定键为 “normal_order” 的普通订单队列绑定;团购订单消息的路由键设置为 “group_buy_order”,与团购订单队列绑定 。当订单生成时,根据订单类型设置相应的路由键,订单消息就会被准确地路由到对应的队列,由不同的订单处理模块进行处理,比如普通订单按照常规流程进行处理,团购订单可能需要进行团购规则的校验、团购人数统计等特殊处理 。通过这种方式,实现了订单的分类管理和高效处理 。
代码实战演示
下面通过 Java 代码来演示如何实现路由模式。假设我们有一个订单处理系统,根据订单类型将订单消息发送到不同的队列。
首先,在 Maven 项目的pom.xml文件中添加 RabbitMQ 客户端依赖:
<dependency>
<groupId>com.rabbitmq</groupId>
<artifactId>amqp-client</artifactId>
<version>5.16.0</version>
</dependency>
生产者代码如下:
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
public class OrderProducer {
private final static String EXCHANGE_NAME = "order_exchange";
private final static String NORMAL_ORDER_ROUTING_KEY = "normal_order";
private final static String GROUP_BUY_ORDER_ROUTING_KEY = "group_buy_order";
public static void main(String[] argv) throws Exception {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
try (Connection connection = factory.newConnection();
Channel channel = connection.createChannel()) {
// 声明直连交换机
channel.exchangeDeclare(EXCHANGE_NAME, "direct");
// 模拟发送普通订单消息
String normalOrderMessage = "Normal Order: Product A, Quantity 1";
channel.basicPublish(EXCHANGE_NAME, NORMAL_ORDER_ROUTING_KEY, null, normalOrderMessage.getBytes("UTF-8"));
System.out.println(" [x] Sent '" + normalOrderMessage + "' with routing key: " + NORMAL_ORDER_ROUTING_KEY);
// 模拟发送团购订单消息
String groupBuyOrderMessage = "Group Buy Order: Product B, Quantity 10";
channel.basicPublish(EXCHANGE_NAME, GROUP_BUY_ORDER_ROUTING_KEY, null, groupBuyOrderMessage.getBytes("UTF-8"));
System.out.println(" [x] Sent '" + groupBuyOrderMessage + "' with routing key: " + GROUP_BUY_ORDER_ROUTING_KEY);
}
}
}
在生产者代码中,首先创建了连接工厂、连接和通道。然后使用channel.exchangeDeclare方法声明了一个名为 “order_exchange” 的直连交换机。接着,分别模拟发送了普通订单消息和团购订单消息,发送时指定了对应的路由键 。
消费者代码(以普通订单消费者为例):
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.DeliverCallback;
public class NormalOrderConsumer {
private final static String EXCHANGE_NAME = "order_exchange";
private final static String NORMAL_ORDER_ROUTING_KEY = "normal_order";
private final static String QUEUE_NAME = "normal_order_queue";
public static void main(String[] argv) throws Exception {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
try (Connection connection = factory.newConnection();
Channel channel = connection.createChannel()) {
// 声明直连交换机
channel.exchangeDeclare(EXCHANGE_NAME, "direct");
// 声明队列
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
// 将队列绑定到交换机,并指定绑定键
channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, NORMAL_ORDER_ROUTING_KEY);
System.out.println(" [*] Waiting for normal order messages. To exit press CTRL+C");
DeliverCallback deliverCallback = (consumerTag, delivery) -> {
String message = new String(delivery.getBody(), "UTF-8");
System.out.println(" [x] Received '" + message + "'");
};
channel.basicConsume(QUEUE_NAME, true, deliverCallback, consumerTag -> { });
}
}
}
普通订单消费者代码中,同样先声明了直连交换机,然后声明了 “normal_order_queue” 队列,并使用channel.queueBind方法将队列绑定到交换机上,指定绑定键为 “normal_order” 。定义了消息处理回调函数DeliverCallback,当接收到消息时,会打印出消息内容 。最后使用channel.basicConsume方法开始消费消息 。通过运行生产者和消费者代码,可以看到订单消息会根据路由键被准确地发送到对应的队列并被处理,成功实现了路由模式 。
灵活匹配:主题模式
主题模式原理剖析
主题模式是 RabbitMQ 中一种功能强大且灵活的消息路由模式,它在路由模式的基础上,进一步拓展了路由规则,通过引入通配符来实现更灵活的消息匹配和分发 。在主题模式中,同样使用交换机来接收生产者发送的消息,并根据消息的路由键将其路由到匹配的队列中 。
主题模式使用的交换机类型是主题交换机(Topic Exchange) 。与直连交换机不同,主题交换机在匹配路由键时,支持使用通配符进行模糊匹配,从而大大提高了消息路由的灵活性 。主题模式中支持两种通配符:“”(星号)和 “#”(井号) 。“” 代表任意一个单词,“#” 代表零个或多个单词 。这里所说的单词,是指由 “.” 分隔的字符串片段 。例如,路由键 “order.new” 中包含两个单词 “order” 和 “new” 。
当生产者发送消息时,会指定一个路由键,如 “user.create.success” 。交换机在接收到消息后,会将该路由键与各个队列的绑定键进行匹配 。如果某个队列的绑定键为 “user.#”,那么该队列将匹配到这条消息,因为 “#” 可以匹配零个或多个单词,这里 “user.create.success” 中的 “create.success” 被 “#” 匹配 ;如果绑定键为 “user..success”,同样也能匹配到,因为 “” 匹配了 “create” 这一个单词 。通过这种通配符的匹配方式,一条消息可以被路由到多个符合条件的队列,实现了消息的灵活分发 。
实际应用场景
主题模式在实际业务中有广泛的应用场景。以内容推送系统为例,假设一个内容平台有多种类型的内容,如新闻、视频、文章等,同时有不同兴趣偏好的用户群体 。通过主题模式,可以将内容发布的消息进行灵活路由 。将新闻相关的内容消息的路由键设置为 “news.*”,如 “news.politics”(政治新闻)、“news.entertainment”(娱乐新闻) 。对于关注政治新闻的用户队列,绑定键设置为 “news.politics”,这样当有新的政治新闻发布时,该用户队列就能接收到消息,从而将新闻推送给关注政治的用户 ;对于关注所有新闻的用户队列,绑定键设置为 “news.#”,则可以接收所有类型的新闻消息 。通过这种方式,实现了根据用户兴趣精准推送内容,提高了用户体验和内容传播的效率 。
在消息过滤场景中,主题模式也发挥着重要作用 。比如在一个分布式系统中,各个模块会产生大量的日志消息 。为了对这些日志进行有效的管理和分析,可以使用主题模式进行消息过滤 。将错误日志消息的路由键设置为 “error.*”,如 “error.database”(数据库错误)、“error.network”(网络错误) 。创建一个专门处理数据库错误的队列,绑定键设置为 “error.database”,当有数据库错误日志产生时,该队列就能接收到消息,进行针对性的处理,如记录详细的错误信息、发送告警通知给数据库管理员等 ;对于记录所有错误日志的队列,绑定键设置为 “error.#”,可以收集所有类型的错误日志,便于后续的统计和分析 。通过主题模式的灵活匹配,实现了对日志消息的高效过滤和处理 。
代码示例讲解
下面通过 Java 代码来展示如何使用主题模式实现消息的灵活分发。假设我们有一个内容推送系统,根据不同的内容类型和用户兴趣进行消息路由 。
首先,在 Maven 项目的pom.xml文件中添加 RabbitMQ 客户端依赖:
<dependency>
<groupId>com.rabbitmq</groupId>
<artifactId>amqp-client</artifactId>
<version>5.16.0</version>
</dependency>
生产者代码如下:
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
public class ContentProducer {
private final static String EXCHANGE_NAME = "content_exchange";
public static void main(String[] argv) throws Exception {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
try (Connection connection = factory.newConnection();
Channel channel = connection.createChannel()) {
// 声明主题交换机
channel.exchangeDeclare(EXCHANGE_NAME, "topic");
// 模拟发布新闻消息
String newsRoutingKey = "news.politics";
String newsMessage = "New Political News: New Policy Announcement";
channel.basicPublish(EXCHANGE_NAME, newsRoutingKey, null, newsMessage.getBytes("UTF-8"));
System.out.println(" [x] Sent '" + newsMessage + "' with routing key: " + newsRoutingKey);
// 模拟发布视频消息
String videoRoutingKey = "video.entertainment";
String videoMessage = "New Entertainment Video: Popular Movie Trailer";
channel.basicPublish(EXCHANGE_NAME, videoRoutingKey, null, videoMessage.getBytes("UTF-8"));
System.out.println(" [x] Sent '" + videoMessage + "' with routing key: " + videoRoutingKey);
}
}
}
在生产者代码中,创建了连接工厂、连接和通道后,使用channel.exchangeDeclare方法声明了一个名为 “content_exchange” 的主题交换机 。然后分别模拟发布了新闻消息和视频消息,发送时指定了对应的路由键 。
消费者代码(以关注政治新闻的用户消费者为例):
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.DeliverCallback;
public class PoliticsNewsConsumer {
private final static String EXCHANGE_NAME = "content_exchange";
private final static String QUEUE_NAME = "politics_news_queue";
private final static String BINDING_KEY = "news.politics";
public static void main(String[] argv) throws Exception {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
try (Connection connection = factory.newConnection();
Channel channel = connection.createChannel()) {
// 声明主题交换机
channel.exchangeDeclare(EXCHANGE_NAME, "topic");
// 声明队列
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
// 将队列绑定到交换机,并指定绑定键
channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, BINDING_KEY);
System.out.println(" [*] Waiting for political news messages. To exit press CTRL+C");
DeliverCallback deliverCallback = (consumerTag, delivery) -> {
String message = new String(delivery.getBody(), "UTF-8");
System.out.println(" [x] Received '" + message + "'");
};
channel.basicConsume(QUEUE_NAME, true, deliverCallback, consumerTag -> { });
}
}
}
关注政治新闻的用户消费者代码中,先声明了主题交换机和 “politics_news_queue” 队列,然后使用channel.queueBind方法将队列绑定到交换机上,指定绑定键为 “news.politics” 。定义了消息处理回调函数DeliverCallback,当接收到消息时,会打印出消息内容 。最后使用channel.basicConsume方法开始消费消息 。通过运行生产者和消费者代码,可以看到消息会根据路由键和绑定键的匹配规则,被准确地路由到对应的队列并被处理,成功实现了主题模式下消息的灵活分发 。
相关文章:
RabbitMQ 消息模式实战:从简单队列到复杂路由(三)
精准投递:路由模式 路由模式详解 路由模式是 RabbitMQ 中一种功能强大且灵活的消息传递模式,它在发布订阅模式的基础上,引入了路由键(Routing Key)的概念,实现了消息的精准路由和分发 。在路由模式中&…...
STM32 定时器主从模式配置解析
STM32 定时器主从模式配置解析 下面这两行代码是配置STM32定时器主从模式的关键设置 代码功能解析 TIM_SelectInputTrigger(TIM3, TIM_TS_TI2FP2); // 选择从模式输出的触发源 TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Reset); // 选择从模式1. TIM_SelectInputTrigger(T…...
Leetcode76覆盖最小子串
覆盖最小子串 代码来自b站左程云 class Solution {public String minWindow(String str, String tar) {char[] s str.toCharArray();char[] t tar.toCharArray();int[] cnt new int[256];for (char cha : t) { cnt[cha]--;}int len Integer.MAX_VALUE;int debt t.length…...
Perl语言深度考查:从文本处理到正则表达式的全面掌握
阅读原文 前言:为什么Perl依然值得学习? "这个脚本用Perl写只需要5分钟!"——在当今Python大行其道的时代,你依然能在不少企业的运维部门听到这样的对话。Perl作为一门有着30多年历史的语言,凭借其强大的文…...
idea中Lombok失效的解决方案
Lombok 是一个 Java 库,旨在通过注解简化 Java 代码的编写,减少样板代码,提高开发效率。它通过自动生成常见的代码(如 getter、setter、构造函数等)来减少开发者的手动编码工作。 一般Lombok失效有四步排查方案&#…...
【LeetCode 热题 100】动态规划 系列
📁 70. 爬楼梯 状态标识:爬到第i层楼梯时,有多少种方法。 状态转移方程:dp[i] dp[i-1] dp[i-2],表示从走一步和走两步的方式。 初始化:dp[1] 1 , dp[2] 2。 返回值:dp[n],即走到…...
刷leetcodehot100返航版--双指针5/16
for (int i 0, j 0; i < n; i ) { while (j < i && check(i, j)) j ; // 具体问题的逻辑 } 常见问题分类: (1) 对于一个序列,用两个指针维护一段区间 (2) 对于两个序列,维护某种次序,比如归并排序中…...
DAY24元组和OS模块
元组 元组的特点: 有序,可以重复,这一点和列表一样元组中的元素不能修改,这一点非常重要,深度学习场景中很多参数、形状定义好了确保后续不能被修改。 很多流行的 ML/DL 库(如 TensorFlow, PyTorch, Num…...
CSS:三大特性
文章目录 一、层叠性二、继承性三、优先级 一、层叠性 二、继承性 可以在MDN网站上查看属性是否可以被继承 例如color 三、优先级...
Cross-Site Scripting(XSS)
1. XSS介绍 跨站脚本攻击(Cross-Site Scripting)简称XSS,人们经常将跨站脚本攻击(Cross Site Scripting)缩写为CSS,但这会与层叠样式表(Cascading Style Sheets,CSS)的缩…...
掌握HTML文件上传:从基础到高级技巧
HTML中input标签的上传文件功能详解 一、基础概念 1. 文件上传的基本原理 在Web开发中,文件上传是指将本地计算机中的文件(如图片、文档、视频等)传输到服务器的过程。HTML中的<input type"file">标签是实现这一功能的基础…...
WebRTC中的几个Channel
一、我指的是谁? 以视频为例,常见的有:MediaChannel、VideoMediaChannel、WebRtcVideoChannel、BaseChannel、VideoChannel,那么,为什么要这么多Channel,只写一个叫做SuperChannel行不行(很多程…...
【设计模式】- 行为型模式1
模板方法模式 定义了一个操作中的算法骨架,将算法的一些步骤推迟到子类,使得子类可以不改变该算法结构的情况下重定义该算法的某些步骤 【主要角色】: 抽象类:给出一个算法的轮廓和骨架(包括一个模板方法 和 若干基…...
容器化-k8s-使用和部署
一、K8s 使用 1、基本概念 集群: 由 master 节点和多个 slaver 节点组成,是 K8s 的运行基础。节点: 可以是物理机或虚拟机,是 K8s 集群的工作单元,运行容器化应用。Pod: K8s 中最小的部署单元,一个 Pod 可以包含一个或多个紧密相关的容器,这些容器共享网络和存储资源。…...
黑马k8s(九)
1.Pod-生命周期概述 2.Pod生命周期-创建和终止 3.Pod生命周期-初始化容器...
Android trace中CPU的RenderThread与GPU
Android trace中CPU的RenderThread与GPU RenderThread是系统的GPU绘制线程,GPU渲染就是通常所谓的硬件加速,如果应用关闭硬件加速,就没有了RenderThread,只有UI Thread,即Android主线程。 Android GPU渲染SurfaceFlin…...
测试工程师如何学会Kubernetes(k8s)容器知识
Kubernetes(K8s)作为云原生时代的关键技术之一,对于运维工程师、开发工程师以及测试工程师来说,都是一门需要掌握的重要技术。作为一名软件测试工程师,学习Kubernetes是一个有助于提升自动化测试、容器化测试以及云原生应用测试能力的重要过程…...
接触感知 钳位电路分析
以下是NG板接触感知电路的原理图。两极分别为P3和P4S,电压值P4S < P3。 电路结构分两部分,第一部分对输入电压进行分压钳位。后级电路使用LM113比较器芯片进行电压比较,输出ST接触感知信号。 钳位电路输出特性分析 输出电压变化趋势&a…...
码蹄集——圆包含
MT1181 圆包含 输入2个圆的圆心的坐标值(x,y)和半径,判断断一个圆是否完全包含另一个圆,输出YES或者NO。另:内切不算做完全包含。 格式 输入格式:输入整型,空格分隔。 每行输入一组…...
ConcurrentSkipListMap的深入学习
目录 1、介绍 1.1、线程安全 1.2、有序性 1.3、跳表数据结构 1.4、API 提供的功能 1.5、高效性 1.6、应用场景 2、数据结构 2.1、跳表(Skip List) 2.2、节点类型: 1.Node 2.Index 3.HeadIndex 2.3、特点 3、选择层级 3.1、随…...
ProfibusDP主站转modbusTCP网关接DP从站网关通讯案例
ProfibusDP主站转modbusTCP网关接DP从站网关通讯案例 在工业自动化领域,Profibus DP和Modbus TCP是两种常见的通信协议。Profibus DP广泛应用于过程自动化、工厂自动化等场景,而Modbus TCP则常见于楼宇自动化、能源管理等领域。由于设备和系统之间往往存…...
第一次做逆向
题目来源:ctf.show 1、下载附件,发现一个exe和一个txt文件 看看病毒加没加壳,发现没加那就直接放IDA 放到IDA找到main主函数,按F5反编译工具就把他还原成类似C语言的代码 然后我们看逻辑,将flag.txt文件的内容进行加…...
【项目】自主实现HTTP服务器:从Socket到CGI全流程解析
00 引言 在构建高效、可扩展的网络应用时,理解HTTP服务器的底层原理是一项必不可少的技能。现代浏览器与移动应用大量依赖HTTP协议完成前后端通信,而这一过程的背后,是由网络套接字驱动的请求解析、响应构建、数据传输等一系列机制所支撑…...
AI最新资讯,GPT4.1加入网页端、Claude 3.7 Sonnet携“极限推理”发布在即
目录 一、GPT4.1加入网页端二、Claude 3.7 Sonnet携“极限推理”发布在即三、这项功能的关键特点1、双模式操作2、可视化思考过程3、可控的思考预算4、性能提升 四、Claude制作SVG图像1、Prompt提示词模板2、demo:技术路线图**Prompt提示词:**3、甘特图4…...
Android 中使用通知(Kotlin 版)
1. 前置条件 Android Studio:确保使用最新版本(2023.3.1)目标 API:最低 API 21,兼容 Android 8.0(渠道)和 13(权限)依赖库:使用 WorkManager 和 Notificatio…...
在 Kotlin 中,什么是解构,如何使用?
在 Kotlin 中,解构是一种语法糖,允许将一个对象分解为多个独立的变量。 这种特性可以让代码更简洁、易读,尤其适用于处理数据类、集合(如 Pair、Map)或其他结构化数据。 1 解构的核心概念 解构通过定义 componentN()…...
apisix透传客户端真实IP(real-ip插件)
文章目录 apisix透传客户端真实IP需求和背景apisix real-ip插件为什么需要 trusted_addresses?安全架构的最佳实践 示例场景apisix界面配置 apisix透传客户端真实IP 需求和背景 当 APISIX 前端有其他反向代理(如 Nginx、HAProxy、云厂商的 LBÿ…...
初学者如何用 Python 写第一个爬虫?
初学者如何用 Python 写第一个爬虫? 一、爬虫的基本概念 (一)爬虫的定义 爬虫,英文名为 Web Crawler,也被叫做网络蜘蛛、网络机器人。想象一下,有一个勤劳的小蜘蛛,在互联网这个巨大的蜘蛛网中…...
基于MNIST数据集的手写数字识别(CNN)
目录 一,模型训练 1.1 数据集介绍 1.2 CNN模型层结构 1.3 定义CNN模型 1.4 神经网络的前向传播过程 1.5 数据预处理 1.6 加载数据 1.7 初始化 1.8 模型训练过程 1.9 保存模型 二,模型测试 2.1 定义与训练时相同的CNN模型架构 2.2 图像的预处…...
QT6 源(103)篇三:阅读与注释 QPlainTextEdit,给出源代码
(10)关于文本处理的内容很多,来不及全面阅读、思考与整理。先给出类的继承图: (11)本源代码来自于头文件 qplaintextedit . h : #ifndef QPLAINTEXTEDIT_H #define QPLAINTEXTEDIT_H#include &…...
yocto5.2开发任务手册-7 升级配方
此文为机器辅助翻译,仅供个人学习使用,如有翻译不当之处欢迎指正 7 升级配方 随着时间的推移,上游开发者会为图层配方构建的软件发布新版本。建议使配方保持与上游版本发布同步更新。 虽然有多种升级配方的方法,但您可能需要先…...
LangPDF: Empowering Your PDFs with Intelligent Language Processing
LangPDF: Empowering Your PDFs with Intelligent Language Processing Unlock Global Communication: AI-Powered PDF Translation and Beyond In an interconnected world, seamless multilingual document management is not just an advantage—it’s a necessity. LangP…...
DDS(数据分发服务) 和 P2P(点对点网络) 的详细对比
1. 核心特性对比 维度 DDS P2P 实时性 微秒级延迟,支持硬实时(如自动驾驶) 毫秒至秒级,依赖网络环境(如文件传输) 架构 去中心化发布/订阅模型,节点自主发现 完全去中心化,节…...
TC8:SOMEIP_ETS_029-030
SOMEIP_ETS_029: echoUINT8Array16Bitlength 目的 检查当method echoUINT8Array16BitLength的参数中长度字段为16bit时,SOME/IP协议层是否能对参数进行序列化和反序列化。 对于可变长度的数组而言,必须用长度字段表示数组长度。否则接收方无法判断有效数据。 SOMEIP_ETS_02…...
Elasticsearch索引全生命周期管理指南之一
#作者:猎人 文章目录 一、索引常规操作二、索引mapping和别名管理 一、索引常规操作 索引数据特点: 索引中的数据随着时间,持续不断增长 按照时间序列划分索引的好处&挑战: 按照时间进行划分索引,会使得管理更加…...
本土DevOps革命:Gitee如何撬动中国企业的数字化转型新动能
在数字化浪潮席卷全球的背景下,中国企业正面临前所未有的转型压力与机遇。随着《数据安全法》和《个人信息保护法》的全面实施,以及信创产业政策的深入推进,研发工具链的自主可控已成为关乎企业核心竞争力的战略命题。在这一关键赛道上&#…...
ARM服务器解决方案
ARM服务器解决方案已成为异构计算领域的重要技术路径,其核心优势与多元化场景适配性正加速产业渗透。以下为关键要点分析: 一、核心优势与架构设计 能效比优化 ARM架构基于RISC指令集,单节点功耗可控制在15W以下,较x86架构能效…...
【暗光图像增强】【基于CNN的方法】2020-AAAI-EEMEFN
EEMEFN:Low-Light Image Enhancement via Edge-Enhanced Multi-Exposure Fusion Network EEMEFN:基于边缘增强多重曝光融合网络的低光照图像增强 AAAI 2020 论文链接 0.论文摘要 本研究专注于极低光照条件下的图像增强技术,旨在提升图像亮度…...
嵌入式EasyRTC音视频实时通话SDK在工业制造领域的智能巡检/AR协作等应用
一、背景 在数字化浪潮席卷全球的当下,远程监控与驾驶技术已深度渗透至工业巡检、智能交通等核心领域。然而,传统方案普遍面临实时性瓶颈、高延迟传输及交互体验匮乏等痛点,严重制约行业智能化转型。EasyRTC作为前沿的实时音视频通信技术&am…...
uniapp-商城-58-后台 新增商品(属性子级的添加和更新)
前面对父级属性的添加进行了分析,这里再来继续做属性子级的数据添加,包含页面逻辑以及后台处理的逻辑。当然这里还是在前面的云对象的方式进行的。 本文介绍了在云对象green-mall-sku中添加子级属性的实现过程。首先,通过updateChild接口处理…...
基于springboot+vue的机场乘客服务系统
开发语言:Java框架:springbootJDK版本:JDK1.8服务器:tomcat7数据库:mysql 5.7数据库工具:Navicat12开发软件:eclipse/myeclipse/ideaMaven包:Maven3.3.9 系统展示 用户管理 航班信…...
npm和nvm和nrm有什么区别
npm 全称:Node Package Manager。 作用: 包管理:用于安装、共享、分发代码,管理项目依赖关系。项目管理:创建和管理 package.json 文件,记录项目依赖和配置信息。脚本执行:运行项目中的脚本&…...
几种排序方式的C语言实现(冒泡、选择、插入、希尔等)
## 分类 存储器类型: - 内排序(数据规模小 内存) - 外排序(数据库 磁盘) 是否基于元素之间的比较 - 基数排序 - 其他排序:冒泡、选择、插入、快速、归并、希尔、堆…… 时间复杂度 - O&#…...
【MATLAB例程】线性卡尔曼滤波的程序,三维状态量和观测量,较为简单,可用于理解多维KF,附代码下载链接
本文所述代码实现了一个 三维状态的扩展卡尔曼滤波 (Extended Kalman Filter, EKF) 算法。通过生成过程噪声和观测噪声,对真实状态进行滤波估计,同时对比了滤波前后状态量的误差和误差累积分布曲线。 文章目录 简介运行结果MATLAB源代码 简介 代码分为以…...
芯片测试之X-ray测试
原理: X-ray是利用阴极射线管产生高能量电子与金属靶撞击,在撞击过程中,因电子突然减速,其损失的动能会以X-Ray形式放出。而对于样品无法以外观方式观测的位置,利用X-Ray穿透不同密度物质后其光强度的变化,…...
机器学习中的特征工程:解锁模型性能的关键
在机器学习领域,模型的性能往往取决于数据的质量和特征的有效性。尽管深度学习模型在某些任务中能够自动提取特征,但在大多数传统机器学习任务中,特征工程仍然是提升模型性能的关键环节。本文将深入探讨特征工程的重要性、常用方法以及在实际…...
【学习笔记】机器学习(Machine Learning) | 第七章|神经网络(1)
机器学习(Machine Learning) 简要声明 基于吴恩达教授(Andrew Ng)课程视频 BiliBili课程资源 文章目录 机器学习(Machine Learning)简要声明 机器学习之深度学习神经网络入门一、神经网络的起源与发展二、神经元模型(…...
反向传播算法:神经网络的核心优化方法,一文打通任督二脉
搞神经网络训练,**反向传播(Backpropagation)**是最核心的算法。 没有它,模型就只能瞎猜参数,训练基本白搭。 这篇文章不整公式推导,不搞花架子,咱就把最关键的几个问题讲明白: 反向传播到底是干啥的? 它是怎么一步步更新参数的? 哪些坑你必须避免? 一、反向传播是…...
neo4j框架:java安装教程
安装使用neo4j需要事先安装好java,java版本的选择是一个犯难的问题。本文总结了在安装java和使用Java过程中遇到的问题以及相应的解决方法。 Java的安装包可以在java官方网站Java Downloads | Oracle 中国进行下载 以java 8为例,选择最后一行的x64 compr…...
基于React的高德地图api教程007:椭圆的绘制、编辑和删除
文章目录 7、椭圆绘制7.1 绘制椭圆7.1.1 设置圆心7.1.2 确定短半轴7.1.3 确定长半轴7.1.4 实时显示椭圆形状7.2 修改椭圆7.2.1 修改椭圆属性信息7.2.2 修改椭圆形状7.3 删除椭圆7.4 定位椭圆7.5 代码下载7.07、椭圆绘制 7.1 绘制椭圆 7.1.1 设置圆心 第一次点击地图设置圆心…...