这是基于vue-vben-admin 模板适用于abp vNext的前端管理项目
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

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)

目录

  1. 简介
  2. 核心组件
  3. 事件发布流程
  4. 事件序列化与传输
  5. 异步处理与队列管理
  6. 失败重试策略
  7. ABP事件总线集成
  8. 可靠性与顺序性保证

简介

本项目实现了基于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

事件发布步骤

  1. 调用IWebhookPublisher.PublishAsync方法发布事件
  2. WebhookSubscriptionManager根据租户ID和Webhook名称获取所有有效订阅
  3. WebhookEventStore将事件数据持久化到数据库
  4. 为每个订阅创建WebhookSenderArgs参数对象
  5. 通过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

重试逻辑

当发送失败时,系统会:

  1. 记录失败的发送尝试,包括状态码和响应内容
  2. 根据配置的重试策略决定是否重试
  3. 如果需要重试,将任务重新加入队列
  4. 支持连续失败检测,避免对持续不可用的端点无限重试

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

可靠性与顺序性保证

可靠性机制

  1. 持久化存储: 所有事件在发布前都会被持久化到数据库
  2. 事务管理: 使用[UnitOfWork]特性确保数据一致性
  3. 错误处理: 完善的异常捕获和日志记录机制
  4. 状态跟踪: 记录每个发送尝试的详细信息

顺序性保证

虽然系统主要设计为异步处理,但在特定场景下可以通过以下方式保证顺序性:

  1. 对于同一租户的同一类型事件,可以使用有序队列
  2. 在订阅端实现幂等性处理,避免重复事件的影响
  3. 使用事件版本号或时间戳来识别事件顺序

数据模型关系

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