芯片|复杂任务中,流程的解耦设计( 二 )



事件和异步在模式上很类似 , 事件驱动在设计上更加精细 , 例如在订单场景中:将订单的状态变化作为一个事件 , 服务间通过消息传递的方式 , 依次处理库存服务、物流服务等;由于事件携带了一定的业务信息和状态 , 流程解耦更加彻底的同时复杂度也会更高 。
四、实践总结1、结构设计在结构设计中围绕任务、节点、数据三个核心要素 , 以确保对任务的执行过程有完整的跟踪和管理 , 实现对任务的节点及相关的操作 , 具备执行重试或者直接取消撤回的控制;

状态管理是一项很复杂的工作 , 要衡量任务中各个状态标识是否合理 , 就要实时监控状态的变化 , 并且基于各种极端情况去验证流程 , 例如:重试设计、任务取消、任务暂停 。
2、高并发管理任务型的场景加上复杂的管理流程 , 执行时间自然也很长 , 如果场景中涉及到大文件的解析、或者数据调度 , 自然会引入任务分割与并发执行的机制;
比较常用的思路:根据任务调度的集群数 , 对数据核心编号进行哈希计算 , 可以采用取模和分段两种算法 , 然后基于多线程的方式并发处理各自服务内的分管任务 。
3、管理模型不管是观察者模式 , 或者发布订阅模型 , 又或者说事件驱动设计 , 都可以理解为生产/消费的关系模型 , 围绕生产、存储、消费三个节点做管理;

  • 生产端:负责创建具体的消息主体 , 在总线模式中 , 通常将消息进行入库存储 , 然后再执行队列推送 , 并跟踪该过程的状态变化 , 保证库和队列的一致性;
  • 消息体:描述动作的发布方和消费方 , 关键的状态信息变化 , 唯一标识和创建时间及版本 , 其余则根据场景需要定义即可;
  • 消费端:在消费时要关注的核心问题就是失败重试 , 要避免重试机制引起数据不一致的问题 , 可以对消费进行加锁或者消息状态校验 , 以实现幂等的效果;
  • 存储端:通常采用数据库和消息中间件双存储的模式 , 并且需要保证二者动作的同时成功或者失败 , 顺序为先入库再执行队列推送;
整个模型在设计思路上比较合理 , 但是架构的复杂性也变得很高 , 比如数据一致性问题、状态机制、事务、幂等性、流程中断等;整个链路需要详细的追踪记录并且可视化管理 , 开发补偿动作的接口 , 用来及时解决可能出现的突发问题 。
4、组件案例Spring框架本身就极具复杂度 , 这里单看事件模型的设计 , 包含三个核心角色:事件、发布、监听;与观察者设计模式在理念上相同;

事件:ApplicationEvent基础抽象类继承自JDK中EventObject类 , 具体事件要继承该类;source事件源 , timestamp发生的系统时间;
发布者:Spring定义的顶级接口ApplicationEventPublisher , 提供事件发布的能力;
监听者:实现JDK中顶级接口EventListener , Spring扩展了多种事件监听器 , 以实现各种场景的需求 , 例如:有序无序、同步异步等;