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

ActiveMQ 高级特性:延迟消息与优先级队列实战(一)

引言

在当今的分布式系统开发中,消息中间件扮演着至关重要的角色,而 ActiveMQ 作为一款广泛使用的开源消息中间件,凭借其丰富的特性和良好的性能,深受开发者的青睐。它支持多种消息模型,如点对点和发布 / 订阅,并且具备消息持久化、事务支持等功能,能够满足不同场景下的消息通信需求。

延迟消息和优先级队列是 ActiveMQ 的两个高级特性,在实际应用中具有重要的价值。延迟消息允许消息在指定的时间后被投递,这在许多场景中都非常有用,比如订单超时处理,如果用户下单后一段时间内未支付,系统可以通过延迟消息自动取消订单;又如任务定时执行,某些任务需要在特定的时间点执行,延迟消息就能很好地实现这一需求。优先级队列则根据消息的优先级进行排序,优先处理高优先级的消息,这在任务调度系统中尤为重要,比如系统中有一些紧急任务和普通任务,通过优先级队列可以确保紧急任务优先得到处理,从而保证系统的高效运行。

本文将深入探讨 ActiveMQ 的延迟消息与优先级队列这两个高级特性,并通过实战示例详细介绍它们的使用方法和注意事项,帮助读者更好地掌握这两个特性,提升在分布式系统开发中运用 ActiveMQ 的能力。

一、ActiveMQ 基础回顾

1.1 简介

ActiveMQ 是 Apache 软件基金会所研发的开放源代码消息中间件,作为一种纯 Java 程序,只要操作系统支持 Java 虚拟机,它便可执行。它的设计目标是在尽可能多的平台和语言上提供标准的、消息驱动的应用集成 ,具备多种强大特性。

在语言支持方面,它允许使用 Java、C、C++、C#、Ruby、Perl、Python、PHP 等多种语言编写客户端,极大地拓宽了其适用范围,让不同技术栈的开发者都能轻松使用。在协议支持上,涵盖 OpenWire、Stomp REST、WS Notification、XMPP、AMQP 等,使其能适应各种复杂的网络环境和应用场景。

ActiveMQ 完全支持 JMS1.1 和 J2EE 1.4 规范,包括持久化、XA 消息、事务等功能,这使得它在企业级应用开发中表现出色,能够满足企业对于消息处理的严格要求。同时,它对 Spring 框架有着良好的支持,可以很容易地内嵌到使用 Spring 的系统里面去,并且支持 Spring2.0 的特性,方便了基于 Spring 框架的项目集成和开发 。此外,它还通过了常见 J2EE 服务器(如 Geronimo、JBoss 4、GlassFish、WebLogic)的测试,借助 JCA 1.5 resource adaptors 的配置,能够自动部署到任何兼容 J2EE 1.4 的商业服务器上 。

ActiveMQ 支持多种传送协议,如 in-VM、TCP、SSL、NIO、UDP、Jgroups、JXTA 等,为不同的应用场景提供了灵活的选择。在消息持久化方面,支持通过 JDBC 和 journal 提供高速的消息持久化,保证了消息在系统故障等情况下的可靠性。从设计架构上,它保证了高性能的集群、客户端 - 服务器、点对点等通信模式的实现,还支持 Ajax 以及与 Axis 的整合,并且可以很容易地调用内嵌 JMS provider 进行测试。

由于这些特性,ActiveMQ 被广泛应用于各种场景。在电商系统中,像京东、淘宝这类大型电商平台,在处理订单、库存、物流等模块间的通信时,ActiveMQ 可以发挥异步处理和应用解耦的作用,提高系统的响应速度和稳定性。在分布式系统开发中,它能实现不同服务之间的可靠消息传递,确保系统的各个部分能够高效协同工作。

1.2 核心组件与工作原理

  • Broker:Broker 是 ActiveMQ 的核心组件,负责接收、存储和传递消息 ,可以将其看作是一个消息服务器。它可以运行在单机上,也可以分布在多个节点上组成集群,以实现高可用性和负载均衡。比如在一个大型的分布式电商系统中,可能会部署多个 Broker 节点,共同承担处理大量订单消息、库存更新消息等任务,防止单个节点因负载过高而出现性能瓶颈。
  • Connection:Connection 是生产者和消费者与 Broker 之间的通信链路 ,就像是一条连接客户端(生产者或消费者)和消息服务器(Broker)的桥梁。它可以是 TCP 连接、SSL 连接或者 HTTP 连接等。当一个订单系统(生产者)要向 ActiveMQ 发送订单消息时,首先需要建立一个到 Broker 的 Connection,通过这个连接来传输消息。
  • Session:Session 是生产者和消费者之间的通信会话 ,它可以是同步会话,也可以是异步会话。在 Session 中可以创建消息的生产者(MessageProducer)、消费者(MessageConsumer)以及消息的目的地(Destination,如队列 Queue 或主题 Topic)。例如,在一个物流系统(消费者)从 ActiveMQ 接收订单配送消息的过程中,会在一个 Session 内创建 MessageConsumer 来接收消息。
  • Destination:Destination 是消息的接收端 ,分为队列(Queue)和主题(Topic)两种类型。队列是一种先进先出(FIFO)的数据结构,生产者将消息发送到队列,消费者从队列中按照先进先出的顺序取消息进行处理,适用于一对一的消息通信场景,比如订单系统发送订单消息到队列,库存系统从队列中获取消息更新库存。主题则采用发布 / 订阅模式,一个生产者可以向主题发送消息,多个消费者可以订阅该主题并接收到相同的消息,适用于一对多的广播通信场景,比如系统发布公告消息到主题,多个相关的业务模块都可以订阅该主题获取公告内容。
  • MessageProducer:消息生产者,负责将消息发送到 Destination 。比如电商系统中的订单模块,在用户下单后,订单模块作为 MessageProducer 将订单相关消息发送到指定的 Queue 或 Topic。
  • MessageConsumer:消息消费者,负责从 Destination 接收消息 。如电商系统中的物流模块,作为 MessageConsumer 从对应的 Queue 或 Topic 中接收订单消息,从而安排后续的物流配送任务。

消息的生产和消费过程如下:

  1. 消息生产:生产者首先创建一个 ConnectionFactory,通过它创建与 Broker 的 Connection。接着,在这个 Connection 上创建 Session。在 Session 中创建 Destination(Queue 或 Topic)以及 MessageProducer。生产者创建消息对象(如 TextMessage、ObjectMessage 等),设置好消息的内容和属性后,通过 MessageProducer 将消息发送到指定的 Destination。例如,在一个在线教育平台中,当用户购买课程后,订单系统作为生产者,创建一个包含订单信息(课程 ID、用户 ID、购买时间等)的 TextMessage,通过 MessageProducer 发送到名为 “orderQueue” 的队列中。
  1. 消息消费:消费者同样先创建 ConnectionFactory 和 Connection,然后在 Connection 上创建 Session,并在 Session 中创建与生产者发送消息时相同的 Destination 以及 MessageConsumer。消费者通过 MessageConsumer 接收消息,可以采用同步阻塞方式(如Message message = consumer.receive();)等待接收消息,也可以设置消息监听器(consumer.setMessageListener(new MessageListener() {... });)以异步方式接收消息。当接收到消息后,消费者对消息进行处理。比如课程管理系统作为消费者,从 “orderQueue” 队列中接收到订单消息后,解析消息内容,更新课程的销售记录等。

二、延迟消息实战

2.1 延迟消息概念与应用场景

延迟消息是指消息在发送后,并不会立即被投递到消费者,而是在经过指定的时间延迟后才被投递 。这种特性在许多实际应用场景中都非常有用。

在电商系统中,订单超时处理是一个常见的场景。当用户下单后,如果在规定的时间内(如 30 分钟)未完成支付,系统需要自动取消订单并释放库存。通过发送延迟消息,在用户下单时,向消息队列发送一条延迟 30 分钟的消息,消息内容包含订单信息。30 分钟后,消息被投递,消费者接收到消息后检查订单状态,如果订单仍未支付,则执行取消订单和释放库存的操作。

在任务定时执行场景中,比如每天凌晨需要执行数据备份任务,或者每周一需要发送周报提醒。可以在系统中设置定时任务,在合适的时间点发送延迟消息,消息到达消费者后触发相应的任务执行逻辑 。例如,在每天凌晨 0 点,系统发送一条延迟 1 分钟的消息,消费者接收到消息后启动数据备份任务,这样可以避免在整点时刻系统负载过高时执行备份任务,影响其他业务的正常运行。

在物流系统中,当货物到达目的地后,可能需要在一段时间后(如 2 小时)自动确认收货并更新物流状态。通过延迟消息,在货物到达目的地时发送一条延迟 2 小时的消息,消息包含物流单号等信息,2 小时后消息被投递,消费者根据消息内容确认收货并更新物流状态,提高物流处理的自动化程度 。

2.2 ActiveMQ 实现延迟消息的方式

2.2.1 使用 TimeToLive 属性

通过设置消息的 TimeToLive(TTL)属性可以实现延迟投递。TTL 属性表示消息在队列中的存活时间,单位为毫秒。当生产者发送消息时,设置 TTL 属性为一个大于 0 的值,消息并不会立即被投递,而是在经过 TTL 时间后才会被投递到消费者 。

例如,以下是使用 Java 代码通过设置 TimeToLive 属性实现延迟消息发送的生产者示例:

 

import javax.jms.*;

import org.apache.activemq.ActiveMQConnectionFactory;

public class DelayedMessageProducer {

private static final String BROKER_URL = "tcp://localhost:61616";

private static final String QUEUE_NAME = "DelayedMessageQueue";

public static void main(String[] args) throws JMSException {

// 创建连接工厂

ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(BROKER_URL);

// 创建连接

Connection connection = connectionFactory.createConnection();

// 启动连接

connection.start();

// 创建会话

Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

// 创建队列

Destination destination = session.createQueue(QUEUE_NAME);

// 创建消息生产者

MessageProducer producer = session.createProducer(destination);

// 创建文本消息

TextMessage message = session.createTextMessage("这是一条延迟消息");

// 设置消息的TimeToLive属性为5000毫秒,即5秒后投递

message.setJMSExpiration(System.currentTimeMillis() + 5000);

// 发送消息

producer.send(message);

System.out.println("延迟消息已发送");

// 关闭资源

producer.close();

session.close();

connection.close();

}

}

消费者代码示例如下:

 

import javax.jms.*;

import org.apache.activemq.ActiveMQConnectionFactory;

public class DelayedMessageConsumer {

private static final String BROKER_URL = "tcp://localhost:61616";

private static final String QUEUE_NAME = "DelayedMessageQueue";

public static void main(String[] args) throws JMSException {

// 创建连接工厂

ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(BROKER_URL);

// 创建连接

Connection connection = connectionFactory.createConnection();

// 启动连接

connection.start();

// 创建会话

Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

// 创建队列

Destination destination = session.createQueue(QUEUE_NAME);

// 创建消息消费者

MessageConsumer consumer = session.createConsumer(destination);

// 接收消息,这里采用同步阻塞方式接收消息

Message message = consumer.receive();

if (message != null && message instanceof TextMessage) {

TextMessage textMessage = (TextMessage) message;

System.out.println("接收到延迟消息:" + textMessage.getText());

}

// 关闭资源

consumer.close();

session.close();

connection.close();

}

}

在上述代码中,生产者创建了一条文本消息,并设置了消息的JMSExpiration属性(即 TTL)为当前时间加上 5000 毫秒,这样消息会在 5 秒后被投递。消费者通过receive方法接收消息,当消息被投递时,消费者可以接收到并处理该消息。

2.2.2 使用 Scheduled Message 机制

ActiveMQ 的 Scheduled Message 机制提供了更灵活的延迟消息设置方式 。它允许通过设置消息的属性来实现延迟投递、定时重复投递等功能。

主要涉及以下几个属性:

  • AMQ_SCHEDULED_DELAY:消息延迟发送的时间,单位为毫秒 。例如,设置该属性为 60000,表示消息将在 60 秒后发送。
  • AMQ_SCHEDULED_PERIOD:每次重新发送该消息的时间间隔,单位为毫秒 。如果设置了该属性,消息在延迟发送后,会按照这个时间间隔重复发送。
  • AMQ_SCHEDULED_REPEAT:重新发送该消息的次数 。结合AMQ_SCHEDULED_PERIOD属性,可以实现消息的多次重复发送。
  • AMQ_SCHEDULED_CRON:使用 Cron 表达式设置发送该消息的时机 。通过 Cron 表达式,可以实现更复杂的定时任务,比如每天凌晨 3 点发送消息。

要使用 Scheduled Message 机制,需要在activemq.xml配置文件中开启 schedulerSupport属性,即在broker节点上添加schedulerSupport="true",如下所示:

 

<broker xmlns="http://activemq.apache.org/schema/core" schedulerSupport="true">

<!-- 其他配置 -->

</broker>

以下是基于 Spring Boot 的代码示例,展示如何使用 Scheduled Message 机制发送延迟消息:

首先,在pom.xml文件中添加 ActiveMQ 和 Spring JMS 的依赖:

 

<dependencies>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-activemq</artifactId>

</dependency>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-jms</artifactId>

</dependency>

</dependencies>

然后,在application.yml文件中配置 ActiveMQ 的连接信息:

 

spring:

activemq:

broker-url: tcp://localhost:61616

user: admin

password: admin

接着,创建消息发送服务类:

 

import org.apache.activemq.ScheduledMessage;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.jms.core.JmsTemplate;

import org.springframework.stereotype.Service;

@Service

public class ScheduledMessageService {

@Autowired

private JmsTemplate jmsTemplate;

public void sendScheduledMessage(String destinationName, String messageContent, long delay, long period, int repeat) {

jmsTemplate.send(destinationName, session -> {

// 创建文本消息

javax.jms.TextMessage textMessage = session.createTextMessage(messageContent);

// 设置延迟发送时间

textMessage.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_DELAY, delay);

// 设置重复发送时间间隔

if (period > 0) {

textMessage.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_PERIOD, period);

}

// 设置重复发送次数

if (repeat > 0) {

textMessage.setIntProperty(ScheduledMessage.AMQ_SCHEDULED_REPEAT, repeat);

}

return textMessage;

});

}

}

最后,在测试类中调用发送方法:

 

import org.junit.jupiter.api.Test;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest

public class ScheduledMessageTest {

@Autowired

private ScheduledMessageService scheduledMessageService;

@Test

public void testSendScheduledMessage() {

// 发送延迟消息,延迟60秒发送,不重复发送

scheduledMessageService.sendScheduledMessage("ScheduledMessageQueue", "这是一条定时延迟消息", 60000, 0, 0);

}

}

在上述代码中,通过ScheduledMessageService类的sendScheduledMessage方法发送延迟消息,设置了消息的延迟时间为 60 秒,不设置重复发送时间间隔和次数。在测试类中调用该方法,即可发送延迟消息 。消费者的代码与前面使用 TimeToLive 属性时的消费者代码类似,通过监听队列接收消息并处理。

2.3 实战案例与代码实现

2.3.1 案例背景与需求分析

假设我们正在开发一个电商系统,其中订单模块需要实现订单支付超时取消的功能。当用户下单后,系统生成订单并发送到消息队列,同时设置订单的支付超时时间为 30 分钟。如果在 30 分钟内用户未完成支付,系统需要自动取消订单,并将订单状态更新为 “已取消”,同时释放订单中占用的库存 。

为了实现这个功能,我们可以利用 ActiveMQ 的延迟消息特性。在用户下单时,向 ActiveMQ 发送一条包含订单信息的延迟消息,延迟时间设置为 30 分钟。30 分钟后,消息被投递到消费者,消费者接收到消息后检查订单的支付状态,如果订单未支付,则执行取消订单和释放库存的操作 。

2.3.2 代码实现与配置

首先,创建一个 Spring Boot 项目,并在pom.xml文件中添加 ActiveMQ 和 Spring JMS 的依赖:

 

<dependencies>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-activemq</artifactId>

</dependency>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-jms</artifactId>

</dependency>

</dependencies>

然后,在application.yml文件中配置 ActiveMQ 的连接信息:

 

spring:

activemq:

broker-url: tcp://localhost:61616

user: admin

password: admin

接下来,创建订单实体类Order:

 

import java.io.Serializable;

public class Order implements Serializable {

private static final long serialVersionUID = 1L;

private Long orderId;

private String orderNo;

private String status;

// 其他订单相关属性和getter、setter方法

}

创建消息发送服务类OrderMessageSender:

 

import org.apache.activemq.ScheduledMessage;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.jms.core.JmsTemplate;

import org.springframework.stereotype.Service;

@Service

public class OrderMessageSender {

@Autowired

private JmsTemplate jmsTemplate;

public void sendOrderMessage(Order order, long delay) {

jmsTemplate.send("OrderQueue", session -> {

// 创建对象消息,因为要传递订单对象

javax.jms.ObjectMessage objectMessage = session.createObjectMessage(order);

// 设置延迟发送时间,单位毫秒

objectMessage.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_DELAY, delay);

return objectMessage;

});

}

}

创建消息接收服务类OrderMessageReceiver:

 

import org.springframework.jms.annotation.JmsListener;

import org.springframework.stereotype.Service;

@Service

public class OrderMessageReceiver {

@JmsListener(destination = "OrderQueue")

public void receiveOrderMessage(Order order) {

// 检查订单支付状态,这里假设订单实体中有支付状态字段,实际应用中需要从数据库查询

if ("未支付".equals(order.getStatus())) {

// 执行取消订单操作,更新订单状态到数据库

order.setStatus("已取消");

// 模拟释放库存操作

System.out.println("订单 " + order.getOrderNo() + " 支付超时,已取消,库存已释放");

} else {

System.out.println("订单 " + order.getOrderNo() + " 已支付,无需取消");

}

}

}

在ActiveMQ的配置文件activemq.xml中,确保开启了 schedulerSupport属性:

 

<broker xmlns="http://activemq.apache.org/schema/core" schedulerSupport="true">

<!-- 其他配置 -->

</broker>

在订单创建的业务逻辑中,调用消息发送服务发送延迟消息:

 

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.web.bind.annotation.PostMapping;

import org.springframework.web.bind.annotation.RequestBody;

import org.springframework.web.bind.annotation.RestController;

@RestController

public class OrderController {

@Autowired

private OrderMessageSender orderMessageSender;

@PostMapping("/orders")

public String createOrder(@RequestBody Order order) {

// 模拟订单创建,设置订单编号和初始状态

order.setOrderNo("20240101001");

order.setStatus("未支付");

// 发送延迟消息,延迟30分钟,单位毫秒

orderMessageSender.sendOrderMessage(order, 30 * 60 * 1000);

return "订单已创建,等待支付";

}

}

2.3.3 测试与验证

启动 ActiveMQ 服务和 Spring Boot 应用。使用 Postman 等工具向/orders接口发送 POST 请求,请求体中包含订单信息,模拟用户下单操作 。

发送请求后,查看控制台输出,确认订单消息已发送。等待 30 分钟后,再次查看控制台输出,应该能看到订单支付超时取消的相关信息,如 “订单 20240101001 支付超时,已取消,库存已释放” 。

为了更准确地验证,可以在数据库中查看订单状态是否已更新为 “已取消”,以及库存相关数据是否已恢复到订单创建前的状态 。通过以上测试,可以验证延迟消息是否按照预期时间投递和消费,以及订单支付超时取消功能是否正常工作。

相关文章:

ActiveMQ 高级特性:延迟消息与优先级队列实战(一)

引言 在当今的分布式系统开发中&#xff0c;消息中间件扮演着至关重要的角色&#xff0c;而 ActiveMQ 作为一款广泛使用的开源消息中间件&#xff0c;凭借其丰富的特性和良好的性能&#xff0c;深受开发者的青睐。它支持多种消息模型&#xff0c;如点对点和发布 / 订阅&#x…...

动手学深度学习12.4.硬件-笔记练习(PyTorch)

以下内容为结合李沐老师的课程和教材补充的学习笔记&#xff0c;以及对课后练习的一些思考&#xff0c;自留回顾&#xff0c;也供同学之人交流参考。 本节课程地址&#xff1a;31 深度学习硬件&#xff1a;CPU 和 GPU【动手学深度学习v2】_哔哩哔哩_bilibili 本节教材地址&am…...

LAN-402 全国产信号采集处理模块K7-325T(4通道采集)

UD LAN-402全国产化信号处理模块最多支持2通道16bit125Msps的短波采集&#xff08;或2通道14bit250Msps超短波采集&#xff09;、2通道16bit310Msps超短波采集&#xff0c;可选配XC7K325T、XC7K410T、JFM7K325T、JFM7K410T FPGA芯片&#xff0c;对外支持PCIe2.0x8接口、千兆网、…...

关于大语言模型的困惑度(PPL)指标优势与劣势

1. 指标本身的局限性 与人类感知脱节&#xff1a; PPL衡量的是模型对词序列的预测概率&#xff08;基于交叉熵损失&#xff09;&#xff0c;但低困惑度未必对应高质量的生成结果。例如&#xff1a; 模型可能生成语法正确但内容空洞的文本&#xff08;PPL低但质量差&#xff09;…...

[Spring AOP 8] Spring AOP 源码全流程总结

Spring AOP总结 更美观清晰的版本在&#xff1a;Github 前面的章节&#xff1a; [Spring AOP 1] 从零开始的JDK动态代理 [Spring AOP 2] 从零开始的CGLIB动态代理 [Spring AOP 3] Spring选择代理 [Spring AOP 4] Spring AOP 切点匹配 [Spring AOP 5] 高级切面与低级切面&#…...

通信网络编程——JAVA

1.计算机网络 IP 定义与作用 &#xff1a;IP 地址是在网络中用于标识设备的数字标签&#xff0c;它允许网络中的设备之间相互定位和通信。每一个设备在特定网络环境下都有一个唯一的 IP 地址&#xff0c;以此来确定其在网络中的位置。 分类 &#xff1a;常见的 IP 地址分为 I…...

支持向量机算法

支持向量机&#xff08;Support Vector Machine&#xff0c;SVM&#xff09;作为机器学习领域中一颗耀眼的明星&#xff0c;凭借其卓越的分类与回归能力&#xff0c;在众多算法中独树一帜。它宛如一位精准的边界守护者&#xff0c;通过巧妙地构建超平面&#xff0c;将不同类别的…...

Redis集群模式、持久化、过期策略、淘汰策略、缓存穿透雪崩击穿问题

Redis四种模式 单节点模式 架构​​&#xff1a;单个Redis实例运行在单台服务器。 ​​优点​​&#xff1a; ​​简单​​&#xff1a;部署和配置容易&#xff0c;适合开发和测试。 ​​低延迟​​&#xff1a;无网络通信开销。 ​​缺点​​&#xff1a; ​​单点故障​​&…...

【WPF】Opacity 属性的使用

在WPF&#xff08;Windows Presentation Foundation&#xff09;中&#xff0c;Opacity 属性是定义一个元素透明度的属性&#xff0c;其值范围是从 0.0&#xff08;完全透明&#xff09;到 1.0&#xff08;完全不透明&#xff09;。由于 Opacity 是在 UIElement 类中定义的&…...

编程题 02-线性结构3 Reversing Linked List【PAT】

文章目录 题目输入格式输出格式输入样例输出样例 题解解题思路完整代码 编程练习题目集目录 题目 Given a constant K K K and a singly linked list L L L, you are supposed to reverse the links of every K K K elements on L L L. For example, given L being 1 → …...

集成指南:如何采用融云 Flutter IMKit 实现双端丝滑社交体验

在移动应用开发领域&#xff0c;跨平台框架的广泛应用已成为一种趋势。 融云跨平台方案持续升级&#xff0c;近期正式上线 Flutter IMKit&#xff0c;uni-app IMKit 也将紧随其后向广大开发者开放。覆盖两大跨平台核心框架&#xff0c;一套代码即可支持 Android、iOS 双端丝滑…...

使用vite重构vue-cli的vue3项目

一、修改依赖 首先修改 package.json&#xff0c;修改启动方式与相应依赖 移除vue-cli并下载vite相关依赖&#xff0c;注意一些peerDependency如fast-glob需要手动下载 # 移除 vue-cli 相关依赖 npm remove vue/cli-plugin-babel vue/cli-plugin-eslint vue/cli-plugin-rout…...

LeetCode 2094.找出 3 位偶数:遍历3位偶数

【LetMeFly】2094.找出 3 位偶数&#xff1a;遍历3位偶数 力扣题目链接&#xff1a;https://leetcode.cn/problems/finding-3-digit-even-numbers/ 给你一个整数数组 digits &#xff0c;其中每个元素是一个数字&#xff08;0 - 9&#xff09;。数组中可能存在重复元素。 你…...

FLASH闪存(擦除、编译)

FLASH闪存 文章目录 FLASH闪存1.存储器映像位置2.FLASH简介3.闪存模块组织3.2闪存的共性&#xff1a; 4.FLASH基本结构4.1FLASH解锁4.2使用指针访问寄存器 5.选项字节5.1选项字节编程5.2选项字节擦除 6.相关函数介绍7.读取内部FLASH&#xff08;实操&#xff09;7.1接线图7.2工…...

企业即时通讯软件,私有化安全防泄密

在数字化转型与信创战略双重驱动下&#xff0c;企业对即时通讯工具的需求已从基础沟通转向安全可控、高效协同的综合能力。BeeWorks作为一款专为政企设计的私有化即时通讯与协同办公平台&#xff0c;凭借其全链路安全架构、深度国产化适配及灵活的业务集成能力&#xff0c;成为…...

直方图特征结合 ** 支持向量机图片分类

一、核心技术框架 1. 直方图特征原理 颜色直方图&#xff1a;统计图像中每个颜色区间&#xff08;如 RGB 通道&#xff09;的像素数量&#xff0c;反映颜色分布。HOG 直方图&#xff08;方向梯度直方图&#xff09;&#xff1a;统计图像局部区域的梯度方向分布&#xff0c;捕…...

【prometheus+Grafana篇】基于Prometheus+Grafana实现windows操作系统的监控与可视化

&#x1f4ab;《博主主页》&#xff1a; &#x1f50e; CSDN主页 &#x1f50e; IF Club社区主页 &#x1f525;《擅长领域》&#xff1a;擅长阿里云AnalyticDB for MySQL(分布式数据仓库)、Oracle、MySQL、Linux、prometheus监控&#xff1b;并对SQLserver、NoSQL(MongoDB)有了…...

PyTorch实战(4)——卷积神经网络(Convolutional Neural Network, CNN)详解

PyTorch实战&#xff08;4&#xff09;——卷积神经网络详解 0. 前言1. 全连接网络的缺陷2. 卷积神经网络基本组件2.1 卷积2.2 步幅和填充2.3 池化2.3 卷积神经网络完整流程 3. 卷积和池化相比全连接网络的优势4. 使用 PyTorch 构建卷积神经网络4.1 使用 PyTorch 构建 CNN 架构…...

【Python】Python常用控制结构详解:条件判断、遍历与循环控制

Python提供了多种控制结构来处理逻辑判断和循环操作&#xff0c;包括if-else条件分支、switch替代方案、遍历方法以及循环控制语句break和continue。以下是对这些功能的详细说明及示例&#xff1a; 一、条件判断&#xff1a;if-else与多分支结构 单分支结构 • 语法&#xff1…...

在Linux中安装JDK并且搭建Java环境

1.首先准备好JDK的Linux的安装包 2.打开Linux,进入root的文件夹,直接拖入即可 3.输入解压命令,后面指定的是位置&#xff08;注意不要填写错误&#xff0c;就填写这个&#xff09; 4.之后进入我们安装的jdk的文件 利用pwd命令&#xff0c;展示我们安装的目录&#xff0c;之后…...

理解多智能体深度确定性策略梯度MADDPG算法:基于python从零实现

引言&#xff1a;多智能体强化学习&#xff08;MARL&#xff09; 多智能体强化学习&#xff08;MARL&#xff09;将强化学习拓展到多个智能体在共享环境中相互交互的场景。这些智能体可能相互合作、竞争&#xff0c;或者目标混杂。MARL 引入了单智能体设置中不存在的独特挑战。…...

【AI大语言模型本质分析框架】

AI大语言模型本质分析框架 ——从教育危机到智能本质的七层递进式解构 第一层&#xff1a;现象观察——阴&#xff08;显性危机&#xff09;与阳&#xff08;隐性变革&#xff09;的共存 观点1&#xff08;阴&#xff09;&#xff1a;AI作弊泛滥&#xff0c;传统教育体系崩溃…...

算法模型部署后_python脚本API测试指南-记录3

API 测试指南 服务运行后&#xff0c;可以通过以下方式测试&#xff1a; Curl: curl -X POST -F "file./test_dataset/surface/surface57.png" http://<服务器IP>:9000/api/v1/predictPython 脚本: (参考 svm_request测试.py) import requestsurl http://…...

鸿蒙(HarmonyOS)应用开发入门教程

目录 第一章:鸿蒙系统简介 1.1 什么是鸿蒙系统? 1.2 鸿蒙系统架构 第二章:开发环境搭建 2.1 安装DevEco Studio 步骤1:下载与安装 步骤2:首次配置 步骤3:设备准备 2.2 创建第一个项目 第三章:鸿蒙应用开发基础 3.1 核心概念:Ability与AbilitySlice 示例代码…...

MIT XV6 - 1.6 Lab: Xv6 and Unix utilities -uptime

接上文 MIT XV6 - 1.5 Lab: Xv6 and Unix utilities - xargs 第一章持续有点久了&#xff0c;虽然肯定有些特点和细节还没注意到&#xff0c;但这次的主要目的是学习内核部分&#xff0c;决定水一篇然后进入第二章节 uptime 第一章的最后一个实验&#xff0c;选做性质&#xf…...

Python语言在地球科学交叉领域中的应用——从数据可视化到常见数据分析方法的使用【实例操作】

前言&#xff1a; Python是功能强大、免费、开源&#xff0c;实现面向对象的编程语言&#xff0c;Python能够运行在Linux、Windows、Macintosh、AIX操作系统上及不同平台&#xff08;x86和arm&#xff09;&#xff0c;Python简洁的语法和对动态输入的支持&#xff0c;再加上解释…...

flutter 的 json序列化和反序列化

一、json转实体 Instantly parse JSON in any language | quicktype 二、实体中的toJson和fromJson 实现 官方推荐的 两个插件(个人觉得一个实体会多一个.g.dart 文件太多了&#xff0c;不喜欢) json_annotation json_serializable 三、使用 dart_json_mapper 实现上面的功…...

什么是数据集市(Data Mart)?

数据集市&#xff08;Data Mart&#xff09;是数据仓库&#xff08;Data Warehouse&#xff09;的一个子集&#xff0c;专门针对某个特定业务部门、业务线或主题领域&#xff0c;存储和管理该部门或领域所需的特定数据。它通常包含从企业范围的数据仓库中抽取、筛选和汇总的部分…...

从攻击者角度来看Go1.24的路径遍历攻击防御

目录 一、具体攻击示例 程序 攻击步骤&#xff1a; 二、为什么攻击者能成功&#xff1f; 分析 类比理解 总结 三、TOCTOU 竞态条件漏洞 1、背景&#xff1a;符号链接遍历攻击 2. TOCTOU 竞态条件漏洞 3. 另一种变体&#xff1a;目录移动攻击 4. 问题的核心 四、防…...

[ARM][汇编] 01.基础概念

目录 1.全局标号 1.1.使用方法 1.1.1.声明全局标号 1.1.2.定义全局标号 1.1.3.引用全局标号 1.2.全局标号与局部标号的区别 1.3.注意事项 2.局部标号 2.1.使用方法 2.1.1.定义局部标号 2.1.2.跳转引用 2.2.局部标号与全局标号的对比 2.3.注意事项 3.符号定义伪指…...

杭州电商全平台代运营领军者——品融电商

杭州电商全平台代运营领军者——品融电商&#xff1a;以“效品合一”驱动品牌全域增长 在电商行业竞争日益白热化的当下&#xff0c;品牌如何突破流量焦虑、实现长效增长&#xff1f;作为中国领先的品牌化电商服务商&#xff0c;杭州品融电商&#xff08;PINKROON&#xff09;…...

02.Golang 切片(slice)源码分析(一、定义与基础操作实现)

Golang 切片&#xff08;slice&#xff09;源码分析&#xff08;一、定义与基础操作实现&#xff09; 注意当前go版本代码为1.23 一、定义 slice 的底层数据是数组&#xff0c;slice 是对数组的封装&#xff0c;它描述一个数组的片段。两者都可以通过下标来访问单个元素。 数…...

当生产了~/qt-arm/bin/qmake,可以单独编译其他-源码的某个模块,如下,编译/qtmultimedia

cd ~/qt-everywhere-src-5.15.2/qtmultimedia # 设置交叉编译器和 qmake 路径 export CC/usr/bin/aarch64-linux-gnu-gcc export CXX/usr/bin/aarch64-linux-gnu-g export QMAKE~/qt-arm/bin/qmake # 使用已安装的 qmake export QT_INSTALL_PREFIX~/qt-arm # 安装路径 # 配…...

WordPress 网站上的 jpg、png 和 WebP 图片插件

核心功能 1. 转换 AVIF 并压缩 AVIF 将您 WordPress 网站上的 jpg、png 和 WebP 图片转换为 AVIF 格式&#xff0c;并根据您设置的压缩级别压缩 AVIF 图片。如果原始图片已经是 WordPress 6.5 以上支持的 AVIF 格式&#xff0c;则原始 AVIF 图片将仅被压缩。 2. 转换 WebP 并…...

构造+简单树状

昨日的牛客周赛算是比较简单的&#xff0c;其中最后一道构造题目属实眼前一亮。 倒数第二个题目也是一个很好的模拟题目&#xff08;考验对二叉树的理解和代码的细节&#xff09; 给定每一层的节点个数&#xff0c;自己拟定一个父亲节点&#xff0c;构造一个满足条件的二叉树。…...

Flask支持哪些日志框架

目录 ✅ Flask 默认支持的日志框架 ✅ 默认推荐:logging(标准库) ✅ 进阶推荐:Loguru(更优雅的日志库) ✅ Flask 日志级别说明(与标准库一致) ✅ 生产环境建议 ✅ 总结推荐 在 Flask 中,默认的日志系统是基于 Python 标准库 logging 模块 构建的。 ✅ Flask 默认…...

健康养生指南:解锁活力生活的科学密码

健康是人生最珍贵的财富&#xff0c;在快节奏的现代生活中&#xff0c;掌握科学的养生方法至关重要。虽然不借助中医理念&#xff0c;我们依然可以从饮食、运动、睡眠等多个方面入手&#xff0c;打造健康生活方式。 合理的饮食是健康的基石。遵循均衡饮食原则&#xff0c;保证每…...

SAR图像压缩感知

SAR图像压缩感知 matlab代码 对应着汕大闫老师的那本压缩感知及其应用&#xff0c;有需要的可以看一下&#xff01;&#xff01; SAR图像压缩感知/baboon.bmp , 66616 SAR图像压缩感知/camera.bmp , 66616 SAR图像压缩感知/DWT.m , 1265 SAR图像压缩感知/Gauss.m , 373 SAR图像…...

定时器设计

定时器设计的必要性 服务器中的定时器设计具有多方面的必要性&#xff0c;主要体现在以下几个关键方面&#xff1a; 任务调度与管理 定时任务执行&#xff1a;服务器常常需要执行一些定时性的任务&#xff0c;如定时备份数据、定时清理缓存、定时更新系统日志等。通过定时器可…...

Spring Boot整合Kafka实战指南:从环境搭建到消息处理全解析

一、环境准备 安装 Kafka 下载 Kafka&#xff1a;从 Apache Kafka 官网下载对应版本的 Kafka。 解压并启动 Kafka&#xff1a; # 启动 Zookeeper&#xff08;Kafka 依赖 Zookeeper&#xff09; bin/zookeeper-server-start.sh config/zookeeper.properties# 启动 Kafka bin/ka…...

(done) 补充:xv6 的一个用户程序 init 是怎么启动的 ?它如何启动第一个 bash ?

先看 main.c 从函数名来看&#xff0c;比较相关的就 userinit() 和 scheduler() #include "types.h" #include "param.h" #include "memlayout.h" #include "riscv.h" #include "defs.h"volatile static int started 0;//…...

AI 搜索引擎 MindSearch

背景 RAG是一种利用文档减少大模型的幻觉&#xff0c;AI搜索也是 AI 搜索引擎 MindSearch 是一个开源的 AI 搜索引擎框架&#xff0c;具有与 Perplexity.ai Pro 相同的性能。您可以轻松部署它来构建您自己的搜索引擎&#xff0c;可以使用闭源 LLM&#xff08;如 GPT、Claude…...

HTML简单语法标签(后续实操:云备份项目)

以下是一些 HTML 的简单语法标签及其功能介绍&#xff1a; 基本结构标签 <!DOCTYPE html>&#xff1a;声明文档类型为 HTML5<html>&#xff1a;HTML 文档的根标签<head>&#xff1a;包含文档元数据&#xff08;如标题、字符编码等&#xff09;<title>…...

CentOS 和 RHEL

CentOS 和 RHEL&#xff08;Red Hat Enterprise Linux&#xff09;关系非常紧密&#xff0c;简而言之&#xff1a; CentOS 最初是 RHEL 的免费、开源克隆版&#xff0c;几乎与 RHEL 二进制兼容。 CentOS 原是 RHEL 的“免费双胞胎”&#xff0c;但已被放弃&#xff0c;现在推荐…...

java----------->代理模式

目录 什么是代理模式&#xff1f; 为什么会有代理模式&#xff1f; 怎么写代理模式&#xff1f; 实现代理模式总共需要三步&#xff1a; 什么是代理模式&#xff1f; 代理模式&#xff1a;给目标对象提供一个代理对象&#xff0c;并且由代理对象控制目标对象的引用 代理就是…...

Wpf学习片段

IRegionManager 和IContainerExtension IRegionManager 是 Prism 框架中用于管理 UI 区域&#xff08;Regions&#xff09;的核心接口&#xff0c;它实现了模块化应用中视图&#xff08;Views&#xff09;的动态加载、导航和生命周期管理。 IContainerExtension 是依赖注入&…...

智能手表测试用例文档

智能手表测试用例文档 产品名称&#xff1a;智能手表 A1 版本号&#xff1a;FW v1.0.0 测试负责人&#xff1a;[填写] 编写时间&#xff1a;2025-xx-xx 文档状态&#xff1a;初次版本 &#x1f4c1; 测试用例结构说明 字段描述用例编号测试用例唯一编号&#xff0c;如 TC-FUN…...

密码学--希尔密码

一、实验目的 1、通过实现简单的古典密码算法&#xff0c;理解密码学的相关概念 2、理解明文、密文、加密密钥、解密密钥、加密算法、解密算法、流密码与分组密码等。 二、实验内容 1、题目内容描述 ①定义分组字符长度 ②随机生成加密密钥&#xff0c;并验证密钥的可行性 …...

配置Hadoop集群-集群配置

以下是 Hadoop 集群的核心配置步骤&#xff0c;基于之前的免密登录和文件同步基础&#xff0c;完成 Hadoop 分布式环境的搭建&#xff1a; 1. 集群规划 假设集群包含 3 个节点&#xff1a; master&#xff1a;NameNode、ResourceManagerslave1&#xff1a;DataNode、NodeMana…...

第三方软件测评中心分享:软件功能测试类型和测试工具

在数字化时代&#xff0c;软件测试已成为确保产品质量的重要环节。功能测试作为软件测试中的核心部分&#xff0c;关注于软件产品是否按预期功能正常运作。 软件功能测试可以按不同的方式进行分类&#xff0c;主要包括以下几种类型&#xff1a;   1.正功能测试&#xff1a;验…...