Go语言Saga模式实战:构建高可用的分布式事务解决方案

news2026/5/10 4:21:24
1. 项目概述一个分布式事务的“传奇”框架最近在梳理团队的后端技术栈特别是微服务架构下的数据一致性问题发现大家对于分布式事务框架的选型和使用存在不少困惑。正好我花了些时间深度研究并实践了 GitHub 上一个名为Lanerra/saga的开源项目。这个名字很有意思“Saga”直译是“传奇”在分布式系统领域它特指一种解决长事务问题的经典模式。这个项目就是一个用 Go 语言实现的、轻量且实用的 Saga 模式框架。简单来说Lanerra/saga 解决的核心痛点是在微服务架构中一个业务操作比如“创建订单”需要跨多个服务订单服务、库存服务、支付服务来完成如何保证这一系列操作要么全部成功要么全部回滚尤其是在某个中间步骤失败的情况下传统的两阶段提交2PC太重而简单的本地事务又无法覆盖跨服务边界。Saga 模式通过将一个大事务拆解为一系列可补偿的本地子事务并提供一个协调器来管理它们的执行与回滚优雅地解决了这个问题。Lanerra/saga 框架的价值在于它没有重复造轮子去实现一个庞大的分布式事务中间件而是聚焦于提供一套清晰、简洁的 Go 语言 SDK 和协调逻辑。它非常适合那些已经采用 Go 技术栈、服务粒度适中、且希望以较低侵入性方式引入最终一致性保障的团队。如果你正在为服务间数据不一致而头疼或者想找一个比“发消息重试”更严谨的方案那么这个项目值得你深入了解。2. 核心设计思想与架构拆解2.1 Saga 模式精要从“大事务”到“可补偿链”要理解 Lanerra/saga必须先吃透 Saga 模式的核心思想。我们可以把它想象成一次多阶段的旅行预订你先订机票步骤1再订酒店步骤2最后租车步骤3。如果租车失败了你不能让机票和酒店订单就这么悬着你需要取消酒店补偿步骤2再取消机票补偿步骤1让整个系统回到最初的状态。这就是 Saga 的核心——正向执行链与反向补偿链。与 ACID 事务的“强一致性”和“隔离性”不同Saga 追求的是最终一致性。它允许在事务执行过程中系统处于一个暂时的、不一致的中间状态比如机票已订酒店未订但通过预定义的补偿操作最终总能达到一致的状态全部成功或全部回滚。这种模式牺牲了部分隔离性中间状态对其他事务可见换来了更高的可用性和吞吐量非常适合松耦合的微服务场景。Lanerra/saga 框架的设计正是基于这一理念。它将一个业务事务定义为一个由多个“参与者”组成的 Saga。每个参与者需要提供两个关键函数一个执行正向操作的Execute函数和一个用于回滚的Compensate函数。框架的协调器负责按顺序调用这些函数并在任何Execute失败时自动触发已成功步骤的Compensate函数进行反向回滚。2.2 框架架构与组件职责Lanerra/saga 的架构非常清晰主要包含以下几个核心组件Saga 协调器 (Coordinator)这是框架的大脑。它负责接收一个 Saga 定义包含参与者列表并驱动整个执行流程。其核心职责是维护 Saga 的执行状态如开始、执行中、已提交、已补偿、失败并决定下一步该调用哪个参与者的哪个函数。协调器必须具有持久化能力以防止进程崩溃导致状态丢失Lanerra/saga 通常依赖外部存储如数据库来实现这一点。参与者 (Participant)代表业务逻辑中的一个步骤。每个参与者是一个结构体必须实现Execute(ctx context.Context) error和Compensate(ctx context.Context) error两个方法。Execute包含业务主逻辑Compensate则是对应的、等幂的撤销逻辑。例如一个“扣减库存”参与者的Compensate就是“增加库存”。日志与状态存储 (Log State Store)这是 Saga 可靠性的基石。协调器需要将每一个关键事件如 Saga 开始、参与者执行开始/成功/失败、补偿开始/成功/失败持久化到日志中。同时Saga 的当前状态也需要持久化。这样即使协调器进程重启它也能从存储中恢复状态并继续执行或补偿。Lanerra/saga 抽象了存储接口允许用户接入 MySQL、PostgreSQL 或 Redis 等。执行器 (Executor)负责实际调用参与者方法的组件。它从协调器接收指令调用相应的Execute或Compensate函数并将结果成功或包含错误信息的失败返回给协调器。执行器通常会处理超时、重试等逻辑。这个架构的优势在于职责分离和可扩展性。业务开发者只需要关心如何实现参与者的两个方法而事务的协调、恢复、持久化等复杂问题由框架统一处理。这种设计极大地降低了使用分布式事务的门槛。注意Saga 模式要求补偿操作必须是等幂的。因为网络超时等原因协调器可能会重复调用同一个补偿函数。如果你的Compensate里是“发送一封邮件通知”那重复执行就会造成问题。正确的做法是补偿操作应该设计成“设置状态为已取消”或“增加回滚标识”确保多次执行效果相同。3. 核心实现细节与实操要点3.1 参与者接口设计与实现规范在 Lanerra/saga 中定义一个参与者是使用的起点。框架通常会定义一个接口例如type Participant interface { Execute(ctx context.Context) error Compensate(ctx context.Context) error }在实际项目中你需要为每一个业务步骤创建一个结构体来实现这个接口。这里有几个关键的实现规范第一上下文传递与超时控制。Execute和Compensate方法的第一个参数都是context.Context。你必须利用好这个上下文。在Execute内部当你调用其他服务的 gRPC 或 HTTP 接口时应该使用传入的这个ctx这样协调器设置的超时才能在整个 Saga 链路中生效。例如func (p *InventoryParticipant) Execute(ctx context.Context) error { // 使用传入的ctx确保能继承超时和取消信号 resp, err : inventoryClient.DeductStock(ctx, pb.DeductRequest{...}) if err ! nil { return fmt.Errorf(deduct stock failed: %w, err) } // 将本次操作生成的业务ID如库存流水号保存到参与者结构体中供Compensate使用 p.deductRecordID resp.RecordId return nil }第二补偿操作的等幂性与数据准备。Compensate方法必须能够安全地重复执行。常见的做法是在Execute成功后将回滚所需的关键数据如上例中的deductRecordID保存在参与者的实例变量中。这样在Compensate中就可以根据这个 ID 执行精准的回滚操作比如将对应流水记录的状态标记为“已冲正”而不是简单地“库存1”后者在重试时可能导致数据错误。第三业务异常与系统异常分离。在Execute或Compensate中你返回的error需要被框架正确解读。通常框架会区分“业务逻辑失败”如库存不足和“系统暂时性失败”如网络超时。对于后者框架可能会进行重试。因此你应该根据错误类型返回不同的错误或者通过实现特定的错误接口来让框架识别。例如可以约定返回ErrBusinessFailure表示不应重试的业务失败而其他错误则可能触发重试机制。3.2 协调器的状态机与持久化策略协调器是 Saga 的大脑其核心是一个状态机。一个典型的 Saga 状态流转如下[Idle] - [Started] - [Executing Participant 1] - [Participant 1 Succeeded] - [Executing Participant 2] - ... - [All Participants Succeeded] - [Committed]如果任何步骤失败... - [Participant N Failed] - [Compensating Participant N-1] - ... - [Compensating Participant 1] - [Compensated]Lanerra/saga 的协调器需要将这个状态机以及每个参与者的执行结果持久化。持久化通常涉及两张核心表Saga 实例表记录每个 Saga 全局信息。CREATE TABLE saga_instance ( id VARCHAR(64) PRIMARY KEY, biz_type VARCHAR(50) NOT NULL, -- 业务类型如create_order status VARCHAR(20) NOT NULL, -- 状态STARTED, EXECUTING, COMPENSATING, SUCCEEDED, FAILED, COMPENSATED input_data TEXT, -- 启动时的业务参数JSON格式 created_at TIMESTAMP NOT NULL, updated_at TIMESTAMP NOT NULL );Saga 日志表记录每一次状态变迁的详细事件用于故障恢复和审计。CREATE TABLE saga_log ( id BIGINT PRIMARY KEY AUTO_INCREMENT, saga_id VARCHAR(64) NOT NULL, participant_name VARCHAR(100), -- 当前操作的参与者名 event_type VARCHAR(30) NOT NULL, -- 事件EXECUTE_START, EXECUTE_SUCCESS, EXECUTE_FAIL, COMPENSATE_START, COMPENSATE_SUCCESS payload TEXT, -- 事件详情如错误信息 created_at TIMESTAMP NOT NULL, INDEX idx_saga_id (saga_id) );持久化时机是关键。协调器必须在状态变更后和调用下一个参与者前完成持久化。这确保了即使协调器进程在调用参与者后崩溃重启后也能从日志中知道最后一个持久化的状态并决定是重试执行还是开始补偿。这种“先持久化后操作”的模式是 Saga 实现可靠性的核心。3.3 超时、重试与幂等性保障机制在分布式环境下网络分区、服务瞬时故障是常态。Lanerra/saga 框架要具备生产可用性必须在超时、重试和幂等方面做足功夫。超时控制协调器在启动一个 Saga 时应该设置一个全局超时时间。这个时间会通过context.Context传递给每一个参与者。此外每个参与者也可以有自己的局部超时设置。当超时发生时协调器会将当前 Saga 标记为失败并启动补偿流程。你需要根据业务逻辑的复杂程度合理设置这些超时值。重试策略并非所有失败都需要立即补偿。对于网络抖动、数据库连接池满等暂时性故障应该进行重试。Lanerra/saga 通常会在执行器层面实现重试逻辑。一个常见的策略是“指数退避重试”第一次失败后等待 1 秒重试。第二次失败后等待 2 秒重试。第三次失败后等待 4 秒重试。如果超过最大重试次数如3次或遇到业务逻辑错误如账户余额不足则判定为最终失败触发补偿。重试必须与幂等性结合。参与者的Execute方法也应该是幂等的因为重试可能导致Execute被重复调用。实现方式可以是利用数据库的唯一约束或者在业务层使用“请求ID”或“幂等令牌”来确保同一业务请求只处理一次。实操心得在实现参与者时我强烈建议为每个参与者的操作设计一个唯一业务键。例如创建订单的参与者其业务键可以是“订单类型用户ID时间戳哈希”。在Execute方法中先查询这个业务键是否已存在如果存在且成功则直接返回成功如果存在但失败则视情况决定是重试还是返回失败。这能完美解决重试导致的重复执行问题。4. 完整集成与实战演练4.1 项目初始化与基础配置假设我们有一个电商场景的“创建订单”Saga涉及三个服务订单服务Order、库存服务Inventory、积分服务Credit。我们将使用 Lanerra/saga 来协调这个过程。首先需要在你的 Go 项目中引入该库假设它已发布在某个仓库go get github.com/lanerra/saga接下来定义 Saga 的全局配置。这通常在应用启动时完成可以放在一个独立的saga_config.go文件里。package saga import ( context time github.com/lanerra/saga/core github.com/lanerra/saga/store/sql // 假设使用SQL存储 ) var Coordinator *core.Coordinator func InitSagaCoordinator(dsn string) error { // 1. 初始化存储 store, err : sql.NewStore(dsn) // 传入数据库连接字符串 if err ! nil { return err } // 2. 创建协调器配置 config : core.Config{ Store: store, GlobalTimeout: 30 * time.Second, // 整个Saga最多执行30秒 ParticipantTimeout: 10 * time.Second, // 每个参与者最多10秒 MaxRetryAttempts: 3, // 最大重试次数 RetryDelay: 1 * time.Second, // 重试基础延迟 } // 3. 实例化协调器 Coordinator core.NewCoordinator(config) // 4. 注册Saga定义这里先定义后面会补充参与者 // Coordinator.RegisterSaga(create_order, []core.Participant{...}) // 5. 启动协调器的后台恢复goroutine用于处理崩溃后未完成的Saga go Coordinator.Recover(context.Background()) return nil }在main.go中初始化数据库连接后调用InitSagaCoordinator。4.2 定义并实现业务参与者现在我们来分别实现三个参与者。每个参与者是一个独立的 Go 结构体。订单创建参与者 (OrderCreateParticipant):package saga import ( context fmt your_project/order_service/client ) type OrderCreateParticipant struct { OrderClient order.Client Request *order.CreateRequest // 创建订单的请求参数 OrderID string // 执行成功后保存的订单ID用于补偿 } func (p *OrderCreateParticipant) Execute(ctx context.Context) error { resp, err : p.OrderClient.CreateOrder(ctx, p.Request) if err ! nil { // 可能是业务错误如商品不存在也可能是系统错误 return fmt.Errorf(order service create failed: %w, err) } p.OrderID resp.OrderId // 保存成功后的订单ID return nil } func (p *OrderCreateParticipant) Compensate(ctx context.Context) error { if p.OrderID { // 如果Execute根本没成功则无需补偿 return nil } // 调用订单服务的取消接口。此接口必须是幂等的。 err : p.OrderClient.CancelOrder(ctx, order.CancelRequest{OrderId: p.OrderID}) if err ! nil { // 补偿操作失败是严重问题可能需要告警和人工干预 // 这里返回错误协调器可能会重试补偿 return fmt.Errorf(compensate order failed (order_id: %s): %w, p.OrderID, err) } return nil }库存扣减参与者 (InventoryDeductParticipant):和订单参与者类似Execute调用扣库存接口并保存库存流水IDCompensate用该ID调用恢复库存的接口。积分抵扣参与者 (CreditDeductParticipant):逻辑同上。4.3 组装 Saga 并启动执行在服务层当接收到“创建订单”的请求时我们组装并启动这个 Saga。package service import ( context github.com/google/uuid your_project/internal/saga // 引入上面定义的saga包 ) func CreateOrderSaga(ctx context.Context, req *CreateOrderRequest) error { // 1. 生成全局唯一的Saga实例ID sagaID : uuid.New().String() // 2. 组装参与者列表注意顺序就是执行顺序 participants : []saga.Participant{ saga.OrderCreateParticipant{OrderClient: orderClient, Request: convertReq(req)}, saga.InventoryDeductParticipant{InventoryClient: inventoryClient, Sku: req.Sku, Quantity: req.Quantity}, saga.CreditDeductParticipant{CreditClient: creditClient, UserID: req.UserID, Amount: calculateCredit(req)}, } // 3. 定义Saga可以给它一个业务类型名称方便管理 sagaDef : saga.Definition{ ID: sagaID, BizType: create_order, Participants: participants, // 可以附加一些业务数据供参与者或监控使用 Input: map[string]interface{}{user_id: req.UserID, sku: req.Sku}, } // 4. 启动Saga执行 resultCh : saga.Coordinator.Execute(ctx, sagaDef) // 5. 等待执行结果可以是异步的这里简单同步等待 select { case result : -resultCh: if result.Error ! nil { // Saga执行失败可能已部分补偿 log.Errorf(Saga %s failed: %v, sagaID, result.Error) // 返回给上游的错误信息需要斟酌可能不是直接透传内部错误 return fmt.Errorf(create order transaction failed) } log.Infof(Saga %s succeeded., sagaID) return nil case -ctx.Done(): // 外部上下文超时或取消 // 注意这里外部取消Saga可能还在后台继续执行或补偿需要根据业务需求处理 return ctx.Err() } }这样一个完整的、具备事务能力的“创建订单”流程就封装好了。业务代码只需调用CreateOrderSaga而无需关心内部复杂的跨服务调用和回滚逻辑。5. 生产环境下的问题排查与优化实践5.1 常见故障场景与排查路径在实际运维中Saga 协调器或参与者都可能出现问题。下面是一个常见问题排查表问题现象可能原因排查步骤与解决方案Saga 状态长时间卡在EXECUTING1. 某个参与者Execute方法僵死死锁、无限循环。2. 网络问题导致协调器与执行器/参与者失联。3. 协调器进程崩溃恢复线程未正常工作。1.查日志查看对应参与者的应用日志确认Execute是否打印了开始和结束日志。2.查超时核对协调器配置的ParticipantTimeout和GlobalTimeout。如果超时设置过长可以适当调短。3.查协调器检查协调器日志看恢复线程是否在运行检查数据库saga_instance表中该实例的状态和时间戳。补偿操作失败Saga 状态为FAILED1. 补偿操作本身有bug或依赖服务不可用。2. 补偿操作不幂等重复执行时失败。3. 补偿所需的数据在Execute成功后丢失。1.这是最严重的情况意味着出现了“悬挂”的不一致状态如订单创建了但库存没扣。2.立即告警需要人工介入。查看saga_log表定位是哪个参与者的补偿失败。3.修复补偿逻辑确保其健壮性和幂等性。然后通过管理接口手动触发该Saga的重新补偿。Saga 日志表增长过快1. 业务流量大。2. 未清理历史日志。1. 这是正常现象但需规划存储。可以为saga_log表设计归档策略例如将超过30天的日志转移到历史表或对象存储。2. 确保业务查询和协调器恢复不依赖全量历史日志。参与者重试次数过多影响性能1. 某个下游服务不稳定持续返回可重试错误。2. 重试间隔太短。1.监控告警对参与者的失败重试次数设置监控。2.优化重试策略采用指数退避 随机抖动jitter避免重试雪崩。3.引入熔断器对频繁失败的下游服务调用实施熔断暂时停止调用直接快速失败触发Saga补偿避免资源浪费。5.2 监控、告警与可观测性建设一个健壮的 Saga 系统离不开强大的可观测性。你需要监控以下几个关键指标Saga 执行结果分布统计不同业务类型BizTypeSaga 的成功率、失败率、补偿率。失败率陡增是下游服务故障的早期信号。Saga 执行耗时分布通过 P95、P99 分位数监控 Saga 从开始到结束的耗时。耗时变长可能意味着某个参与者服务性能下降。参与者调用耗时与错误率监控每个参与者Execute和Compensate的调用耗时和错误码。这是定位性能瓶颈和故障点的最直接依据。协调器状态监控协调器后台恢复线程是否活跃内存中待处理的 Saga 实例数量等。告警策略建议紧急告警任何 Saga 进入FAILED状态补偿失败。这需要立即人工干预。重要告警某个业务类型的 Saga 失败率在5分钟内超过5%。警告告警Saga 平均执行耗时超过预设阈值的两倍。实现上可以在协调器记录日志时同时发送事件到监控系统如 Prometheus Grafana或在关键节点如补偿失败调用告警接口。5.3 高阶优化异步化与批量处理当业务流量非常大时同步等待每个 Saga 执行完毕可能会阻塞请求线程。此时可以考虑异步化处理。模式一发后即忘 (Fire-and-Forget)业务 API 只负责创建并启动 Saga然后立即返回一个“业务流水号”或“Saga ID”。客户端通过这个 ID 轮询或通过 WebSocket 等渠道获取最终结果。协调器在 Saga 完成后将结果写入一个共享存储如 Redis或发送一个完成事件。模式二基于消息队列的 Saga这是更解耦的方式。协调器不再直接调用参与者服务而是向消息队列如 Kafka、RocketMQ发布命令事件。每个参与者服务订阅相关的事件执行操作然后向另一个主题发布执行结果事件。协调器监听结果事件来驱动状态机。这种方式吞吐量极高且服务间完全解耦但复杂度也更高需要保证消息的可靠投递和顺序。Lanerra/saga 框架本身可能不直接支持消息队列模式但其核心的状态机思想是通用的。你可以基于其状态持久化机制将“调用参与者”的动作改为“向MQ发布消息”从而实现一个异步、高吞吐的 Saga 协调器。这通常是在业务规模发展到一定阶段后才需要考虑的架构演进。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2599565.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…