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

Spring Boot 与 RabbitMQ 的深度集成实践(三)

高级特性实现

消息持久化

在实际的生产环境中,消息的可靠性是至关重要的。消息持久化是确保 RabbitMQ 在发生故障或重启后,消息不会丢失的关键机制。它涉及到消息、队列和交换机的持久化配置。

首先,配置队列持久化。在创建队列时,将durable参数设置为true,表示该队列是持久化队列。当 RabbitMQ 服务器重启时,持久化队列会从磁盘中恢复,而不是被重新创建。例如,在之前创建队列的配置类中:

 

@Bean

public Queue directQueue() {

return new Queue("direct.queue", true);

}

这里创建的direct.queue队列通过true参数设置为持久化队列。这样,即使服务器出现故障,队列中的消息也不会丢失。

对于交换机,同样可以通过durable参数来设置持久化。以直连交换机为例:

 

@Bean

public DirectExchange directExchange() {

return new DirectExchange("direct.exchange", true, false);

}

direct.exchange交换机被设置为持久化,保证了在服务器重启后,交换机的配置信息仍然存在,不会影响消息的路由。

在消息层面,Spring AMQP 默认会将消息设置为持久化。当使用RabbitTemplate发送消息时,消息的MessageProperties中的deliveryMode属性默认被设置为MessageDeliveryMode.PERSISTENT,表示消息是持久化的。这意味着消息不仅会被存储在内存中,还会被写入磁盘,从而在服务器重启后仍然可用。例如,在生产者类RabbitMQProducer中发送消息时:

 

public void sendMessage(String exchange, String routingKey, String message) {

rabbitTemplate.convertAndSend(exchange, routingKey, message);

System.out.println("Sent message: " + message);

}

这里发送的消息会自动被标记为持久化,确保了消息在传输过程中的可靠性。通过配置消息、队列和交换机的持久化,可以大大提高消息系统的可靠性,避免因服务器故障导致的消息丢失问题,为企业级应用提供了坚实的消息保障。

消息确认机制

消息确认机制是保证消息在生产者和消费者之间可靠传递的重要手段,它分为生产者消息确认和消费者消息确认。

在生产者端,RabbitMQ 提供了confirm回调机制,用于确认消息是否成功发送到交换机。首先,在application.yml中开启publisher - confirm - type配置:

 

spring:

rabbitmq:

publisher - confirm - type: correlated

这表示开启了发布确认模式,当消息发送到交换机后,会触发回调方法。

然后,在配置类中为RabbitTemplate设置ConfirmCallback回调:

 

import org.springframework.amqp.rabbit.connection.ConnectionFactory;

import org.springframework.amqp.rabbit.core.RabbitTemplate;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

@Configuration

public class RabbitMQConfig {

@Bean

public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {

RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);

rabbitTemplate.setConfirmCallback((correlationData, ack, cause) -> {

if (ack) {

System.out.println("Message sent to exchange successfully, correlation data: " + correlationData);

} else {

System.out.println("Failed to send message to exchange, correlation data: " + correlationData + ", cause: " + cause);

}

});

return rabbitTemplate;

}

}

在这个回调中,correlationData包含了消息发送时的相关数据,如消息 ID 等;ack表示消息是否成功发送到交换机,true表示成功,false表示失败;cause则是失败的原因。通过这种方式,生产者可以根据回调结果来判断消息的发送状态,以便进行相应的处理,如记录日志、重新发送消息等。

对于消费者,RabbitMQ 支持自动确认和手动确认两种方式。自动确认是默认的方式,当消费者接收到消息后,RabbitMQ 会自动将消息从队列中移除。然而,这种方式存在一定的风险,如果消费者在处理消息过程中出现异常,消息已经被确认移除,可能会导致数据丢失。

手动确认则更加安全可靠。在application.yml中,可以将消费者的确认模式设置为手动确认:

 

spring:

rabbitmq:

listener:

simple:

acknowledge - mode: manual

在消费者类中,通过Channel对象来手动确认消息:

 

import org.springframework.amqp.rabbit.annotation.RabbitListener;

import org.springframework.amqp.core.Message;

import org.springframework.amqp.rabbit.core.ChannelAwareMessageListener;

import org.springframework.stereotype.Component;

import com.rabbitmq.client.Channel;

@Component

public class RabbitMQConsumer implements ChannelAwareMessageListener {

@RabbitListener(queues = "direct.queue")

@Override

public void onMessage(Message message, Channel channel) throws Exception {

try {

long deliveryTag = message.getMessageProperties().getDeliveryTag();

// 处理消息逻辑

System.out.println("Received message: " + new String(message.getBody()));

// 手动确认消息,multiple为false表示只确认当前消息

channel.basicAck(deliveryTag, false);

} catch (Exception e) {

long deliveryTag = message.getMessageProperties().getDeliveryTag();

// 处理异常,例如将消息放入死信队列或记录日志

System.out.println("Error processing message: " + e.getMessage());

// 拒绝消息,requeue为false表示不重新入队,消息会进入死信队列(如果配置了死信队列)

channel.basicNack(deliveryTag, false, false);

}

}

}

在手动确认模式下,消费者在成功处理消息后,通过channel.basicAck方法来确认消息;如果处理过程中出现异常,则通过channel.basicNack方法来拒绝消息,并可以根据业务需求决定是否将消息重新放入队列。这种方式确保了消息在被正确处理后才会从队列中移除,提高了消息处理的可靠性。

死信队列和延迟队列

死信队列(Dead Letter Queue,DLQ)是一种特殊的队列,用于处理那些无法被正常消费的消息。当消息在一个队列中变成死信(dead message)之后,它能被重新发送到另一个交换器中,这个交换器就是死信交换器(DLX),绑定 DLX 的队列就称为死信队列。

导致消息成为死信的常见原因有以下几种:

  • 消息被拒绝:当消费者使用basic.reject或basic.nack方法拒绝消息,并且设置requeue参数为false时,消息会成为死信。这通常发生在消息内容不符合预期,或者消费者处理消息时出现严重错误,无法继续处理该消息的情况下。例如,在处理订单消息时,如果消息格式错误,无法解析订单信息,消费者可以拒绝该消息并将其标记为死信。
  • 消息过期:如果为消息或队列设置了生存时间(TTL,Time To Live),当消息在队列中的存活时间超过了 TTL 值时,消息就会过期成为死信。例如,在电商场景中,用户下单后生成的订单消息,如果在一定时间内未被处理(如 30 分钟),可以将其设置为过期,进入死信队列进行后续处理,如取消订单、通知用户等。
  • 队列达到最大长度:当队列中的消息数量达到了其设置的最大长度限制时,新进入队列的消息会被视为死信。这在一些对队列容量有限制的场景中很有用,例如,为了防止队列无限增长导致内存耗尽,可以设置队列的最大长度,当队列满时,新消息进入死信队列,以便进行特殊处理。

死信队列在实际应用中有广泛的场景。例如,在订单处理系统中,当订单消息处理失败(如库存不足、支付失败等)时,可以将订单消息放入死信队列,由专门的处理程序对死信队列中的消息进行分析和处理,如重新尝试处理订单、通知管理员等。在消息重试机制中,也可以利用死信队列,当消息多次重试仍未成功时,将其放入死信队列,避免消息在正常队列中无限循环重试,占用资源。

在 Spring Boot 中配置死信队列,首先需要创建正常队列、死信队列和死信交换机。以下是一个配置示例:

 

import org.springframework.amqp.core.*;

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

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import java.util.HashMap;

import java.util.Map;

@Configuration

public class DeadLetterQueueConfig {

public static final String NORMAL_QUEUE = "normal.queue";

public static final String DEAD_LETTER_QUEUE = "dead.letter.queue";

public static final String DEAD_LETTER_EXCHANGE = "dead.letter.exchange";

public static final String ROUTING_KEY = "routing.key";

// 创建正常队列,并配置死信交换机和路由键

@Bean

public Queue normalQueue() {

Map<String, Object> args = new HashMap<>();

args.put("x-dead-letter-exchange", DEAD_LETTER_EXCHANGE);

args.put("x-dead-letter-routing-key", ROUTING_KEY);

return QueueBuilder.durable(NORMAL_QUEUE).withArguments(args).build();

}

// 创建死信队列

@Bean

public Queue deadLetterQueue() {

return QueueBuilder.durable(DEAD_LETTER_QUEUE).build();

}

// 创建死信交换机

@Bean

public DirectExchange deadLetterExchange() {

return new DirectExchange(DEAD_LETTER_EXCHANGE);

}

// 绑定死信队列和死信交换机

@Bean

public Binding bindingDeadLetterQueue(@Qualifier("deadLetterQueue") Queue queue,

@Qualifier("deadLetterExchange") DirectExchange exchange) {

return BindingBuilder.bind(queue).to(exchange).with(ROUTING_KEY);

}

}

在这个配置中,normalQueue方法创建了一个正常队列,并通过x-dead-letter-exchange和x-dead-letter-routing-key参数配置了死信交换机和路由键。当正常队列中的消息成为死信时,会根据这些配置被发送到死信交换机,再由死信交换机路由到死信队列。deadLetterQueue方法创建了死信队列,deadLetterExchange方法创建了死信交换机,最后通过bindingDeadLetterQueue方法将死信队列和死信交换机进行绑定,建立起死信消息的路由通道。

延迟队列是一种特殊的队列,它允许消息在指定的延迟时间后才被消费者消费。在 AMQP 协议中,RabbitMQ 本身并没有直接支持延迟队列的功能,但可以通过死信队列和 TTL(Time To Live)来模拟实现延迟队列的效果。

具体实现原理是:生产者将消息发送到一个设置了 TTL 的正常队列中,当消息在正常队列中的存活时间超过了 TTL 值时,消息会成为死信,并被发送到死信队列中。由于死信队列有消费者监听,所以当消息进入死信队列时,就相当于延迟了 TTL 时间后被消费,从而实现了延迟队列的功能。

在实际应用中,延迟队列有很多场景。例如,在电商系统中,用户下单后,如果在一定时间内(如 30 分钟)未支付,订单将被自动取消。可以将取消订单的消息发送到延迟队列,设置延迟时间为 30 分钟,当 30 分钟后,消息从延迟队列中被消费,系统可以检查订单状态,如果仍未支付,则取消订单。在定时任务场景中,也可以利用延迟队列来实现定时执行任务的功能,如定时发送邮件、定时生成报表等。

以电商订单超时取消为例,展示如何配置延迟队列。首先,在上述死信队列配置的基础上,为正常队列设置 TTL:

 

// 创建正常队列,并配置死信交换机、路由键和TTL

@Bean

public Queue normalQueue() {

Map<String, Object> args = new HashMap<>();

args.put("x-dead-letter-exchange", DEAD_LETTER_EXCHANGE);

args.put("x-dead-letter-routing-key", ROUTING_KEY);

// 设置队列中消息的TTL为30分钟(30 * 60 * 1000毫秒)

args.put("x-message-ttl", 30 * 60 * 1000);

return QueueBuilder.durable(NORMAL_QUEUE).withArguments(args).build();

}

在生产者类中,发送订单消息到正常队列:

 

import org.springframework.amqp.rabbit.core.RabbitTemplate;

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

import org.springframework.stereotype.Service;

@Service

public class OrderProducer {

@Autowired

private RabbitTemplate rabbitTemplate;

public void sendOrderMessage(String orderInfo) {

rabbitTemplate.convertAndSend("", DeadLetterQueueConfig.NORMAL_QUEUE, orderInfo);

System.out.println("Sent order message: " + orderInfo);

}

}

在消费者类中,监听死信队列,处理超时订单:

 

import org.springframework.amqp.rabbit.annotation.RabbitListener;

import org.springframework.stereotype.Component;

@Component

public class OrderConsumer {

@RabbitListener(queues = DeadLetterQueueConfig.DEAD_LETTER_QUEUE)

public void handleTimeoutOrder(String orderInfo) {

System.out.println("Received timeout order message: " + orderInfo);

// 处理超时订单逻辑,如取消订单、通知用户等

}

}

通过以上配置和代码,实现了利用死信队列和 TTL 模拟延迟队列,实现电商订单超时自动取消的功能。这种方式充分利用了 RabbitMQ 的特性,为分布式系统中的定时任务和延迟处理提供了灵活可靠的解决方案。

相关文章:

Spring Boot 与 RabbitMQ 的深度集成实践(三)

高级特性实现 消息持久化 在实际的生产环境中&#xff0c;消息的可靠性是至关重要的。消息持久化是确保 RabbitMQ 在发生故障或重启后&#xff0c;消息不会丢失的关键机制。它涉及到消息、队列和交换机的持久化配置。 首先&#xff0c;配置队列持久化。在创建队列时&#xf…...

部署java项目

1.编写shell脚本部署服务 restart.sh #!/bin/bash # # start the user program # echo "-------------------- start jk service --------------------" LOG_DIR"/home/joy/usr/app/ers-log" LOG_FILE"$LOG_DIR/log_$(date "%Y%m%d").txt&…...

中国城市间交通驾车距离矩阵(2024)

中国城市间交通驾车距离矩阵(2024) 1852 数据简介 中国城市中心的交通驾车距离&#xff0c;该数据为通过审图号GS(2024)0650的中国城市地图得其城市中心距离&#xff0c;再通过高德地图api计算得出其交通驾车最短距离矩阵&#xff0c;单位为KM&#xff0c;方便大家研究使用。…...

物联网数据湖架构

物联网海量数据湖分析架构&#xff08;推荐实践&#xff09; ┌──────────────┐ │ IoT设备端 │ └──────┬───────┘│&#xff08;MQTT/HTTP&#xff09;▼ ┌──────────────┐ │ EMQX等 │ 可选&#xff08;也可…...

Python将Excel单元格某一范围生成—截图(进阶版—带样式+批量+多级表头)

目录 专栏导读1、库的介绍2、库的安装3、核心代码4、通用版——带样式5、进阶版(可筛选+自动截图)多级表头版总结专栏导读 🌸 欢迎来到Python办公自动化专栏—Python处理办公问题,解放您的双手 🏳️‍🌈 博客主页:请点击——> 一晌小贪欢的博客主页求关注 👍 该…...

使用Python将 Excel 中的图表、形状和其他元素导出为图片

目录 为什么将 Excel 中的图表、形状和其他元素导出为图片&#xff1f; 工具与设置 Python 将 Excel 图表导出为图片 将图表导出为图片 将图表工作表导出为图片 Python 将 Excel 中的形状和其他元素导出为图片 微软 Excel 是一个功能强大的数据分析和可视化工具&#xff…...

从编程助手到AI工程师:Trae插件Builder模式实战Excel合并工具开发

Trae插件下载链接&#xff1a;https://www.trae.com.cn/plugin 引言&#xff1a;AI编程工具的新纪元 在软件开发领域&#xff0c;AI辅助编程正在经历一场革命性的变革。Trae插件&#xff08;原MarsCode编程助手&#xff09;最新推出的Builder模式&#xff0c;标志着AI编程工具…...

AI大模型从0到1记录学习numpy pandas day25

第 3 章 Pandas 3.1 什么是Pandas Pandas 是一个开源的数据分析和数据处理库&#xff0c;它是基于 Python 编程语言的。 Pandas 提供了易于使用的数据结构和数据分析工具&#xff0c;特别适用于处理结构化数据&#xff0c;如表格型数据&#xff08;类似于Excel表格&#xff09;…...

【云实验】Excel文件转存到RDS数据库

实验名称&#xff1a;Excel文件转存到RDS数据库 说明&#xff1a;把Excel的数据通过数据管理服务DMS&#xff08;Data Management Service&#xff09;导入到RDS MySQL数据库中。 流程&#xff1a;创建一个RDS for MySQL的实例&#xff0c;再创建数据库和账号&#xff0c;通过D…...

用Python实现数据库数据自动化导出PDF报告:从MySQL到个性化文档的全流程实践

本文将介绍如何使用Python构建一个自动化工具&#xff0c;实现从MySQL数据库提取员工数据&#xff0c;并为每位员工生成包含定制化表格的PDF报告。通过该方案&#xff0c;可显著提升数据导出效率&#xff0c;避免手动操作误差&#xff0c;同时支持灵活的格式定制。 需求&#…...

深入理解 ZAB:ZooKeeper 原子广播协议的工作原理

目录 ZAB 协议&#xff1a;ZooKeeper 如何做到高可用和强一致&#xff1f;&#x1f512;ZAB 协议的核心目标 &#x1f3af;ZAB 协议的关键概念 &#x1f4a1;ZAB 协议的运行阶段 &#x1f3ac;阶段一&#xff1a;Leader 选举 (Leader Election) &#x1f5f3;️阶段二&#xff…...

Javascript本地存储的方式有哪些?区别及应用场景?(含Deep Seek讲解)

JavaScript本地存储方式的区别与适用场景 1. Cookie 特点: Cookie是一种较早的本地存储技术&#xff0c;主要通过HTTP协议在客户端和服务器之间传递数据。它的大小通常被限制为4KB以内&#xff0c;并且每次HTTP请求都会携带Cookie信息。缺点: 数据量有限制&#xff08;最多4K…...

二元Logistic回归

二元Logistic回归 在机器学习领域&#xff0c;二元Logistic回归是一种非常经典的分类模型&#xff0c;广泛用于解决具有两类标签的分类问题。Logistic回归通过逻辑函数&#xff08;Sigmoid函数&#xff09;将预测结果映射到概率值&#xff0c;并进行分类。 一、Logistic回归 …...

Android framework 问题记录

一、休眠唤醒&#xff0c;很快熄屏 1.1 问题描述 机器休眠唤醒后&#xff0c;没有按照约定的熄屏timeout 进行熄屏&#xff0c;很快就熄屏&#xff08;约2s~3s左右&#xff09; 1.2 原因分析&#xff1a; 抓取相关log&#xff0c;打印休眠背光 相关调用栈 //具体打印调用栈…...

企业网站架构部署与优化 --web技术与nginx网站环境部署

一、Web 基础 本节将介绍Web 基础知识,包括域名的概念、DNS 原理、静态网页和动态网页的 相关知识。 1、域名和DNS 1.1、域名的概念 网络是基于TCP/IP 协议进行通信和连接的&#xff0c;每一台主机都有一个唯一的标识(固定的IP 地址),用以区别在网络上成千上万个用户和计算机。…...

Scala与Spark:原理、实践与技术全景详解

Scala与Spark&#xff1a;原理、实践与技术全景详解 一、引言 在大数据与分布式计算领域&#xff0c;Apache Spark 已成为事实标准的计算引擎&#xff0c;而 Scala 作为其主要开发语言&#xff0c;也逐渐成为数据工程师和后端开发者的必备技能。本文将系统梳理 Scala 语言基础…...

【聚类】层次聚类

层次聚类 文章目录 层次聚类1. 算法介绍2. 公式及原理3. 伪代码 1. 算法介绍 背景与目标 层次聚类&#xff08;Hierarchical Clustering&#xff09;是一类无需事先指定簇数的聚类方法&#xff0c;通过构造一棵“树状图”&#xff08;dendrogram&#xff09;来呈现数据的多层次…...

Windows环境安装LibreOffice实现word转pdf

前言&#xff1a;最近在工作中遇到了一个需求要实现word转pdf&#xff0c;本来我在上一个公司使用aspose.words工具使用的得心应手&#xff0c;都已经把功能点实现了&#xff0c;两句代码轻轻松松&#xff0c;但是被告知不能用商业版的东西&#xff0c;公司要求只能用开源的&am…...

【FAQ】HarmonyOS SDK 闭源开放能力 —Vision Kit (3)

1.问题描述&#xff1a; 通过CardRecognition识别身份证拍照拿到的照片地址&#xff0c;使用该方法获取不到图片文件&#xff0c;请问如何解决&#xff1f; 解决方案&#xff1a; //卡证识别实现页&#xff0c;文件名为CardDemoPage&#xff0c;需被引入至入口页 import { …...

【聚类】K-means++

K-means 文章目录 K-means1. 算法介绍2. 公式及原理3. 伪代码 1. 算法介绍 背景与目标 k-means 是 David Arthur 和 Sergei Vassilvitskii 于2007年提出的改进 k-means 初始化方法&#xff0c;其核心目标是&#xff1a; 在保证聚类质量的前提下&#xff0c;通过更合理地选择初始…...

Java实现PDF加水印功能:技术解析与实践指南

Java实现PDF加水印功能&#xff1a;技术解析与实践指南 在当今数字化办公环境中&#xff0c;PDF文件因其跨平台兼容性和格式稳定性而被广泛应用。然而&#xff0c;为了保护文档的版权、标记文档状态&#xff08;如“草稿”“机密”等&#xff09;或增加文档的可追溯性&#xf…...

【C#】用 DevExpress 创建带“下拉子表”的参数表格视图

展示如何用 DevExpress 创建带“下拉子表”的参数表格视图。主表为 参数行 ParamRow&#xff0c;子表为 子项 ChildParam。 一、创建模型类 public class ParamRow {public string Pn { get; set; }public string DisplayName { get; set; }public string Value { get; set; }…...

Go语言八股文之Mysql优化

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 非常期待和您一起在这个小…...

学习记录:DAY29

项目开发日志&#xff1a;技术实践与成长之路 前言 回顾这几天的状态&#xff0c;热情总是比我想象中更快被消耗完。比起茫然徘徊的小丑&#xff0c;我更希望自己是对着风车冲锋的疯子。 今天继续深入项目的实际业务。 状态好点的时候&#xff0c;再看自己EMO时写的东西&…...

LLaMA-Factory:了解webUI参数

Finetuning method参数 full&#xff08;全量微调&#xff09; 更新模型全部参数&#xff0c;完全适配新任务 效果最好&#xff0c;但资源消耗最大适用于计算资源充足的场景存在过拟合的风险&#xff0c;需要大量数据支持 freeze&#xff08;冻结微调&#xff09; 固定底层参…...

【实战】GPT-SoVITS+内网穿透:3分钟搭建可公网访问的语音克隆系统

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...

HTML向四周扩散背景

<!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><title>扩散背景效果</title><style>body {…...

React 个人笔记 Hooks编程

作用 配合函数式编程&#xff0c;保证在不产生类的时候完成一个整体的组件 常用组件 useStateuseContextuseReduceruseEffectuseMemouseCallback 前三个值为自变量 后三者为因变量 前三者相当于其他编程函数的变量声明&#xff0c;而后三者相当于对变量进行了(if now ! pr…...

CSS- 4.6 radiu、shadow、animation动画

本系列可作为前端学习系列的笔记&#xff0c;代码的运行环境是在HBuilder中&#xff0c;小编会将代码复制下来&#xff0c;大家复制下来就可以练习了&#xff0c;方便大家学习。 HTML系列文章 已经收录在前端专栏&#xff0c;有需要的宝宝们可以点击前端专栏查看&#xff01; 点…...

ngx_http_scgi_module 技术指南

一、快速上手示例 http {# 定义 SCGI 参数&#xff08;标准 CGI 环境变量&#xff09;include /etc/nginx/scgi_params;server {listen 80;location /app/ {# 将请求转发到本地 9000 端口的 SCGI 服务器scgi_pass localhost:9000;# 只转发非空的 HTTPS 参数scgi…...

NFT市场开发技术全解析:从架构设计到实现

NFT&#xff08;非同质化代币&#xff09;市场已成为区块链领域的热门应用场景&#xff0c;涵盖艺术品、游戏资产、虚拟地产等多个领域。本文将从技术栈选择、核心功能实现、开发流程、挑战与优化等方面&#xff0c;系统梳理NFT市场的开发要点&#xff0c;并结合实际案例与代码…...

第六十一篇 Java反射解析:用咖啡调配理解动态编程的艺术

引言&#xff1a;一杯咖啡引发的技术思考 在星巴克的收银台前&#xff0c;我们总能看到店员熟练地根据顾客需求调配不同口味的咖啡&#xff1a;美式、拿铁、卡布奇诺… 这让我联想到编程世界中的对象创建。如果每新增一种咖啡就要修改收银系统&#xff0c;这样的设计显然不够优…...

【android bluetooth 协议分析 01】【HCI 层介绍 7】【ReadLocalName命令介绍】

1. HCI_Read_Local_Name Read Local Name 是 HCI&#xff08;Host Controller Interface&#xff09;命令之一&#xff0c;属于 BR/EDR 控制器的 HCI Command 类别&#xff0c;其主要功能是 读取本地设备&#xff08;Controller&#xff09;的人类可读名称&#xff08;Local N…...

window xampp apache使用腾讯云ssl证书配置https

下载腾讯云ssl证书&#xff1a; 编辑Apache根目录下 conf/httpd.conf 文件&#xff1a; #LoadModule ssl_module modules/mod_ssl.so和#Include conf/extra/httpd-ssl.conf&#xff0c;去掉前面的#号注释。 编辑Apache根目录下 conf/httpd-ssl.conf 文件&#xff1a; <Vi…...

企业开发工具git的使用:从入门到高效团队协作

前言&#xff1a;本文介绍了Git的安装、本地仓库的创建与配置&#xff0c;以及工作区、暂存区和版本库的区分。详细讲解了版本回退、撤销修改等操作&#xff0c;并深入探讨了分支管理&#xff0c;包括分支的创建、切换、合并、删除及冲突解决。此外&#xff0c;还介绍了远程操作…...

【git config --global alias | Git分支操作效率提升实践指南】

git config --global alias | Git分支操作效率提升实践指南 背景与痛点分析 在现代软件开发团队中&#xff0c;Git分支管理是日常工作的重要组成部分。特别是在规范的开发流程中&#xff0c;我们经常会遇到类似 feature/user-management、bugfix/login-issue 或 per/cny/dev …...

VR 互动实训与展示,借科技开启沉浸式体验新篇​

对于企业而言&#xff0c;产品设计与展示是极为关键的环节&#xff0c;这直接关系到能否成功吸引客户&#xff0c;以及精准获取市场反馈。在当下科技飞速发展的时代&#xff0c;VR 互动实训为这一至关重要的环节注入了全新活力&#xff0c;带来了前所未有的体验。以某智能家居企…...

一文了解VR拍摄制作

虚拟现实&#xff08;VR&#xff09;技术通过计算机技术模拟环境&#xff0c;使用户能够身临其境地沉浸在虚拟世界中进行交互体验。 在VR拍摄中&#xff0c;主要利用这一技术来创建360度全景视频或图片&#xff0c;让观众能够全方位地感受拍摄场景。这种拍摄方式不仅改变了我们…...

【内测征集】LarkVR 播控系统上新:VR 应用一站式专业播控与管理工具

Paraverse平行云自主研发的LarkXR实时云渲染平台&#xff0c;作为行业领先的企业级云渲染解决方案&#xff0c;在国际市场占据重要地位。公司自2016年创立以来&#xff0c;始终引领3D/XR云化技术的创新发展&#xff0c;目前已在全球范围内为超过10,000名开发者和1,000家企业客户…...

Windows逆向工程提升之二进制分析工具:HEX查看与对比技术

公开视频 -> 链接点击跳转公开课程博客首页 -> ​​​链接点击跳转博客主页 目录 十六进制查看工具 应用于逆向工程的知识点 ​编辑 二进制对比工具 应用于逆向工程的知识点 十六进制查看工具 十六进制查看器是逆向工程的基础工具&#xff0c;它可以以十六进制格式…...

电脑A和电脑B都无法ping通电脑C网络,电脑C可以ping通电脑A和B,使用新系统测试正常,排除硬件问题。

主要硬件&#xff1a;研华AIMB-705主板、i5-6500 C机在防火墙高级设置里启用以下两项规则后&#xff0c;A/B机可正常访问C机网络。&#xff08;直接关闭防火墙也可解决此问题&#xff09; 文件和打印机共享 (回显请求 - ICMPv4-In) 核心网络诊断 - ICMP 回显请求 (ICMPv4-In)…...

【VMware】虚拟机运行 Linux Ubuntu、MAC 安装和配置

文章目录 一、VMware Workstation Pro 下载二、VMware Workstation Pro 安装三、Ubuntu Linux虚拟机镜像下载安装与配置 1、Ubuntu系统镜像下载 2、创建虚拟机&#xff08;VMware&#xff09;及硬件配置 3、编辑虚拟机设置 4、安装Ubuntu系统及系统…...

遨游科普:三防平板是什么?有什么作用?

在数字化与智能化浪潮席卷全球的今天&#xff0c;电子设备的可靠性已成为衡量其价值的核心标准之一。三防平板&#xff0c;这一“硬核”的工业设备&#xff0c;正凭借其卓越的环境适应能力&#xff0c;从专业领域走向大众视野&#xff0c;成为极端场景下不可或缺的数字化工具。…...

电脑闪屏可能的原因

1. 显示器 / 屏幕故障 屏幕排线接触不良&#xff1a;笔记本电脑屏幕排线&#xff08;屏线&#xff09;松动或磨损&#xff0c;导致信号传输不稳定&#xff0c;常见于频繁开合屏幕的设备。屏幕面板损坏&#xff1a;液晶屏内部灯管老化、背光模块故障或面板本身损坏&#xff0c;…...

VR 互动实训的显著优势​

&#xff08;一&#xff09;沉浸式学习&#xff0c;提升培训效果​ 在 VR 互动实训中&#xff0c;员工不再是被动的知识接受者&#xff0c;而是主动的参与者。以销售培训为例&#xff0c;员工戴上 VR 设备&#xff0c;就能置身于逼真的销售场景中&#xff0c;与虚拟客户进行面对…...

2025.05.19【Connectedscatter】连接散点图详解

How to add a legend to base R plot The legend() function allows to add a legend. See how to use it with a list of available customization. Image on the chart background The rasterImage function allows to add an image on the background of the chart. 文章目…...

C++之函数模板类模板

模板 1.泛型编程2. 函数模板函数模板概念函数模板的实例化模板参数的匹配原则 3.类模板类模板的定义格式类模板的实例化 4.模板的优缺点 C 模板是一种强大的泛型编程工具&#xff0c;它允许你编写与类型无关的代码&#xff0c;提高代码复用性。 1.泛型编程 先看一个我们之前经…...

《告别低效签约!智合同如何用AI重构商业“契约时代”》​​——解析智能合约技术的爆发与行业变革

在数字化浪潮奔涌的当下&#xff0c;合同作为商业活动的核心枢纽&#xff0c;正经历着智能化的深度变革。智合同-合同智能应用这一创新模式&#xff0c;犹如一颗璀璨的新星&#xff0c;在商业领域的天空中绽放出独特光芒&#xff0c;深刻改变着人们对合同管理与应用的认知和实践…...

Axure难点解决分享:垂直菜单展开与收回(4大核心问题与专家级解决方案)

亲爱的小伙伴,在您浏览之前,烦请关注一下,在此深表感谢!如有帮助请订阅专栏! Axure产品经理精品视频课已登录CSDN可点击学习https://edu.csdn.net/course/detail/40420 课程主题:垂直菜单展开与收回 主要内容:超长菜单实现、展开与收回bug解释、Axure9版本限制等问题解…...

PCB设计教程【入门篇】——电路分析基础-基本元件(电阻电容电感)

前言 本教程基于B站Expert电子实验室的PCB设计教学的整理&#xff0c;为个人学习记录&#xff0c;旨在帮助PCB设计新手入门。所有内容仅作学习交流使用&#xff0c;无任何商业目的。若涉及侵权&#xff0c;请随时联系&#xff0c;将会立即处理 目录 前言 1.PCB原理图的作用…...