【系统设计】高效的分布式系统:使用 Spring Boot 和 Kafka 实现 Saga 模式
在现代分布式系统中,管理跨多个服务的长事务至关重要。传统的分布式事务解决方案往往面临性能瓶颈和复杂性问题,而 Saga 模式 作为一种灵活高效的解决方案,逐渐受到开发者的青睐。本文将探讨如何利用 Spring Boot 和 Kafka 实现 Saga 模式,并详细介绍事务补偿机制,帮助你构建稳定可靠的分布式系统。
什么是 Saga 模式?
原理介绍
在微服务架构中,一个业务流程通常涉及多个独立的服务。这些服务必须协同工作以完成完整的业务操作。例如,用户下单可能需要订单服务、支付服务和库存服务的合作。然而,跨服务操作通常涉及复杂的事务管理,传统的分布式事务(如两阶段提交)不仅效率低下,还难以扩展和维护。
Saga 模式 提供了一种替代方案,通过将一个长事务分解为一系列的本地事务,并通过事件或命令进行协调,从而实现最终一致性。这种方法不仅提高了系统的可扩展性,还简化了事务管理。
解决的问题及其重要性
Saga 模式解决了以下问题:
- 分布式事务管理:通过拆分事务,避免了传统分布式事务的性能和复杂性问题。
- 系统可扩展性:各服务独立运行,易于扩展和维护。
- 错误恢复:通过补偿机制,确保在步骤失败时,系统能恢复到一致状态。
在现代微服务架构中,确保跨服务操作的可靠性和一致性至关重要。Saga 模式提供了一个高效且灵活的解决方案,使系统在面对复杂业务流程和潜在错误时能够稳定运行。
Saga 模式的组成部分与实现方法
Saga 模式主要有两种实现方式:Choreography(编排) 和 Orchestration(指挥)。下面将详细介绍这两种模式,并展示如何使用 Spring Boot 和 Kafka 实现它们,包括事务补偿机制。
架构图
编排模式
+----------------+ +----------------+ +----------------+
| OrderService | | PaymentService | | InventoryService|
+----------------+ +----------------+ +----------------+| | || CreateOrderCommand | ||------------------------->| || | || OrderCreatedEvent | ||<-------------------------| || | || | PaymentCommand || |------------------------>|| | || | PaymentProcessedEvent || |<------------------------|| | || InventoryCommand | ||------------------------->| || | || | InventoryUpdatedEvent||<-------------------------| || | |
指挥模式
+----------------+ +----------------+ +----------------+
| SagaOrchestrator| | OrderService | | PaymentService |
+----------------+ +----------------+ +----------------+| | || CreateOrderCommand | ||----------------------->| || | || OrderCreatedEvent | ||<-----------------------| || | || PaymentCommand | ||--------------------------------------------------->|| | || PaymentApprovedEvent | ||<---------------------------------------------------|| | || | || InventoryCommand | ||----------------------->| || | |
1. 编排模式
在 编排模式 下,各服务通过事件进行通信和协调,没有中央控制器。每个服务独立地监听和发布事件,以完成整个业务流程。
1.1 组成部分
- 事件定义:服务之间传递的消息,如
OrderCreatedEvent
、PaymentProcessedEvent
等。 - Kafka 生产者与消费者:用于事件的发布和订阅。
- 各服务逻辑:根据收到的事件执行相应的操作,并发布下一个事件。
1.2 实现步骤与代码
1.2.1 定义事件
// OrderCreatedEvent.java
public class OrderCreatedEvent {private String orderId;private String product;private int quantity;// getters and setters
}// PaymentProcessedEvent.java
public class PaymentProcessedEvent {private String orderId;private boolean success;// getters and setters
}// PaymentFailedEvent.java
public class PaymentFailedEvent {private String orderId;private String reason;// getters and setters
}// OrderCancelledEvent.java
public class OrderCancelledEvent {private String orderId;// getters and setters
}
1.2.2 配置 Kafka
# application.yml
spring:kafka:bootstrap-servers: localhost:9092consumer:group-id: saga-groupauto-offset-reset: earliestkey-deserializer: org.apache.kafka.common.serialization.StringDeserializervalue-deserializer: org.apache.kafka.common.serialization.StringDeserializerproducer:key-serializer: org.apache.kafka.common.serialization.StringSerializervalue-serializer: org.apache.kafka.common.serialization.StringSerializer
1.2.3 实现 OrderService
@Service
public class OrderService {@Autowiredprivate KafkaTemplate<String, String> kafkaTemplate;private ObjectMapper mapper = new ObjectMapper();@KafkaListener(topics = "create-order-command", groupId = "order-service-group")public void handleCreateOrder(String message) throws JsonProcessingException {CreateOrderCommand command = mapper.readValue(message, CreateOrderCommand.class);// 创建订单逻辑// TODO: 保存订单到数据库// 发布 OrderCreatedEventOrderCreatedEvent event = new OrderCreatedEvent();event.setOrderId(command.getOrderId());event.setProduct(command.getProduct());event.setQuantity(command.getQuantity());String eventMsg = mapper.writeValueAsString(event);kafkaTemplate.send("order-created", eventMsg);}@KafkaListener(topics = "payment-failed", groupId = "saga-group")public void handlePaymentFailed(String message) throws JsonProcessingException {PaymentFailedEvent failedEvent = mapper.readValue(message, PaymentFailedEvent.class);// 取消订单逻辑cancelOrder(failedEvent.getOrderId());// 发布 OrderCancelledEventOrderCancelledEvent cancelledEvent = new OrderCancelledEvent();cancelledEvent.setOrderId(failedEvent.getOrderId());String cancelledMsg = mapper.writeValueAsString(cancelledEvent);kafkaTemplate.send("order-cancelled", cancelledMsg);}private void cancelOrder(String orderId) {// TODO: 取消订单逻辑}
}
1.2.4 实现 PaymentService
@Service
public class PaymentService {@Autowiredprivate KafkaTemplate<String, String> kafkaTemplate;private ObjectMapper mapper = new ObjectMapper();@KafkaListener(topics = "order-created", groupId = "saga-group")public void handleOrderCreated(String message) throws JsonProcessingException {OrderCreatedEvent event = mapper.readValue(message, OrderCreatedEvent.class);// 处理支付逻辑boolean success = processPayment(event.getOrderId(), event.getQuantity());if (success) {// 发布 PaymentProcessedEventPaymentProcessedEvent paymentEvent = new PaymentProcessedEvent(event.getOrderId(), true);String paymentMsg = mapper.writeValueAsString(paymentEvent);kafkaTemplate.send("payment-processed", paymentMsg);} else {// 发布 PaymentFailedEventPaymentFailedEvent failedEvent = new PaymentFailedEvent();failedEvent.setOrderId(event.getOrderId());failedEvent.setReason("Payment processing failed.");String failedMsg = mapper.writeValueAsString(failedEvent);kafkaTemplate.send("payment-failed", failedMsg);}}private boolean processPayment(String orderId, int quantity) {// TODO: 实现支付逻辑,模拟支付失败return false;}
}
1.2.5 实现 InventoryService
@Service
public class InventoryService {@KafkaListener(topics = "order-cancelled", groupId = "saga-group")public void handleOrderCancelled(String message) throws JsonProcessingException {OrderCancelledEvent cancelledEvent = new ObjectMapper().readValue(message, OrderCancelledEvent.class);// 回滚库存逻辑rollbackInventory(cancelledEvent.getOrderId());}private void rollbackInventory(String orderId) {// TODO: 实现库存回滚逻辑}
}
1.3 事务补偿机制
在 编排模式 中,当某个服务的操作失败时,需要通过发布补偿事件来反向撤销之前的操作。上述代码中,PaymentService
在支付失败时发布 PaymentFailedEvent
,OrderService
监听该事件并执行订单取消逻辑,随后发布 OrderCancelledEvent
,最后 InventoryService
监听并回滚库存。
2. 指挥模式
在 指挥模式 下,存在一个中央的 Saga 管理器(Orchestrator),负责调度和协调各个服务的操作,并在需要时触发补偿机制。
2.1 组成部分
- Saga Orchestrator:负责整个事务流程的控制和协调。
- 命令和事件定义:如
CreateOrderCommand
、PaymentCommand
等。 - Kafka 生产者与消费者:用于命令和事件的发布与订阅。
- 各服务逻辑:根据接收到的命令执行操作,并发布相应的事件。
2.2 实现步骤与代码
2.2.1 定义命令和事件
// CreateOrderCommand.java
public class CreateOrderCommand {private String orderId;private String product;private int quantity;// getters and setters
}// OrderCreatedEvent.java
public class OrderCreatedEvent {private String orderId;// getters and setters
}// PaymentCommand.java
public class PaymentCommand {private String orderId;private double amount;// getters and setters
}// PaymentApprovedEvent.java
public class PaymentApprovedEvent {private String orderId;// getters and setters
}// PaymentRejectedEvent.java
public class PaymentRejectedEvent {private String orderId;private String reason;// getters and setters
}// CancelOrderCommand.java
public class CancelOrderCommand {private String orderId;// getters and setters
}// OrderCancelledEvent.java
public class OrderCancelledEvent {private String orderId;// getters and setters
}
2.2.2 实现 SagaOrchestrator
@Service
public class SagaOrchestrator {@Autowiredprivate KafkaTemplate<String, String> kafkaTemplate;private ObjectMapper mapper = new ObjectMapper();@KafkaListener(topics = "order-created", groupId = "saga-orchestrator-group")public void handleOrderCreated(String message) throws JsonProcessingException {OrderCreatedEvent event = mapper.readValue(message, OrderCreatedEvent.class);try {// 发送 PaymentCommandPaymentCommand paymentCommand = new PaymentCommand();paymentCommand.setOrderId(event.getOrderId());paymentCommand.setAmount(calculateAmount(event.getOrderId()));String paymentCmd = mapper.writeValueAsString(paymentCommand);kafkaTemplate.send("payment-command", paymentCmd);} catch (Exception e) {// 发送补偿命令sendCancelOrderCommand(event.getOrderId());}}@KafkaListener(topics = "payment-approved", groupId = "saga-orchestrator-group")public void handlePaymentApproved(String message) throws JsonProcessingException {PaymentApprovedEvent event = mapper.readValue(message, PaymentApprovedEvent.class);// 继续后续操作,如库存更新// TODO: 发送其他命令或处理逻辑}@KafkaListener(topics = "payment-rejected", groupId = "saga-orchestrator-group")public void handlePaymentRejected(String message) throws JsonProcessingException {PaymentRejectedEvent event = mapper.readValue(message, PaymentRejectedEvent.class);// 发送补偿命令sendCancelOrderCommand(event.getOrderId());}public void startSaga(Order order) throws JsonProcessingException {// 发送 CreateOrderCommandCreateOrderCommand createCommand = new CreateOrderCommand();createCommand.setOrderId(order.getId());createCommand.setProduct(order.getProduct());createCommand.setQuantity(order.getQuantity());String createCmd = mapper.writeValueAsString(createCommand);kafkaTemplate.send("create-order-command", createCmd);}private void sendCancelOrderCommand(String orderId) throws JsonProcessingException {CancelOrderCommand cancelCommand = new CancelOrderCommand();cancelCommand.setOrderId(orderId);String cancelMsg = mapper.writeValueAsString(cancelCommand);kafkaTemplate.send("cancel-order-command", cancelMsg);}private double calculateAmount(String orderId) {// TODO: 实现金额计算逻辑return 100.0;}
}
2.2.3 修改 OrderService
@Service
public class OrderService {@Autowiredprivate KafkaTemplate<String, String> kafkaTemplate;private ObjectMapper mapper = new ObjectMapper();@KafkaListener(topics = "create-order-command", groupId = "order-service-group")public void handleCreateOrder(String message) throws JsonProcessingException {CreateOrderCommand command = mapper.readValue(message, CreateOrderCommand.class);// 创建订单逻辑// TODO: 保存订单到数据库// 发布 OrderCreatedEventOrderCreatedEvent event = new OrderCreatedEvent();event.setOrderId(command.getOrderId());String eventMsg = mapper.writeValueAsString(event);kafkaTemplate.send("order-created", eventMsg);}@KafkaListener(topics = "cancel-order-command", groupId = "order-service-group")public void handleCancelOrder(String message) throws JsonProcessingException {CancelOrderCommand command = mapper.readValue(message, CancelOrderCommand.class);// 取消订单逻辑cancelOrder(command.getOrderId());// 发布 OrderCancelledEventOrderCancelledEvent event = new OrderCancelledEvent();event.setOrderId(command.getOrderId());String cancelledMsg = mapper.writeValueAsString(event);kafkaTemplate.send("order-cancelled", cancelledMsg);}private void cancelOrder(String orderId) {// TODO: 实现取消订单逻辑}
}
2.2.4 修改 PaymentService
@Service
public class PaymentService {@Autowiredprivate KafkaTemplate<String, String> kafkaTemplate;private ObjectMapper mapper = new ObjectMapper();@KafkaListener(topics = "payment-command", groupId = "payment-service-group")public void handlePaymentCommand(String message) throws JsonProcessingException {PaymentCommand command = mapper.readValue(message, PaymentCommand.class);// 处理支付逻辑boolean approved = processPayment(command.getOrderId(), command.getAmount());if (approved) {// 发布 PaymentApprovedEventPaymentApprovedEvent event = new PaymentApprovedEvent();event.setOrderId(command.getOrderId());String approvedMsg = mapper.writeValueAsString(event);kafkaTemplate.send("payment-approved", approvedMsg);} else {// 发布 PaymentRejectedEventPaymentRejectedEvent rejectedEvent = new PaymentRejectedEvent();rejectedEvent.setOrderId(command.getOrderId());rejectedEvent.setReason("Payment was rejected.");String rejectedMsg = mapper.writeValueAsString(rejectedEvent);kafkaTemplate.send("payment-rejected", rejectedMsg);}}private boolean processPayment(String orderId, double amount) {// TODO: 实现支付逻辑,模拟支付失败return false;}
}
2.2.5 实现 InventoryService
@Service
public class InventoryService {@KafkaListener(topics = "order-cancelled", groupId = "saga-orchestrator-group")public void handleOrderCancelled(String message) throws JsonProcessingException {OrderCancelledEvent cancelledEvent = new ObjectMapper().readValue(message, OrderCancelledEvent.class);// 回滚库存逻辑rollbackInventory(cancelledEvent.getOrderId());}private void rollbackInventory(String orderId) {// TODO: 实现库存回滚逻辑}
}
2.3 事务补偿机制
在 指挥模式 中,Saga Orchestrator 作为中央控制器,负责监控事务流程并在发生错误时触发补偿操作。例如,当 PaymentService
处理支付失败时,发布 PaymentRejectedEvent
,Saga Orchestrator 监听到该事件后,发送 CancelOrderCommand
给 OrderService
执行订单取消操作,确保系统一致性。
总结
Saga 模式为分布式系统中的长事务管理提供了一种高效且灵活的解决方案。通过 编排 与 指挥 两种实现方式,开发者可以根据具体业务需求和系统架构选择最合适的方式。
- 编排模式 适用于服务间关系较为松散、需要高扩展性的场景,各服务通过事件进行独立协调,但补偿逻辑较为分散。
- 指挥模式 适用于需要集中控制事务流程、易于追踪和调试的场景,Saga Orchestrator 作为中央管理者,补偿逻辑统一管理,但可能成为系统的瓶颈。
无论选择哪种模式,事务补偿机制 都是确保系统可靠性和一致性的关键。通过合理设计补偿逻辑,可以有效应对分布式环境下的各种故障和异常,提升系统的健壮性。
借助 Spring Boot 和 Kafka 强大的生态和工具支持,实现 Saga 模式变得更加便捷和高效。希望本文能够帮助你深入理解 Saga 模式,并在实际项目中灵活应用,打造稳定可靠的分布式系统。
参考资料
- Saga Patterns: Managing Data Consistency in Microservices
- Spring Cloud Stream 与 Kafka 集成
- Axon Framework 官方文档
版权声明
本文为原创内容,转载请注明出处。
相关文章:
【系统设计】高效的分布式系统:使用 Spring Boot 和 Kafka 实现 Saga 模式
在现代分布式系统中,管理跨多个服务的长事务至关重要。传统的分布式事务解决方案往往面临性能瓶颈和复杂性问题,而 Saga 模式 作为一种灵活高效的解决方案,逐渐受到开发者的青睐。本文将探讨如何利用 Spring Boot 和 Kafka 实现 Saga 模式&am…...
蓝桥杯 python day01 第一题
1. 确定字符串是否包含唯一字符 确定字符串是否包含唯一字符 题目描述 实现一个算法来识别一个字符串的字符是否是唯一的(忽略字母大小写)。 若唯一,则输出YES,否则输出NO。 输入描述 输入一行字符串,长度不超过…...

10款好用的win10录屏软件带你体验专业录屏。
其实win10系统的设备上有自带的录屏功能,还有powerpoint里面也有录屏工具可以使用。如果有朋友觉得里面的功能并不能够满足自己的录屏需求的话,可以用专门的录屏软件来完成。比如我最近找到的这4款工具,录制的视频效果好,操作还方…...

2025浙江省考报名流程详细教程
2025年浙江省考报名马上就要开始了,有想要参加浙江省考的同学,可以提前看一下报名流程,和报名照要求。 报名时间:11月6日9时一11月11日17时 南核时间:11月6日9时一11月13日17时 缴费时间:11月14日9时一11月…...
unity3d——关于GetComponent<T>()
先看代码: TankBaseObj obj other.GetComponent<TankBaseObj>();if(obj ! null){//说明是坦克打到坦克 受伤处理 固定不会受伤 移动的会受伤obj.Wound(fatherObj);} TankBaseObj 是一个基类 wound是一个虚函数 子类已经重新实现 当你的游戏对象依附…...

Spring 框架中常见的注解(Spring、SpringMVC、SpringBoot)
1. Spring 中常见注解 还有Recourse:相当于AutowiredQualifier Value : 用于将配置文件中的值注入到Bean的字段中。 Bean : 用于在配置类中声明一个Bean。 Lazy : 用于延迟加载Bean。 2. SpringMVC 中常见注解 还有GetMapping PostMapping PutMapping DeleteMapp…...

Hms?: 1渗透测试
靶机:Hms?: 1 Hms?: 1 ~ VulnHub 攻击机:kail linux 2024 主机扫描阶段发现不了靶机,所以需要按DriftingBlues2一样手动配置网卡 1,将两台虚拟机网络连接都改为NAT模式,并查看靶机的MAC地址 2,攻击机上做主机扫描发现…...

1、Qt6 Quick 简介
一、Qt6 Quick 简介 1、Qt Quick简介 Qt Quick 是 Qt 6 中使用的用户界面技术的总称。它是在 Qt 4 中引入的,现在在 Qt 6 中进行了扩展。Qt Quick 本身是几种技术的集合: QML——用户界面标记语言JavaScript - 动态脚本语言Qt C - 高度可移植的增强型…...
大模型论文集-20241103
Investigating the catastrophic forgetting in multimodal large language models 研究问题 本文探讨了多模态大型语言模型(MLLMs)在学习新任务时的灾难性遗忘现象。研究者关注于在添加新数据集后,模型是否能够保留之前学到的知识而不忘记…...

GESP4级考试语法知识(计数排序-桶排序)
整数排列参考程序代码: #include<iostream> #include<cstring> using namespace std; int main() {int a[101],n,i,j,k;memset(a,0,sizeof(a)); //数组清0cin>>n; //输入数字个数for(i1;i<n;i) {cin>>k; //输…...

红队-shodan搜索引擎篇
如涉及侵权马上删除文章 笔记的只是方便各位师傅学习知识,以下网站只涉及学习内容,其他的都与本人无关,切莫逾越法律红线,否则后果自负 一.shodan原理与功能的介绍 Shodan Search Engine 它是专门搜网络设备的,只要联网的,只要有IP地址的都可以称为网络设备 1.shodan&#x…...
SQL 数据结构查询
1:查询变得结构。 SELECT COLID,SO.NAME,EP.VALUE,SO.LENGTH,MIN(ST.NAME) AS TYPE FROM SYS.EXTENDED_PROPERTIES EP RIGHT JOIN SYS.SYSCOLUMNS SO ON MAJOR_IDID AND COLIDMINOR_ID LEFT JOIN SYS.SYSTYPES ST ON ST.XTYPESO…...

《高频电子线路》—— 角度调制(调相、调频)
文章内容来源于【中国大学MOOC 华中科技大学通信(高频)电子线路精品公开课】,此篇文章仅作为笔记分享。 目录 角度调制(调相、调频) 角度调制的原因 调频VS调幅 角度调制的分类 本章重难点 调相 时域࿰…...

危机来临前---- 力扣: 876
危机即将来临 – 链表的中间节点 描述: 给你单链表的头结点 head ,请你找出并返回链表的中间结点。如果有两个中间结点,则返回第二个中间结点。 示例: 何解? 1、遍历找到中间节点 : 这个之在回文链表中找…...
langchain调用chatgpt对文本进行编码
1.导包 from langchain_openai import OpenAIEmbeddings2.加载编码器 embeddings_model OpenAIEmbeddings(model"text-embedding-3-large",base_url"https://api.chatanywhere.tech/v1")3.编码 embeded_result embeddings_model.embed_documents([&qu…...
python manage.py
自定义命令python manage.py 文件夹建立:(Python Package)这个形式的包,里面会自动加载__init__.py文件 1.新建management文件夹(文件必须加载在新建APP下,不能建在初始APP下) 2.在里面创建名为:commands的文件夹 3.在其下创建名…...

qt QDoubleSpinBox详解
1、概述 QDoubleSpinBox是Qt框架中的一个控件,专门用于浮点数(即小数)的输入和调节。它提供了一个用户界面元素,允许用户在预设的范围内通过拖动滑块、点击箭头或使用键盘来递增或递减浮点数值。QDoubleSpinBox通常用于需要精确数…...
RK3229 Android9自定义一个按键实现长按短按
一、kernel修改 --- a/arch/arm/boot/dts/rk3229-evb-android.dtsib/arch/arm/boot/dts/rk3229-evb-android.dtsi-18,26 18,25 };gpio_keys {status "okay";compatible "gpio-keys";#address-cells <1>;#size-cells <0>;autorepeat;pinct…...
A*算法求第k短路
话不多说先上例题。。 acwing:178. 第K短路 给定一张 NN 个点(编号 1,2…N1,2…N),MM 条边的有向图,求从起点 SS 到终点 TT 的第 KK 短路的长度,路径允许重复经过点或边。 注意: 每条最短路中至…...

CVPR’25截稿在即:今年的重大新规,你知道吗?
介绍会议: CVPR 2025全称是 IEEE/CVF Conference on Computer Vision and Pattern Recognition,即IEEE/CVF国际计算机视觉与模式识别会议。将于2025年6月11日至15日在美国田纳西州纳什维尔召开,CVPR是计算机视觉和模式识别领域的顶级会议。与…...

深入剖析AI大模型:大模型时代的 Prompt 工程全解析
今天聊的内容,我认为是AI开发里面非常重要的内容。它在AI开发里无处不在,当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗",或者让翻译模型 "将这段合同翻译成商务日语" 时,输入的这句话就是 Prompt。…...

AI Agent与Agentic AI:原理、应用、挑战与未来展望
文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例:使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例:使用OpenAI GPT-3进…...
【Linux】C语言执行shell指令
在C语言中执行Shell指令 在C语言中,有几种方法可以执行Shell指令: 1. 使用system()函数 这是最简单的方法,包含在stdlib.h头文件中: #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...
第25节 Node.js 断言测试
Node.js的assert模块主要用于编写程序的单元测试时使用,通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试,通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...

深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用
文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么?1.1.2 感知机的工作原理 1.2 感知机的简单应用:基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...

论文阅读笔记——Muffin: Testing Deep Learning Libraries via Neural Architecture Fuzzing
Muffin 论文 现有方法 CRADLE 和 LEMON,依赖模型推理阶段输出进行差分测试,但在训练阶段是不可行的,因为训练阶段直到最后才有固定输出,中间过程是不断变化的。API 库覆盖低,因为各个 API 都是在各种具体场景下使用。…...

在 Spring Boot 中使用 JSP
jsp? 好多年没用了。重新整一下 还费了点时间,记录一下。 项目结构: pom: <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://ww…...

CVPR2025重磅突破:AnomalyAny框架实现单样本生成逼真异常数据,破解视觉检测瓶颈!
本文介绍了一种名为AnomalyAny的创新框架,该方法利用Stable Diffusion的强大生成能力,仅需单个正常样本和文本描述,即可生成逼真且多样化的异常样本,有效解决了视觉异常检测中异常样本稀缺的难题,为工业质检、医疗影像…...
命令行关闭Windows防火墙
命令行关闭Windows防火墙 引言一、防火墙:被低估的"智能安检员"二、优先尝试!90%问题无需关闭防火墙方案1:程序白名单(解决软件误拦截)方案2:开放特定端口(解决网游/开发端口不通)三、命令行极速关闭方案方法一:PowerShell(推荐Win10/11)方法二:CMD命令…...
算法250609 高精度
加法 #include<stdio.h> #include<iostream> #include<string.h> #include<math.h> #include<algorithm> using namespace std; char input1[205]; char input2[205]; int main(){while(scanf("%s%s",input1,input2)!EOF){int a[205]…...