Orleans 流系统握手机制时序图

时序图说明

以下时序图展示了 Orleans 流系统中握手机制的完整流程,包括正常情况和异常情况的处理。

1. 正常握手流程

流代理(PullingAgent) 消费者(Consumer) 缓存(QueueCache) 存储(Storage) GetSequenceToken(subscriptionId) 查询上次处理位置 返回 lastProcessedToken 返回 StreamHandshakeToken GetCacheCursor(streamId, token) 返回 Cursor Cursor.MoveNext() (移动到下一个未处理消息) 保存 LastToken = requestedHandshakeToken 握手成功,开始消息投递 流代理(PullingAgent) 消费者(Consumer) 缓存(QueueCache) 存储(Storage)

2. 新订阅握手流程

流代理(PullingAgent) 新消费者(NewConsumer) 缓存(QueueCache) GetSequenceToken(subscriptionId) 返回 null (新订阅,无历史状态) GetCacheCursor(streamId, cacheToken) 返回 Cursor (从缓存位置开始) 保存 LastToken = null 握手成功,从缓存位置开始投递 流代理(PullingAgent) 新消费者(NewConsumer) 缓存(QueueCache)

3. 异常处理流程

流代理(PullingAgent) 消费者(Consumer) 错误协议(ErrorProtocol) GetSequenceToken(subscriptionId) 抛出异常 (网络问题/消费者不可用) 检查 IsShutdown return false (停止处理) ErrorProtocol(consumerData, exception) 记录错误,决定是否标记为故障 返回 faultedSubscription 状态 return false (停止处理该消费者) GetCacheCursor(streamId, cacheToken) (备用方案) 握手完成,使用备用位置 alt 订阅被标记为故障 订阅正常 alt 代理正在关闭 代理正常运行 流代理(PullingAgent) 消费者(Consumer) 错误协议(ErrorProtocol)

4. 重试机制流程

流代理(PullingAgent) 消费者(Consumer) 重试执行器(RetryExecutor) ExecuteWithRetries(GetSequenceToken, INFINITE_RETRIES) GetSequenceToken(subscriptionId) 返回 StreamHandshakeToken 返回结果 抛出异常 检查重试条件 等待退避时间 GetSequenceToken(subscriptionId) (重试) 抛出异常 alt 满足重试条件 不满足重试条件 alt 成功 失败 流代理(PullingAgent) 消费者(Consumer) 重试执行器(RetryExecutor)

5. 消息投递流程

流代理(PullingAgent) 消费者(Consumer) 缓存(QueueCache) Cursor.GetCurrent() (获取当前消息) 返回 StreamMessage DeliverMessage(message, sequenceToken) 处理消息 返回处理结果 Cursor.MoveNext() (移动到下一个消息) 返回是否还有更多消息 继续投递下一条消息 等待新消息或定期握手 alt 还有更多消息 没有更多消息 流代理(PullingAgent) 消费者(Consumer) 缓存(QueueCache)

6. 故障恢复流程

流代理(PullingAgent) 重启消费者(RestartedConsumer) 存储(Storage) 恢复上次处理状态 返回 lastProcessedToken GetSequenceToken(subscriptionId) 返回恢复的 StreamHandshakeToken GetCacheCursor(streamId, recoveredToken) Cursor.MoveNext() (从恢复位置的下一个开始) 保存恢复状态 握手成功,从恢复位置继续投递 流代理(PullingAgent) 重启消费者(RestartedConsumer) 存储(Storage)

7. 状态同步流程

流代理(PullingAgent) 消费者(Consumer) 存储(Storage) 处理消息完成 更新 lastProcessedToken 确认状态已保存 定期握手检查 GetSequenceToken(subscriptionId) 返回当前状态 比较当前状态与 LastToken 继续正常投递 调整投递位置 从新位置开始投递 alt 状态一致 状态不一致 流代理(PullingAgent) 消费者(Consumer) 存储(Storage)

8. 关键设计决策说明

8.1 为什么使用无限重试?

  • 可靠性优先:握手失败意味着消息投递失败
  • 网络不稳定:分布式环境中网络问题很常见
  • 消费者重启:消费者可能暂时不可用

8.2 为什么需要 MoveNext()?

  • 避免重复:令牌指向已处理的消息
  • 连续性保证:确保从下一个未处理消息开始
  • 状态一致性:保持消费者和代理状态同步

8.3 为什么需要备用方案?

  • 容错性:握手失败时系统仍能工作
  • 降级策略:从已知安全位置开始
  • 系统可用性:避免因握手失败导致整个系统停止

8.4 为什么保存 LastToken?

  • 下次握手参考:为下次握手提供基准
  • 状态追踪:监控消费者状态变化
  • 性能优化:减少重复的状态查询

9. 性能优化点

  1. 异步处理:所有操作都是异步的,避免阻塞
  2. 状态缓存:缓存常用状态信息,减少存储访问
  3. 批量操作:支持批量消息投递
  4. 智能重试:使用退避算法避免过度重试
  5. 资源管理:及时释放不需要的资源

10. 监控指标

  • 握手成功率:成功握手次数 / 总握手次数
  • 握手延迟:从开始握手到完成的时间
  • 重试次数:平均重试次数
  • 错误率:握手失败的比例
  • 消息投递延迟:从握手完成到开始投递的时间

这个握手机制确保了 Orleans 流系统在复杂的分布式环境中能够可靠、高效地处理消息投递。

相关推荐
码事漫谈21 分钟前
勿删
后端
IT_陈寒4 小时前
用了Proxy才发现以前的JavaScript白写了
前端·人工智能·后端
唐青枫5 小时前
别把 ArrayList 当成会自动管理内存的 List:Zig 动态数组从入门到实战
后端
鸿蒙开发5 小时前
我为 HarmonyOS 做了一个统一大模型 SDK:@hmkit/ai 正式开源
后端
猪是念来过倒5 小时前
Semaphore 与 RateLimiter:并发控制双雄详解
后端
掘金者阿豪5 小时前
异构数据同步最怕什么?不是同步慢,而是数据对不上
后端
程序员cxuan6 小时前
Claude 官方的学习教程,太强了。
人工智能·后端·程序员
老孙讲技术6 小时前
把工地遮挡和掉线接进项目部:setMessageCallback 订 alarm 与 deviceStatus
后端·物联网·音视频开发
老孙讲技术6 小时前
关店后有人进门,监控值班群却没响:用 setMessageCallback 订 human,再用 aiHuman 打开人形
后端·物联网·音视频开发
LEE6 小时前
原来 Claude Code 最厉害的工具,一行代码都不写
前端·后端