16 KiB
事件处理机制
**本文档引用的文件** - [DefaultWebhookPublisher.cs](file://aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks/LINGYUN/Abp/Webhooks/DefaultWebhookPublisher.cs) - [DistributedEventBusWebhookPublisher.cs](file://aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.EventBus/LINGYUN/Abp/Webhooks/EventBus/DistributedEventBusWebhookPublisher.cs) - [WebhooksEventHandler.cs](file://aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/EventBus/Handlers/WebhooksEventHandler.cs) - [WebhookEventStore.cs](file://aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookEventStore.cs) - [WebhookSenderArgs.cs](file://aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks/LINGYUN/Abp/Webhooks/WebhookSenderArgs.cs) - [DefaultWebhookSender.cs](file://aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks/LINGYUN/Abp/Webhooks/DefaultWebhookSender.cs) - [WebhookSubscriptionManager.cs](file://aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks/LINGYUN/Abp/Webhooks/WebhookSubscriptionManager.cs) - [WebhookEventRecord.cs](file://aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookEventRecord.cs) - [WebhookSendAttemptStore.cs](file://aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookSendAttemptStore.cs) - [WebhooksEventData.cs](file://aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.EventBus/LINGYUN/Abp/Webhooks/EventBus/WebhooksEventData.cs)目录
简介
本项目实现了基于ABP框架的Webhooks事件处理机制,提供了一套完整的事件发布、订阅、传输和确认流程。系统通过分布式事件总线实现跨服务通信,利用后台作业进行异步处理,并确保事件传递的可靠性和顺序性。
核心组件
Webhook发布器
IWebhookPublisher接口定义了三种事件发布方法:针对当前租户、指定租户或多个租户发布事件。DefaultWebhookPublisher是其默认实现,负责将事件数据持久化并分发给订阅者。
classDiagram
class IWebhookPublisher {
<<interface>>
+PublishAsync(string webhookName, object data)
+PublishAsync(string webhookName, object data, Guid? tenantId)
+PublishAsync(Guid?[] tenantIds, string webhookName, object data)
}
class DefaultWebhookPublisher {
-IWebhookSubscriptionManager subscriptionManager
-ICurrentTenant currentTenant
-IBackgroundJobManager backgroundJobManager
+WebhookEventStore WebhookEventStore
+PublishAsync(string webhookName, object data)
+PublishAsync(string webhookName, object data, Guid? tenantId)
+PublishAsync(Guid?[] tenantIds, string webhookName, object data)
}
IWebhookPublisher <|.. DefaultWebhookPublisher
图示来源
- IWebhookPublisher.cs
- DefaultWebhookPublisher.cs
Webhook事件存储
IWebhookEventStore接口定义了事件存储操作,WebhookEventStore是其实现类,负责将WebhookEvent实体持久化到数据库中。
classDiagram
class IWebhookEventStore {
<<interface>>
+GetAsync(Guid? tenantId, Guid id) WebhookEvent
+InsertAndGetIdAsync(WebhookEvent webhookEvent) Guid
}
class WebhookEventStore {
-IWebhookEventRecordRepository repository
-IObjectMapper mapper
+GetAsync(Guid? tenantId, Guid id) WebhookEvent
+InsertAndGetIdAsync(WebhookEvent webhookEvent) Guid
}
class WebhookEventRecord {
+Guid Id
+Guid? TenantId
+string WebhookName
+string Data
+DateTime CreationTime
+bool IsDeleted
}
IWebhookEventStore <|.. WebhookEventStore
WebhookEventRecord --> WebhookEvent : "映射"
图示来源
- WebhookEventStore.cs
- WebhookEventRecord.cs
本节来源
- WebhookEventStore.cs
- WebhookEventRecord.cs
Webhook发送器
IWebhookSender接口定义了Webhook发送操作,DefaultWebhookSender是其默认实现,负责通过HTTP客户端向订阅者的端点发送事件。
classDiagram
class IWebhookSender {
<<interface>>
+SendWebhookAsync(WebhookSenderArgs args) Task<Guid>
}
class DefaultWebhookSender {
-IWebhookManager webhookManager
-IHttpClientFactory httpClientFactory
-AbpWebhooksOptions options
+Logger ILogger
+SendWebhookAsync(WebhookSenderArgs args) Task<Guid>
+CreateWebhookRequestMessage(WebhookSenderArgs args) HttpRequestMessage
+CreateWebhookClient(WebhookSenderArgs args) HttpClient
}
class WebhookSenderArgs {
+Guid? TenantId
+Guid WebhookEventId
+string WebhookName
+string Data
+Guid WebhookSubscriptionId
+string WebhookUri
+string Secret
+IDictionary<string, string> Headers
+bool TryOnce
+bool SendExactSameData
+int? TimeoutDuration
}
IWebhookSender <|.. DefaultWebhookSender
图示来源
- DefaultWebhookSender.cs
- WebhookSenderArgs.cs
本节来源
- DefaultWebhookSender.cs
- WebhookSenderArgs.cs
Webhook订阅管理器
IWebhookSubscriptionManager接口定义了订阅管理操作,WebhookSubscriptionManager是其实现类,负责管理租户的Webhook订阅。
classDiagram
class IWebhookSubscriptionManager {
<<interface>>
+GetAsync(Guid id) WebhookSubscriptionInfo
+GetAllSubscriptionsAsync(Guid? tenantId) WebhookSubscriptionInfo[]
+GetAllSubscriptionsIfFeaturesGrantedAsync(Guid? tenantId, string webhookName) WebhookSubscriptionInfo[]
+AddOrUpdateSubscriptionAsync(WebhookSubscriptionInfo subscription)
+ActivateWebhookSubscriptionAsync(Guid id, bool active)
+DeleteSubscriptionAsync(Guid id)
}
class WebhookSubscriptionManager {
-IGuidGenerator guidGenerator
-IUnitOfWorkManager unitOfWorkManager
-IWebhookDefinitionManager definitionManager
+WebhookSubscriptionsStore WebhookSubscriptionsStore
+GetAsync(Guid id) WebhookSubscriptionInfo
+GetAllSubscriptionsAsync(Guid? tenantId) WebhookSubscriptionInfo[]
+GetAllSubscriptionsIfFeaturesGrantedAsync(Guid? tenantId, string webhookName) WebhookSubscriptionInfo[]
+AddOrUpdateSubscriptionAsync(WebhookSubscriptionInfo subscription)
+ActivateWebhookSubscriptionAsync(Guid id, bool active)
+DeleteSubscriptionAsync(Guid id)
}
IWebhookSubscriptionManager <|.. WebhookSubscriptionManager
图示来源
- WebhookSubscriptionManager.cs
本节来源
- WebhookSubscriptionManager.cs
事件发布流程
事件发布序列图
sequenceDiagram
participant Publisher as Webhook发布器
participant Store as 事件存储
participant Manager as 订阅管理器
participant Job as 后台作业管理器
Publisher->>Manager : 获取订阅信息
Manager-->>Publisher : 返回订阅列表
Publisher->>Store : 持久化事件数据
Store-->>Publisher : 返回事件ID
Publisher->>Job : 队列化发送任务
Job-->>Publisher : 确认入队
图示来源
- DefaultWebhookPublisher.cs
本节来源
- DefaultWebhookPublisher.cs
事件发布步骤
- 调用
IWebhookPublisher.PublishAsync方法发布事件 WebhookSubscriptionManager根据租户ID和Webhook名称获取所有有效订阅WebhookEventStore将事件数据持久化到数据库- 为每个订阅创建
WebhookSenderArgs参数对象 - 通过
IBackgroundJobManager将发送任务加入后台作业队列
事件序列化与传输
序列化格式
事件数据使用JSON格式进行序列化,通过Newtonsoft.Json.JsonConvert.SerializeObject方法将任意对象转换为JSON字符串。
[SPEC SYMBOL](file://aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks/LINGYUN/Abp/Webhooks/DefaultWebhookPublisher.cs#L123-L140)
传输协议
使用HTTP POST请求传输事件,请求包含以下要素:
- URL: 订阅者配置的Webhook端点
- Method: POST
- Content-Type: application/json
- Body: JSON格式的事件数据
- Headers: 包含认证和其他元数据的HTTP头
异步处理与队列管理
后台作业处理流程
flowchart TD
A[事件发布] --> B{获取订阅}
B --> C[持久化事件]
C --> D[创建发送任务]
D --> E[加入后台作业队列]
E --> F[Hangfire执行]
F --> G[发送HTTP请求]
G --> H{成功?}
H --> |是| I[记录成功]
H --> |否| J[记录失败]
J --> K[触发重试机制]
图示来源
- DefaultWebhookPublisher.cs
- DefaultWebhookSender.cs
本节来源
- DefaultWebhookPublisher.cs
- DefaultWebhookSender.cs
队列管理机制
系统使用ABP框架的后台作业系统(基于Hangfire)管理事件发送队列。每个发送任务被封装为WebhookSenderArgs对象并加入队列。
失败重试策略
发送尝试存储
IWebhookSendAttemptStore接口和WebhookSendAttemptStore实现类负责管理发送尝试记录。
classDiagram
class IWebhookSendAttemptStore {
<<interface>>
+GetAllSendAttemptsBySubscriptionAsPagedListAsync()
+GetAllSendAttemptsByWebhookEventIdAsync()
+GetAsync()
+GetSendAttemptCountAsync()
+HasXConsecutiveFailAsync()
}
class WebhookSendAttemptStore {
-IWebhookSendRecordRepository repository
-IObjectMapper mapper
+GetAllSendAttemptsBySubscriptionAsPagedListAsync()
+GetAllSendAttemptsByWebhookEventIdAsync()
+GetAsync()
+GetSendAttemptCountAsync()
+HasXConsecutiveFailAsync()
}
IWebhookSendAttemptStore <|.. WebhookSendAttemptStore
图示来源
- WebhookSendAttemptStore.cs
本节来源
- WebhookSendAttemptStore.cs
重试逻辑
当发送失败时,系统会:
- 记录失败的发送尝试,包括状态码和响应内容
- 根据配置的重试策略决定是否重试
- 如果需要重试,将任务重新加入队列
- 支持连续失败检测,避免对持续不可用的端点无限重试
ABP事件总线集成
分布式事件总线发布器
DistributedEventBusWebhookPublisher实现了通过ABP分布式事件总线发布Webhook的功能。
classDiagram
class IDistributedEventBus {
<<interface>>
+PublishAsync<TEvent>(TEvent eventData)
}
class DistributedEventBusWebhookPublisher {
-IDistributedEventBus eventBus
+PublishAsync(string webhookName, object data)
+PublishAsync(string webhookName, object data, Guid? tenantId)
+PublishAsync(Guid?[] tenantIds, string webhookName, object data)
}
class WebhooksEventData {
+Guid?[] TenantIds
+string WebhookName
+string Data
+bool SendExactSameData
+WebhookHeader Headers
}
IDistributedEventBus <|-- DistributedEventBusWebhookPublisher
DistributedEventBusWebhookPublisher --> WebhooksEventData : "创建"
DistributedEventBusWebhookPublisher --> IDistributedEventBus : "发布"
图示来源
- DistributedEventBusWebhookPublisher.cs
- WebhooksEventData.cs
本节来源
- DistributedEventBusWebhookPublisher.cs
- WebhooksEventData.cs
事件处理器
WebhooksEventHandler监听分布式事件总线上的Webhook事件并进行处理。
classDiagram
class IDistributedEventHandler~TEvent~ {
<<interface>>
+HandleEventAsync(TEvent eventData)
}
class WebhooksEventHandler {
+IWebhookEventStore WebhookEventStore
-ICurrentTenant currentTenant
-IBackgroundJobManager backgroundJobManager
-IWebhookSubscriptionManager subscriptionManager
+HandleEventAsync(WebhooksEventData eventData)
}
IDistributedEventHandler~WebhooksEventData~ <|.. WebhooksEventHandler
图示来源
- WebhooksEventHandler.cs
本节来源
- WebhooksEventHandler.cs
可靠性与顺序性保证
可靠性机制
- 持久化存储: 所有事件在发布前都会被持久化到数据库
- 事务管理: 使用
[UnitOfWork]特性确保数据一致性 - 错误处理: 完善的异常捕获和日志记录机制
- 状态跟踪: 记录每个发送尝试的详细信息
顺序性保证
虽然系统主要设计为异步处理,但在特定场景下可以通过以下方式保证顺序性:
- 对于同一租户的同一类型事件,可以使用有序队列
- 在订阅端实现幂等性处理,避免重复事件的影响
- 使用事件版本号或时间戳来识别事件顺序
数据模型关系
erDiagram
WEBHOOK_EVENT {
guid Id PK
guid? TenantId FK
string WebhookName
string Data
datetime CreationTime
boolean IsDeleted
}
WEBHOOK_SUBSCRIPTION {
guid Id PK
guid? TenantId FK
string WebhookUri
string Secret
boolean IsActive
int TimeoutDuration
}
WEBHOOK_SEND_ATTEMPT {
guid Id PK
guid WebhookEventId FK
guid WebhookSubscriptionId FK
guid? TenantId FK
datetime CreationTime
int? ResponseStatusCode
string ResponseContent
string RequestHeaders
string ResponseHeaders
}
WEBHOOK_EVENT ||--o{ WEBHOOK_SEND_ATTEMPT : "1:N"
WEBHOOK_SUBSCRIPTION ||--o{ WEBHOOK_SEND_ATTEMPT : "1:N"
图示来源
- WebhookEventRecord.cs
- WebhookSendAttemptStore.cs
本节来源
- WebhookEventRecord.cs
- WebhookSendAttemptStore.cs