后端工作流自动化流程编排【免费下载链接】workflow-coreLightweight workflow engine for .NET Standard项目地址https://gitcode.com/gh_mirrors/wo/workflow-core点击查看免费下载本指南围绕 Workflow Core 官方提供程序WorkflowCore.LockProviders.SqlServer展开讲解如何利用 SQL Server 内置的sp_getapplock/sp_releaseapplock存储过程实现分布式锁管理器DLMDistributed Lock Manager从而支撑多节点集群并发处理工作流。读完本文你将掌握该提供程序的安装、配置、底层锁机制、资源命名与返回码语义并能在自己的 ASP.NET Core / 控制台应用中组合队列提供程序搭建真正可水平扩展的 Workflow Core 集群。为什么需要分布式锁从单节点到集群Workflow Core 默认在单节点模式下运行。从 WorkflowOptions 的源码可以看到其内置的锁与队列均为进程内实现LockFactory默认构造SingleNodeLockProviderQueueFactory默认构造SingleNodeQueueProvider。SingleNodeLockProvider 内部只是一个受lock保护的HashSetstring锁只在当前进程内有效。这意味着当多个节点同时处理队列中的同一个工作流时内存锁无法跨进程互斥两个节点可能同时取出并执行同一个工作流实例导致状态竞争、重复执行与数据损坏。而 multi-node-clusters 文档 明确指出要运行多节点集群必须同时配置外部队列提供程序与分布式锁管理器来协调各节点。WorkflowCore.LockProviders.SqlServer正是官方提供的分布式锁管理器实现它以 SQL Server 为锁的权威存储通过应用锁Application Lock实现跨节点互斥让多个节点可以安全地共同消费同一个工作流队列。安装提供程序通过 NuGet 安装官方包PM Install-Package WorkflowCore.LockProviders.SqlServer该包面向netstandard2.0见 WorkflowCore.LockProviders.SqlServer.csproj因此可被 .NET Standard 2.0 及以上版本的宿主项目引用。它依赖Microsoft.Data.SqlClient当前仓库锁定版本为 5.1.5并通过项目引用依赖核心库WorkflowCore无需额外手工配置。快速配置一行代码接入在构建服务提供程序通常为依赖注入容器时调用UseSqlServerLocking扩展方法即可替换默认的锁实现services.AddWorkflow(x x.UseSqlServerLocking(connection string));这里的connection string即指向你 SQL Server 实例的 ADO.NET 连接字符串。扩展方法定义在 ServiceCollectionExtensions.cs其实现非常简洁public static WorkflowOptions UseSqlServerLocking(this WorkflowOptions options, string connectionString) { options.UseDistributedLockManager(sp new SqlLockProvider(connectionString, sp.GetServiceILoggerFactory())); return options; }它通过 WorkflowOptions.UseDistributedLockManager 将LockFactory替换为SqlLockProvider随后在 ServiceCollectionExtensions.AddWorkflow 中该工厂被注册为IDistributedLockProvider单例。所有后台任务与控制器都会从容器解析这个单例并使用它。配合持久化提供程序例如 WorkflowCore.Persistence.SqlServer和队列提供程序例如 WorkflowCore.QueueProviders.SqlServer 或 RabbitMQ一起注册即可形成完整的集群化配置services.AddWorkflow(x { x.UseSqlServerLocking(Server...;Database...;User Id...;Password...;); x.UseSqlServerPersistence(Server...;Database...;User Id...;Password...;); // x.UseQueueProvider(...); // 外部队列如 SQL Server / RabbitMQ / Redis 队列 });底层原理SqlLockProvider 如何工作锁接口契约所有分布式锁提供程序都实现 IDistributedLockProvider 接口其核心方法为Taskbool AcquireLock(string Id, CancellationToken cancellationToken)尝试获取指定资源 ID 的锁成功返回trueTask ReleaseLock(string Id)释放指定资源 ID 的锁Task Start()/Task Stop()生命周期钩子由WorkflowHost在启动/停止时调用见 WorkflowHost.cs 与#L139。SqlLockProvider对这两个方法直接返回已完成的任务无需额外初始化。sp_getapplock 的参数语义SqlLockProvider.cs 是核心实现它把每个工作流资源映射为一条 SQL Server 应用锁。获取锁时执行sp_getapplock存储过程关键参数如下参数取值说明Resourcewfc:{Id}锁资源名称以固定前缀wfcWorkflow Core 缩写加冒号再拼接资源 ID避免与其他应用的应用锁冲突LockOwnerSession锁归属范围为当前数据库会话连接断开时锁自动释放防止节点崩溃后锁永久残留LockModeExclusive排他锁同一时刻只能有一个节点持有LockTimeout0获取锁的等待超时毫秒。为0表示不等待立即返回获取结果构造函数中还通过SqlConnectionStringBuilder对连接字符串做了两处增强见 SqlLockProvider.cs强制开启连接池Pooling true并把ApplicationName设置为Workflow Core Lock Manager便于在 SQL Server 侧诊断连接来源。返回码语义谁抢到了锁sp_getapplock通过RetVal返回码告知结果SqlLockProvider逐一处理对应 SqlLockProvider.cs返回码含义提供程序行为 0锁获取成功记录连接并返回true表示本次会话持锁成功-1请求超时本次因LockTimeout 0通常表现为立即失败记录 Debug 日志返回false-2请求被取消记录 Debug 日志返回false-3被选为死锁牺牲者记录 Debug 日志返回false-999参数错误或其他内部错误记录 Error 日志返回false只有返回码非负时才认为持锁成功否则关闭连接并放弃本次处理。锁的生命周期从持锁到释放持锁期间成功的连接被保存在进程内字典_locks[Id]中后续释放锁时直接复用同一连接调用sp_releaseapplock同样以Session为LockOwner。若sp_releaseapplock返回码为负则记录错误日志。进程内互斥AcquireLock与ReleaseLock外围均有AutoResetEvent _mutex保护保证同一节点内对锁字典与连接集合的并发访问是线程安全的。容错设计由于锁归属于数据库会话即使节点进程崩溃、连接断开SQL Server 也会自动释放该锁不会出现锁永远无法释放的僵局同时每次获取锁都新建独立连接天然避免了会话复用带来的误释放风险。分布式锁在 Workflow Core 中的实际应用场景从源码结构看IDistributedLockProvider被注入到多个核心服务中锁的粒度与资源 ID 设计如下WorkflowConsumer工作流队列消费者。出队后先AcquireLock(itemId)即工作流实例 ID再执行若获取失败则直接跳过本次说明该实例正被其他节点处理。执行完成后在finally中释放锁并清理灰名单。EventConsumer事件队列消费者。事件出队时对evt:{itemId}加锁唤醒订阅时对订阅所属的sub.WorkflowId加锁防止多个节点同时投递同一事件。RunnablePoller轮询器通过poll runnables、unprocessed events、poll-commands等全局资源 ID 加锁保证同一时刻只有一个节点在轮询持久化存储并派发可执行实例。WorkflowController启动、挂起、恢复、终止工作流等管理操作均以workflowId加锁避免管理操作与消费者并发修改同一实例。ActivityController活动订阅以sub:{subscription.Id}加锁协调分布式活动令牌的领取。SyncWorkflowRunner同步执行器同样基于锁保证同步执行的互斥性。这些场景印证了分布式锁的两种粒度实例级按 workflowId / eventKey 精确互斥同一资源与全局级固定资源 ID 实现主节点选举式互斥二者共同保证集群中的并发安全。集群部署与配置注意事项必须搭配外部队列提供程序锁只解决谁先执行的互斥问题不解决工作项如何在节点间分发的问题。集群化需要同时配置外部队列如仓库内的 WorkflowCore.QueueProviders.SqlServer、WorkflowCore.QueueProviders.RabbitMQ 等详见 multi-node-clusters 文档。SQL Server 连接要求提供程序需要能够连接到你指定的 SQL Server 实例并具备执行sp_getapplock/sp_releaseapplock的权限public数据库角色默认即可调用这两类系统存储过程。它不要求额外的表或初始化脚本也不依赖 Workflow Core 自身的持久化表。锁超时行为由于LockTimeout 0获取锁采用立即失败而非阻塞等待的策略消费者获取锁失败后会跳过本次轮询、等待下一个轮询周期重试。这与 WorkflowOptions.PollInterval默认 10 秒共同决定了集群的调度节奏。资源前缀隔离所有锁资源都以wfc:为前缀多个 Workflow Core 集群若共享同一个 SQL Server 实例可通过前缀天然隔离若需进一步区分可考虑使用不同数据库。总结WorkflowCore.LockProviders.SqlServer是一个零依赖外部中间件如 Redis、ZooKeeper的分布式锁方案——只要你的基础设施中已有 SQL Server就可以用一行UseSqlServerLocking(connectionString)将 Workflow Core 从单节点升级为多节点集群。其底层借助 SQL Server 成熟的应用锁机制sp_getapplock/sp_releaseapplock会话级锁所有权实现了跨节点的互斥与崩溃自动释放配合外部队列提供程序即可支撑工作流引擎的水平扩展。赞分享后端工作流自动化流程编排【免费下载链接】workflow-coreLightweight workflow engine for .NET Standard项目地址https://gitcode.com/gh_mirrors/wo/workflow-core点击查看免费下载相关推荐ASP.NET Core 缓存库 SqlServer 测试指南基于真实 SQL Server 的分布式缓存功能测试ASP.NET Core 缓存库 SqlServer 测试指南基于真实 SQL Server 的分布式缓存功能测试 导读 在 ASP.NET Core 的 s后端Web框架dotnet-sql-cache 工具实战指南为 ASP.NET Core SQL Server 分布式缓存创建表与索引dotnet sql cache 工具实战指南为 ASP.NET Core SQL Server 分布式缓存创建表与索引 导读 dotnet sql cach后端Web框架基于 PostgreSQL 咨询锁的分布式锁实现Medusa medusajs/locking-postgres 模块提供者全解析基于 PostgreSQL 咨询锁的分布式锁实现Medusa medusajs/locking postgres 模块提供者全解析 本篇文章围绕 Medus后端电商前端上一篇Airbyte Orb 数据源连接器深度解析基于 Low-Code CDK 的声明式实现与增量同步实战下一篇WinUtilWindows系统管理的终极免费工具3分钟快速配置新电脑创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
阅读完成 · 觉得有帮助?