| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 大数据 -> 架构范式一 - 事件驱动架构(EDA) -> 正文阅读 |
|
[大数据]架构范式一 - 事件驱动架构(EDA) |
一、什么是EDA架构?EDA 是一种基于发布/订阅模式的消息异步通信的架构,你可以把它理解为架构层面的观察者模式。它主要分为以下7个核心对象,具体的协同模式可以参考以下原理图。
大致流程为:
二、适用场景第一,因为它是异步的,因此特别适合以下:
第二,如果业务模式的整个主流程不强调强一致性且流程变化很快的,则可以适当的考虑这种架构。 第三、因为它是通过管道进行异步通信,如果你的系统是那些对交易实时性要求较高的或者是跟2C端页面交互强关联的,则不太建议使用该异步架构; 三、优势第一、在这种模式下,系统一般被分解成多个独立又互相有一定关联关系的服务或模块,这种模式真正体现高内聚低耦合,很好的体现Y轴扩展。笔者曾经负责过的一个票据处理系统就是这种EDA架构,每个worker只负责一个工序(满足高内聚),当需要新增额外工序的时候只需要继承基类新增新类型的worker,并配套新rule即可。眨眼看上去是不是责任链模式在系统架构中的体现?(题外话:扩展性理论可以参考《The Art of Scalability》里面的AKF?scale cube模型); 第二,高内聚带来的好处就是,每当新增功能时大概率只需要改动某个节点的worker,改动的影响可以被限定在一定范围内(即某个worker内部); 第三,worker理论上可以无限水平扩展以便支持大规模的业务量;当manger变成瓶颈后,也可以适当把manager从单实例扩展成集群; 第四、基于事件(event)实际上持久化到Event bus ,因此便于做差错处理,提升了系统整体的可运维性。例如,event1在manager2处理失败后即不会继续往后处理,方便IT人员排查并修复后把该event重新路由至同一个manager下进行处理。 四、幂等性既然使用到EDA这种事件触发型的架构模式,势必会面临一个以下常见的场景:
因此,幂等性设计在这种架构下就显得尤为必要。所有的所有的业务流程或操作在数据库视野上归根结底就是事物状态的变更和查询两大类。如果是查询类的操作,那幂不幂等这个无关重要。如果是变更类的操作,那就需要考虑幂等的设计。一般来说,幂等性可以通过token、状态码、乐观锁等方式实现。 其实这个幂等性在接口层面很是关键,笔者所负责的一些系统都出现了好些幂等性设计不足导致一些生产故障。这里我就按照之前的经验总结一些如何解决这个问题,有些是从同事的代码看到的,有些是自己之前的一些经验,虽然大体跟网上搜到的都是大致一样。
上面讲的这几种方式其实都是有个共通点,通过给某个业务请求生成或赋予一个唯一对应的令牌(如token,或乐观锁的#version),然后服务端针对业务接口的调用进行令牌校验,如果不能满足规则则拒绝处理。当然,上面的每种方法也有其局限性,因此在用于生产的设计方案中一般都是以上两种或多种方法的组合体。最关键的是,具体每个方案怎么组合或者组合到哪种程度是要与实际业务场景相结合的,总不能为了所谓的技术追求而犯了教条主义的错。 五、最终一致性EDA架构是通过实现可靠事件模式来达成业务层的最终一致性的。什么是可靠事件模式?可靠事件其实就是保证事件(event)能够被成功投递、接收及处理,简直TCP链接的增强版。其中可靠性通过以下三个维度进行可靠性保证。Talk is cheap,?show u the pic。 1、投递可靠性 首先,EDA架构下的消息巴士一般采用各种消息中间件作为消息传递的桥梁,而主流的开源消息中间件(例如RabbitMQ/RocketMQ/Kafka)使用的都是At least Once的投递机制(即每个消息必须投递至少一次),简单点说就是消息发送者(这里指“事件巴士”)发送消息至消息接受者(这里指“下游”)并且要监听响应,如果在规定指定时间内没有收到,则消息发送者会按某种频次重新发送该消息直到收到响应为止。 当然,如果是“上游”投递至“事件巴士”也需要从上游的应用层面做可靠性的容错处理。有兴趣的同学可以看一下Kafka的ACK机制。 2、传输可靠性 因为架构中使用消息中间件,目前大部分中间件都有对应的消息持久化机制,保证数据在没有被下游成功确认收到前不会丢失,哪怕是中间件本身宕机重启。当然,这个功能因中间件而异,部分中间件是放开给客户端控制的。 当然,中间件本身也有相应的数据容错策略。举个例子,Kafaka通过分区复制的策略保证数据不丢失。具体大致逻辑是由生产者(producer)首先找到领导者(leader)(这里的leader是Broker1上的Partition0)并把消息写到leader分区,然后leader分区会通过内部管道把消息复制到其它broker上的分区,这就是所谓的分区复制,这里附上原理图方便大家理解。 3、处理可靠性 我的理解,这里的处理可靠性更多指的是应用层的消息路由逻辑。就是说,当一个事件(event)被一个节点(worker)处理完后,会按照路由策略表严格指定该事件(event)的下一个节点(worker)是谁。我认为它的可靠性是相对平时的代码接口调用或者过程式代码的这种风格而言的,这也正是它的可靠性所在。
六、监控EDA的这种架构还有一个突出的特点,就是因为每个节点都是解耦的,所以哪个节点都不清楚进来的每一个event当前的状态是怎样的,究竟是已经处理完毕呢还是被丢到死信主题呢。这就好像流水线上的工人,个人只会完成自己的工序并再放回到流水线上。 当然,我们可以通过定义每个节点的worker的异常处理逻辑(即发生异常时指定错误码并顺带进行告警),但是这种方法有两个弊端:
因此,需要定义单独的monitor对这种异常进行监控并告警。如上图,MonitorManager和worker的协同方式一般可以有以下几种方式。
七、后话今天差不多,后面可以讲一下另外一个跟事件驱动架构相关或者有关联的事件溯源架构。 |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/23 13:36:59- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |