Java大师成长计划之第26天:Spring生态与微服务架构之消息驱动的微服务
📢 友情提示:
本文由银河易创AI(https://ai.eaigx.com)平台gpt-4-turbo模型辅助创作完成,旨在提供灵感参考与技术分享,文中关键数据、代码与结论建议通过官方渠道验证。
在现代微服务架构中,服务之间的通信是至关重要的,而 消息驱动(Message-Driven)架构正是解决微服务之间通信挑战的一种重要方式。通过消息队列和事件驱动机制,微服务能够实现松耦合、异步通信,并提高系统的伸缩性和容错性。在 Spring 生态中,消息驱动架构被广泛应用于实现微服务间的异步通信和事件驱动系统。本文将介绍如何在 Spring 生态中使用消息驱动的微服务,并探讨相关技术,如 Spring Cloud Stream 和 Spring Kafka。
一、消息驱动架构的概念
1.1 什么是消息驱动架构?
消息驱动架构(Message-Driven Architecture,MDA)是一种基于消息队列的架构模式,在这种架构中,服务间通过异步的消息传递机制进行通信。与传统的同步通信模式(如 RESTful API 或 RPC)不同,消息驱动架构让微服务之间的通信不再依赖于直接的请求-响应模式,而是通过消息队列或事件流来传递信息和数据。消息驱动架构的核心思想是将服务之间的依赖解耦,避免服务直接调用,进而实现更高的系统灵活性和扩展性。
在消息驱动架构中,服务通过生产和消费消息进行协作。生产者(Producer)将消息发送到消息中间件,消费者(Consumer)从消息中间件中消费消息并进行处理。这种异步的通信方式大大减少了服务之间的耦合,使得系统更加松散、灵活,并且能够支持更加复杂和高效的系统交互模式。
1.2 消息驱动架构的基本原理
消息驱动架构通常涉及以下几个关键组件和流程:
-
消息生产者(Producer) :消息生产者是发送消息的实体。在微服务中,通常是一个服务,它会向消息中间件发送一个或多个消息。这些消息代表了系统中的某些事件、指令或数据更新。
-
消息消费者(Consumer) :消息消费者是接收和处理消息的实体。消费者从消息队列中拉取消息,进行相关的业务处理,并根据消息内容进行相应的操作。消费者通常是一些独立的微服务或应用程序。
-
消息中间件(Message Broker) :消息中间件是系统中的核心组件,充当消息传递的中介。消息中间件接收来自生产者的消息并将其存储,然后按照一定的规则将这些消息转发给消费者。常见的消息中间件包括 RabbitMQ、Kafka、ActiveMQ、RocketMQ 等。
-
消息队列(Message Queue) :消息队列是消息中间件中的一个重要组成部分,它用于暂存生产者发送的消息,直到消费者准备好处理这些消息。消息队列通常支持消息的持久化、确认机制和高可用性等特性。
-
事件驱动(Event-Driven) :消息驱动架构通常是基于事件驱动的,即每当系统中的某个状态发生变化时,就会触发一个事件。这个事件通过消息的形式被发送到消息中间件,由相应的消费者进行处理。
1.2.1 异步处理与解耦
在传统的微服务架构中,服务之间通常通过 同步调用(例如 HTTP 请求或远程方法调用)进行通信,这种方式会导致高耦合和性能瓶颈。如果某个服务出现故障,或者网络延迟较高,整个系统的性能可能会受到影响。而消息驱动架构通过引入消息中间件,将服务之间的通信转变为 异步通信,解决了这些问题。
通过消息中间件,生产者和消费者之间不再直接依赖于对方的可用性。生产者发送消息后并不需要等待消费者的响应,而消费者则可以在自己的时间处理消息。消息可以被暂时存储在队列中,待消费者准备好后再进行处理,从而实现了高效的异步处理。
1.2.2 事件驱动和松耦合
在消息驱动架构中,系统的组件之间通过事件来进行通信,而不是直接调用。事件是系统中的状态变化或某些操作的触发器。例如,当用户下单时,系统会触发一个订单创建事件,相关服务(如库存服务、支付服务、发货服务等)会订阅该事件并进行相应的处理。这种设计方式使得系统中的各个模块之间解耦,降低了服务之间的直接依赖。
每个服务只关心自己需要的事件,而不需要知道其他服务的具体实现。例如,订单服务发送“订单创建”事件,库存服务只需订阅并处理该事件,而不需要知道订单服务是如何实现的。这种方式使得系统更具灵活性,易于扩展和维护。
1.3 消息驱动架构的优势
1.3.1 松耦合
消息驱动架构最重要的优势之一是能够实现服务之间的松耦合。在传统的微服务架构中,服务通常需要彼此调用,服务之间的耦合度较高。而消息驱动架构通过消息中间件将服务之间的通信解耦,生产者和消费者无需直接了解对方的实现和状态。它们只需要遵循消息的生产和消费规则即可,从而大大降低了服务间的耦合度。
1.3.2 高可扩展性
通过消息队列和事件驱动机制,消息驱动架构使得微服务能够水平扩展。当流量增加时,可以简单地增加更多的消费者来并行处理消息,而无需修改系统的核心逻辑。此外,消息中间件通常会自动处理消息的负载均衡,使得系统在应对高并发时更加高效。
1.3.3 异步处理与高吞吐量
消息驱动架构支持异步通信,这意味着服务可以在不等待响应的情况下继续执行其他任务,从而提高系统的吞吐量。在流量激增或高并发的情况下,生产者可以不断发送消息,而消费者则可以在自己的节奏下处理这些消息。通过这种方式,系统能够更好地应对高并发、低延迟的要求。
1.3.4 容错性与可靠性
消息驱动架构能够提高系统的容错性。当某个服务不可用时,生产者将消息暂存到消息队列中,直到消费者恢复可用后再进行处理。这样即使部分服务出现故障,整个系统的其他部分仍然能够正常工作,从而避免了服务间的级联故障。
此外,消息中间件通常会提供消息的持久化、重试和确认机制,保证消息不会丢失。即使在系统出现异常的情况下,消息也可以被安全地保存并重新处理。
1.3.5 事件驱动和响应性
消息驱动架构通常是事件驱动的,这意味着系统中的各个模块可以根据具体的事件进行处理。事件驱动能够更好地支持业务需求的变化和复杂的业务流程。当一个服务的状态发生变化时,相关的消费者会根据这些事件做出反应,从而推动整个系统的业务流程。
1.4 消息驱动架构的应用场景
消息驱动架构非常适合用于处理分布式系统中的以下应用场景:
-
异步任务处理:当系统中存在一些需要长时间运行的任务(如文件上传、数据处理等),可以使用消息驱动架构将这些任务异步处理,避免阻塞主线程。
-
事件源和CQRS:在事件源(Event Sourcing)和命令查询职责分离(CQRS)模式中,事件驱动架构是核心的技术基础。事件源模式通过存储每个事件的状态变化,确保数据的一致性;CQRS 则通过分别处理命令和查询请求来优化系统性能。
-
日志处理与监控:在微服务架构中,服务的日志、监控信息和审计事件可以通过消息驱动架构进行统一收集和处理,以便对系统进行实时监控和异常分析。
-
分布式事务与补偿机制:在微服务中,事务跨越多个服务时通常需要依赖于消息驱动的异步事务补偿机制。通过消息队列的可靠性和事件驱动,系统能够实现可靠的分布式事务管理。
1.5 总结
消息驱动架构通过采用消息队列和事件驱动的方式,成功实现了微服务间的松耦合、异步通信和高可扩展性。它通过将消息传递、处理和事件响应与业务逻辑解耦,提供了系统灵活性、可靠性和高效性。随着微服务架构的不断发展,消息驱动架构在现代分布式系统中的应用越来越广泛,是确保系统稳定、高效和可扩展的重要设计模式。
通过了解消息驱动架构的概念和优势,开发者可以更加清晰地把握微服务架构的设计思路,并利用 Spring 等现代框架,快速构建出高效、可靠的消息驱动微服务系统。
二、Spring 生态中的消息驱动微服务
在现代微服务架构中,Spring 生态提供了丰富的工具和框架来支持消息驱动的微服务开发。其中,Spring Cloud Stream 和 Spring Kafka 是两个最常用的组件,它们分别集成了消息中间件(如 RabbitMQ、Kafka)和 Spring 的应用程序,帮助开发者构建高效、可靠的消息驱动微服务。下面将详细介绍如何在 Spring 生态中实现消息驱动的微服务。
2.1 Spring Cloud Stream
Spring Cloud Stream 是一个用于构建消息驱动微服务的框架,旨在简化与消息中间件的交互。它提供了一种编程模型,使得开发者可以专注于业务逻辑,而不必关注底层如何与消息系统进行集成。Spring Cloud Stream 支持各种消息中间件,并让开发者以声明式的方式定义消息通道和消息绑定。
2.1.1 核心概念
在 Spring Cloud Stream 中,有几个核心概念需要理解:
-
绑定器(Binder) :绑定器是连接应用程序和消息中间件的桥梁。每种消息中间件(如 RabbitMQ、Kafka)都有相应的绑定器,负责处理应用程序与消息中间件之间的交互。
-
通道(Channel) :通道是消息生产者和消费者之间的桥梁。开发者可以通过
@Output
和@Input
注解定义输入和输出通道。例如,输入通道用于接收消息,输出通道用于发送消息。 -
消息(Message) :在消息驱动的架构中,消息是数据的载体,通常包括数据体和头部信息。
-
流(Stream) :流是一系列连续的消息的集合,通常与事件相关联。使用流可以轻松处理事件驱动的业务场景。
2.1.2 使用 Spring Cloud Stream 的步骤
1. 添加依赖
要使用 Spring Cloud Stream,需要在 pom.xml
中添加相关依赖。以下示例以 RabbitMQ 为例:
xml
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-stream-rabbit</artifactId>
</dependency>
如果使用 Kafka,可添加以下依赖:
xml
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-stream-kafka</artifactId>
</dependency>
2. 配置消息通道
在 application.yml
中,您需要配置消息通道和绑定器。这一部分将定义输入通道和输出通道的目的地(queue/topic)。
yaml
spring:cloud:stream:bindings:output:destination: myQueue # 定义输出通道的目标队列input:destination: myQueue # 定义输入通道的目标队列rabbit:bindings:output:producer:routing-key-expression: "'myQueue'" # 输出通道的路由键input:consumer:durableSubscription: true # 确保存活的消费者订阅
3. 定义消息生产者
创建一个消息生产者,通过 @Output
注解定义输出通道,并通过消息通道发送消息。
java
import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.cloud.stream.messaging.Source;
import org.springframework.integration.support.MessageBuilder;
import org.springframework.messaging.MessageChannel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;@Service
@EnableBinding(Source.class) // 启用消息生产者绑定
public class MyMessageProducer {@Autowiredprivate MessageChannel output; // 获取绑定的输出通道public void sendMessage(String message) {output.send(MessageBuilder.withPayload(message).build()); // 发送消息}
}
4. 定义消息消费者
创建一个消息消费者,通过 @Input
注解定义输入通道,接收并处理消息。
java
import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.cloud.stream.messaging.Sink;
import org.springframework.cloud.stream.annotation.StreamListener;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.stereotype.Service;@Service
@EnableBinding(Sink.class) // 启用消息消费者绑定
public class MyMessageConsumer {@StreamListener(Sink.INPUT)public void handleMessage(@Payload String message) {System.out.println("Received message: " + message); // 处理接收到的消息}
}
5. 启动应用
启动 Spring Boot 应用后,消息生产者将消息发送到 RabbitMQ 或 Kafka 的队列中,而消费者会从相应的队列中接收消息并进行处理。这一过程可以通过日志进行跟踪。
2.1.3 Spring Cloud Stream 的优势和使用场景
-
简化开发:Spring Cloud Stream 抽象了与消息中间件的集成,开发者只需关注业务逻辑,降低了复杂性。
-
动态配置:Spring Cloud Stream 提供了使用配置属性动态配置消息通道的能力,便于在不同的环境下进行配置。
-
支持多种消息中间件:通过不同的绑定器,Spring Cloud Stream 支持多种常用的消息中间件(如 RabbitMQ、Kafka 等),开发者可以根据需求选择最佳的中间件。
-
应用场景:适用于需要处理即时数据流、异步操作、事件源、实时监控等场景的微服务架构。
2.2 Spring Kafka
Spring Kafka 是一个用于简化 Kafka 集成的框架,它允许开发者使用 Spring 的编程模型来接入 Kafka。Kafka 是一种高吞吐量、可扩展的分布式消息流平台,广泛用于处理大规模流数据。
2.2.1 核心特性
-
高吞吐量与低延迟:Kafka 擅长处理高并发和高量级的消息传输,适合大规模分布式应用。
-
分布式与持久化:Kafka 数据可以持久化并在不同的节点间进行复制,确保消息不会丢失。
-
流式处理:Kafka 支持实时的流式处理,可以与 Spark、Flink 等流处理框架配合使用。
2.2.2 使用 Spring Kafka 的步骤
1. 添加依赖
在 pom.xml
中添加 Spring Kafka 依赖:
xml
<dependency><groupId>org.springframework.kafka</groupId><artifactId>spring-kafka</artifactId>
</dependency>
2. 配置 Kafka 生产者与消费者
在 application.yml
中配置 Kafka 的连接参数,包括 Kafka 服务器地址、序列化与反序列化设置等。
yaml
spring:kafka:bootstrap-servers: localhost:9092 # Kafka 服务器地址producer:key-serializer: org.apache.kafka.common.serialization.StringSerializervalue-serializer: org.apache.kafka.common.serialization.StringSerializerconsumer:group-id: my-group # 消费者组key-deserializer: org.apache.kafka.common.serialization.StringDeserializervalue-deserializer: org.apache.kafka.common.serialization.StringDeserializer
3. 定义 Kafka Producer
创建一个 Kafka 生产者将消息发送到 Kafka 中。
java
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;@Service
public class KafkaProducer {@Autowiredprivate KafkaTemplate<String, String> kafkaTemplate;private final String topic = "myTopic"; // 消息主题public void sendMessage(String message) {kafkaTemplate.send(topic, message); // 发送消息}
}
4. 定义 Kafka Consumer
创建一个 Kafka 消费者来接收和处理消息。
java
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.stereotype.Service;@Service
public class KafkaConsumer {@KafkaListener(topics = "myTopic", groupId = "my-group") // 订阅主题public void consume(String message) {System.out.println("Received message: " + message); // 处理接收到的消息}
}
5. 启动 Kafka
启动应用程序后,Kafka 生产者将向 Kafka 中发送消息,而 Kafka 消费者将从主题中接收消息进行处理。
2.2.3 Spring Kafka 的优势和使用场景
-
高效的消息处理:Spring Kafka 利用 Kafka 的高吞吐量特性,适合需要快速处理大量消息的场景。
-
分布式系统的良好支持:Kafka 的分布式特性使得其非常适合用于微服务架构,支持服务横向扩展并提高整体性能。
-
流处理与分析:通过 Kafka 与流处理框架(如 Apache Flink 和 Apache Spark)集成,能够实现复杂的数据流处理与分析功能。
-
应用场景:用于构建实时数据流处理、日志收集系统、用户行为分析、订单处理等场景。
2.3 消息驱动架构中的挑战与优化
尽管在 Spring 生态中使用消息驱动微服务带来了许多好处,但一些挑战仍然需要注意:
-
消息排序:在使用 Kafka 时,确保消息的顺序是个关键问题,可以通过分区配置来保证特定键的消息在同一分区中处理。
-
消息重复消费:由于网络或其他因素,可能会导致消息被多次处理。开发者在消费消息时需要考虑幂等性,确保多次处理相同消息不会导致数据不一致。
-
错误处理与重试机制:在消费消息时,可能会遇到错误。正确实现错误处理和重试机制很重要,Spring Kafka 提供了一些内置机制来处理失败的消息。
-
监控与可视化:监控消息流和服务状态对于保证系统的稳定性至关重要,开发者需要利用工具(如 Spring Boot Actuator、Prometheus 和 Grafana)进行监控和可视化。
2.4 总结
Spring 生态中的消息驱动微服务为开发者提供了强大的支持,让实现异步、松耦合的服务通信变得简单。无论是通过 Spring Cloud Stream 还是 Spring Kafka,开发者都能更高效地构建可靠的消息驱动系统。这种架构模式的优势使其适用于各种复杂的业务场景,同时结合 Spring 的各项特性,助力打造高效且灵活的微服务架构。通过深入理解和掌握这些技术,开发者能够更好地应对现代分布式系统中的挑战,提升系统的整体性能和可维护性。
三、总结
消息驱动架构为微服务提供了一种异步、松耦合的通信方式,能够有效提升系统的可扩展性、容错性和性能。在 Spring 生态中,Spring Cloud Stream 和 Spring Kafka 为开发者提供了高效的消息驱动支持,通过这两种框架,可以快速构建出可扩展且可靠的微服务系统。
无论是使用消息中间件进行服务解耦,还是在事件驱动架构中捕获和处理业务事件,消息驱动都为微服务架构带来了巨大的灵活性。通过深入掌握消息驱动架构和相关技术,开发者能够更好地应对现代分布式系统中的复杂性,提升系统的可靠性和响应能力。
相关文章:
Java大师成长计划之第26天:Spring生态与微服务架构之消息驱动的微服务
📢 友情提示: 本文由银河易创AI(https://ai.eaigx.com)平台gpt-4-turbo模型辅助创作完成,旨在提供灵感参考与技术分享,文中关键数据、代码与结论建议通过官方渠道验证。 在现代微服务架构中,服务…...
Linux 文件(1)
1. 文件 1.1 文件是什么 一个文件,是由其文件属性与文件内容构成的。文件属性又称为一个文件的元数据,因此如果一个文件,内容为空,这个文件依然要占据磁盘空间。 1.2 文件在哪里 一个文件,如果没有被打开ÿ…...
程序代码篇---python向http界面发送数据
文章目录 前言 前言 本文简单接受了python向http界面发送数据...
【iOS】探索消息流程
探索消息流程 Runtime介绍OC三大核心动态特性动态类型动态绑定动态语言 方法的本质代码转换objc_msgSendSELIMPMethod 父类方法在子类中的实现 消息查找流程开始查找快速查找流程慢速查找流程二分查找方法列表父类缓存查找 动态方法解析动态方法决议实例方法类方法优化 消息转发…...
院校机试刷题第六天:1134矩阵翻转、1052学生成绩管理、1409对称矩阵
一、1134矩阵翻转 1.题目描述 2.解题思路 很简单的模拟题,甚至只是上下翻转,遍历输出的时候先把最下面那一行输出即可。 3.代码 #include <iostream> #include <vector> using namespace std;int main() {int n;cin >> n;vector&l…...
DeepSeek在简历筛选系统中的深度应用
一、多模态解析引擎的技术突破 1.1 复杂格式的精准解析 针对简历格式多样性挑战,DeepSeek采用三级解析架构: 格式标准化层:基于Transformer的DocParser模型支持200+种文档格式转换视觉特征提取:使用改进的YOLOv8进行证书印章识别(mAP@0.5达93.7%)语义重构模块:通过注意…...
c++多线程debug
debug demo 命令行查看 ps -eLf|grep cam_det //查看当前运行的轻量级进程 ps -aux | grep 执行文件 //查看当前运行的进程 ps -aL | grep 执行文件 //查看当前运行的轻量级进程 pstree -p 主线程ID //查看主线程和新线程的关系 查看线程栈结构 pstack 线程ID 步骤&…...
【回溯 剪支 状态压缩】# P10419 [蓝桥杯 2023 国 A] 01 游戏|普及+
本文涉及知识点 C回溯 位运算、状态压缩、枚举子集汇总 P10419 [蓝桥杯 2023 国 A] 01 游戏 题目描述 小蓝最近玩上了 01 01 01 游戏,这是一款带有二进制思想的棋子游戏,具体来说游戏在一个大小为 N N N\times N NN 的棋盘上进行,棋盘…...
CUDA 纹理入门
一、什么是CUDA纹理 CUDA纹理是NVIDIA GPU提供的一种特殊内存访问机制,它允许高效地访问和过滤结构化数据。纹理内存最初是为图形渲染设计的,但在通用计算(GPGPU)中也很有用。 二、纹理内存的优势 缓存优化:纹理内存有专用的缓存,适合空间局部性好的访问模式 硬件过滤:支…...
大模型微调步骤整理
在对深度学习模型进行微调时,我通常会遵循以下几个通用步骤。 第一步是选择一个合适的预训练模型。PyTorch 的 torchvision.models 模块提供了很多经典的预训练模型,比如 ResNet、VGG、EfficientNet 等。我们可以直接使用它们作为模型的基础结构。例如,加载一个预训练的 Re…...
【GPT入门】第39课 OPENAI官方API调用方法
【GPT入门】第39课 OPENAI官方API调用方法 1. OPENAI 免费API2. openai调用最简单的API3.apiKey提取到环境变量 1. OPENAI 免费API 需要科学上网,可以调用 gpt-4o-mini 的 api, 使用其它旧的GPT,反而可能需要收费,例如 gpt-3.5-turbo 2. op…...
【DeepSeek论文精读】11. 洞察 DeepSeek-V3:扩展挑战和对 AI 架构硬件的思考
欢迎关注[【AIGC论文精读】](https://blog.csdn.net/youcans/category_12321605.html)原创作品 【DeepSeek论文精读】1. 从 DeepSeek LLM 到 DeepSeek R1 【DeepSeek论文精读】7. DeepSeek 的发展历程与关键技术 【DeepSeek论文精读】11. 洞察 DeepSeek-V3ÿ…...
MySQL事务的一些奇奇怪怪知识
Gorm事务有error却不返回会发生什么 Gorm包是大家比较高频使用。正常的用法是,如果有失败返回error,整体rollback,如果不返回error则commit。下面是Transaction的源码: // Transaction start a transaction as a block, return …...
C语言内存函数与数据在内存中的存储
一、c语言内存函数 1、memcpy函数是一个标准库函数,用于内存复制。功能上是用来将一块内存中的内容复制到另一块内存中。用户需要提供目标地址、源地址以及要复制的字节数。例如结构体之间的复制。 memcpy函数的原型是:void* memcpy(void* …...
Power BI Desktop运算符和新建列
1.运算符 运算符 含义 加 - 减 * 乘 / 除 ^ 幂 运算符 含义 等于 > 大于 < 小于 > 大于等于 < 小于等于 <> 不等于 运算符 含义 && 与 || 或 not 非 & 字符串连接 in 包含 not in 不包含 2.新建列 …...
windows 安装gdal实现png转tif,以及栅格拼接
windows 安装gdal实现png转tif,以及栅格拼接 一、安装gdal 网上有很多安装gdal的方法,此处通过osgeo4w安装gdal 1.下载osgeo4w 下载地址 https://trac.osgeo.org/osgeo4w/ 2、安装osgeo4w exe文件安装,前面部分很简单,就不再…...
【嵙大o】C++作业合集
参考: C swap(交换)函数 指针/引用/C自带-CSDN博客 Problem IDTitleCPP指针CPP引用1107 Problem A编写函数:Swap (I) (Append Code)1158 Problem B整型数据的输出格式1163 Problem C时间:24小时制转12小时制1205…...
论信息系统项目的采购管理
论信息系统项目的采购管理 背景一、规划采购管理二、实施采购三、控制采购结语 背景 某市为对扶贫对象实施精确识别、精确帮扶、精确管理,决定由民政部门牵头,建设家庭经济状况分析及市、县(区)、镇(街)三级…...
创建型:单例模式
目录 1、核心思想 2、实现方式 2.1 饿汉式 2.2 懒汉式 2.3 枚举(Enum) 3、关键注意事项 3.1 线程安全 3.2 反射攻击 3.3 序列化与反序列化 3.4 克隆保护 4、适用场景 1、核心思想 目的:确保一个类仅有一个实例 功能:…...
职场方法论总结(4)-如何正确地汇报
一、明确汇报目标 区分类型:是项目进展汇报?数据总结?问题解决方案?还是资源申请?明确目标才能聚焦内容。听众需求: 所有人都希望你用最简短的语言把事情讲清楚,节省时间领导关注结果、风险和资…...
STM32SPI实战-Flash模板
STM32SPI实战-Flash模板 一,常用指令集(部分)二,组件库GD25QXX API 函数解析1,前提条件2,初始化与识别1, void spi_flash_init(void)2, uint32_t spi_flash_read_id(void) 3,擦除操作1, void spi_flash_sector_erase(uint32_t sec…...
CSS- 4.4 固定定位(fixed) 咖啡售卖官网实例
本系列可作为前端学习系列的笔记,代码的运行环境是在HBuilder中,小编会将代码复制下来,大家复制下来就可以练习了,方便大家学习。 HTML系列文章 已经收录在前端专栏,有需要的宝宝们可以点击前端专栏查看! 点…...
【Retinanet】训练自己的数据集
目录 1.下载源码2.配置环境3.数据集准备4.训练自己的数据5.成功训练! 1.下载源码 Retinanet代码:代码 下载到你的目录中,进行打开。 2.配置环境 这里就是cudapytorch,没有配置过的可以参考博客: 深度学习环境的搭建…...
微软将于 8 月 11 日关闭 Bing Search API 服务
微软宣布将于 2025 年 8 月 11 日正式关闭 Bing Search API 服务。届时,所有使用 Bing Search API 的实例将完全停用,同时不再接受新用户注册。 此次停用决定主要影响 Bing Search F1 及 S1 到 S9 资源的用户,以及 Custom Search F0 与 S1 到…...
探索 Python 的利器:help()、dir() 与 AI 工具的结合应用
引言 在编程世界中,Python 以其简洁的语法、强大的功能和丰富的库生态系统成为众多开发者的首选语言。无论是初学者还是资深工程师,在学习新模块、调试代码或探索未知功能时,常常需要有效的工具来帮助理解和解决问题。Python 提供了内置的 help() 和 dir() 函数,让开发者能…...
MySQL查询优化器底层原理解析:从逻辑优化到物理优化
MySQL查询优化器底层原理解析:从逻辑优化到物理优化 引言 在数据库系统中,SQL语句的执行效率直接影响着整个应用的性能表现。一条普通的SQL执行前会经历五个关键阶段:SQL输入、语法分析、语义检查、SQL优化、SQL执行。其中,SQL优…...
UI架构的历史与基础入门
本笔记的目的是通过一系列连贯的例子来探讨“事物-模型-视图-编辑器”这一隐喻。 这些例子都来自我的规划系统(planning system),用于解释上述四个概念。所有例子都已实现,但并未在本文描述的清晰类结构中实现。 这些隐喻对应于《…...
(三)MMA(KeyCloak身份服务器/OutBox Pattern)
文章目录 项目地址一、KeyCloak二、OutBox Pattern2.1 配置Common模块的OutBox1. OutboxMessage2. 数据库配置OutboxMessageConfiguration3. 创建Save前的EF拦截器4. 创建Quartz后台任务5. 配置后台任务6. 注册服务2.2 创建OutBox的消费者项目地址 教程作者:教程地址:代码仓库…...
【通用智能体】Playwright:跨浏览器自动化工具
Playwright:跨浏览器自动化工具 一、Playwright 是什么?二、应用场景及案例场景 1:端到端(E2E)测试场景 2:UI 自动化(表单批量提交)场景 3:页面截图与 PDF 生成场景 4&am…...
单片机设计_停车场车位管理系统(AT89C52、LCD1602)
想要更多项目私wo!!! 一、电路设计 此电路由AT89C52单片机和LCD1602液晶显示模块等器件组成。 二、运行结果 三、部分代码 #include <reg52.h> //调用单片机头文件 #define uchar unsigned char //无符号字符型 宏定义 变量范围0~255 #define uint unsigned…...
【android bluetooth 协议分析 01】【HCI 层介绍 5】【SetEventMask命令介绍】
1. HCI_Set_Event_Mask 命令作用 项目内容命令名HCI_Set_Event_MaskOCF0x0001作用主机通过设置 Event Mask 告诉控制器:我只对某些事件感兴趣,屏蔽其他事件,以减少中断。事件来源事件是 HCI 与主机之间通信的反馈机制,控制器通过…...
python打卡day29
类的装饰器 知识点回顾 类的装饰器装饰器思想的进一步理解:外部修改、动态类方法的定义:内部定义和外部定义 回顾一下,函数的装饰器是 :接收一个函数,返回一个修改后的函数。类也有修饰器,类装饰器本质上确…...
【数据结构】树状数组
树状数组 假设一个数可以 x x x可以被二进制分解成 x 2 i 1 2 i 2 . . . 2 i m x 2^{i_1} 2^{i_2} ... 2^{i_m} x2i12i2...2im,不妨设 i 1 > i 2 > . . . > i m i_1 > i_2 > ... > i_m i1>i2>...>im,进…...
Java虚拟机 - JVM与Java体系结构
Java虚拟机 JVM与Java体系结构为什么要学习JVMJava与JVM简介Java 语言的核心特性JVM:Java 生态的基石JVM的架构模型基于栈的指令集架构(Stack-Based)基于寄存器的指令集架构(Register-Based)JVM生命周期 总结 JVM与Jav…...
翻译:20250518
翻译题 文章目录 翻译题一带一路中国结 一带一路 The “One Belt and One Road” Initiative aims to achieve win-win and shared development. China remains unchanged in its commitment to foster partnerships. China pursues an independent foreign policy of peace, …...
SparkSQL基本操作
以下是 Spark SQL 的基本操作总结,涵盖数据读取、转换、查询、写入等核心功能: 一、初始化 SparkSession scala import org.apache.spark.sql.SparkSession val spark SparkSession.builder() .appName("Spark SQL Demo") .master("…...
Ansible模块——文件内容修改
修改文件单行内容 ansible.builtin.lineinfile 可以按行修改文件内容,一次修改一行,支持正则表达式。 选项名 类型 默认值 描述 attributesstrnull 设置目标文件的 Linux 文件系统属性(attribute bits),作用类似于…...
基于单片机路灯自动控制仪仿真设计
标题:基于单片机路灯自动控制仪仿真设计 内容:1.摘要 本设计旨在解决传统路灯控制方式效率低、能耗大的问题,开展了基于单片机的路灯自动控制仪仿真设计。采用单片机作为核心控制单元,结合光照传感器、时钟模块等硬件,运用相关软件进行编程和…...
Spring Web MVC————入门(3)
今天我们来一个大练习,我们要实现一个登录界面,登录进去了先获取到登录人信息,可以选择计算器和留言板两个功能,另外我们是学后端的,对于前端我们会些基础的就行了,知道ajax怎么用,知道怎么关联…...
拓展运算符与数组解构赋值的区别
拓展运算符与数组解构赋值是ES6中用于处理数组的两种不同的特性,它们有以下区别: 概念与作用 • 拓展运算符:主要用于将数组展开成一系列独立的元素,或者将多个数组合并为一个数组,以及在函数调用时将数组作为可变参…...
【Linux】第二十章 管理基本存储
目录 1. 对 Linux 磁盘进行分区时有哪两种方案?分别加以详细说明。 2. 简单说下创建MBR磁盘分区涉及哪几个步骤? 3. 创建GPT分区与创建MBR分区有什么不同? 4. 在创建分区时就会在分区上创建文件系统吗? 5. 如何持久挂载文件系…...
DeepSeek本地部署全攻略:从零搭建到Web可视化及数据训练
目录 1. 环境准备与硬件要求2. 安装Ollama框架3. 部署DeepSeek模型4. Web可视化配置5. 数据投喂与模型训练6. 进阶技巧与常见问题1. 环境准备与硬件要求 硬件配置建议 基础配置:16GB内存 + RTX 3060显卡(流畅运行7B参数模型)进阶配置:32GB内存 + RTX 4090显卡(支持14B模型…...
JavaScript性能优化实战(12):大型应用性能优化实战案例
在前面的系列文章中,我们探讨了各种JavaScript性能优化技术和策略。本篇将聚焦于实际的大型应用场景,通过真实案例展示如何综合运用这些技术,解决复杂应用中的性能挑战。 目录 电商平台首屏加载优化全流程复杂数据可视化应用性能优化案例在线协作工具的实时响应优化移动端W…...
前缀和——中心数组下标
此题我们不应局限于前缀和的模板,因为该中心下标把数组分为两个部分且每个部分都要求和,我们就一个再创建一个”后缀和” 定义两个数组f,g。f[i]表示[0,i-1]所有元素的和 f[i]f[i-1]nums[i-1];g[i]表示[i1,n-1]的和 g[i]g[i1]nums[i1];因为依…...
Java——创建多线程的四种方式
一、继承Thread 步骤 1.定义一个类继承Thread 2.重写run方法,在方法中设置线程任务(此线程具体执行的代码) 3.创建自定义线程类对象 4.调用Thread中的start方法,开启线程,jvm自动调用run方法 常用方法 void sta…...
广域网学习
PPPoE技术(拨号上网) PPPoE ( PPP over Ethernet ,以太网承载 PPP 协议)是一种把 PPP 帧封装到以太网帧中的链路层协议。 PPPoE 可以使以太网网络中的多台主机连接到远端的宽带接入服务器。 应用场景 PPPoE 组网结构采…...
inverse-design-of-grating-coupler-3d
一、设计和优化3D光栅耦合器 1.1 代码讲解 通过预定义的环形间距参数(distances数组),在FDTD中生成椭圆光栅结构,并通过用户交互确认几何正确性后,可进一步执行参数扫描优化。 # os:用于操作系统相关功能(如文件路径操作) import os import sys# lumapi:Lumerical 的…...
渗透测试流程-中篇
#作者:允砸儿 #日期:乙巳青蛇年 四月廿一(2025年5月18日) 今天笔者带大家继续学习,网安的知识比较杂且知识面很广,这一部分会介绍很多需要使用的工具。会用各种工具是做网安的基础,ok咱们继续…...
2026武汉门窗门业移门木门铝艺门智能锁展会3月国博举办
展出面积:60000㎡ 观众:80000人次 参展企业:800 专业活动:20 2026武汉门窗门业移门木门铝艺门智能锁展会3月国博举办 2026第二届中国武汉整装定制家居暨门窗装饰材料博览会/2026武汉建博会 时间:2026年3月20-22日 …...
如何用mockito+junit测试代码
Mockito 是一个流行的 Java 模拟测试框架,用于创建和管理测试中的模拟对象(mock objects)。它可以帮助开发者编写干净、可维护的单元测试,特别是在需要隔离被测组件与其他依赖项时。 目录 核心概念 1. 模拟对象(Mock Objects) 2. 打桩(Stubbing) 3. 验…...