软件布局划设想计学习计算(22):软件构造——分层布局、事件驱动布局、微内核布局、微服务布局、基于空间的构造

分层架构 (Layered Architecture)

分层架构是最常见的架构,也被称为n层架构。多年以来,许多企业和公司都在他们的项目中使用这种架构,它已经几乎成为事实标准,因此被大多数架构师、开发者和软件设计者所熟知。比如MVC。

分层架构的一个特性就是 关注分离(separation of
concerns) 。在层中的组件只负责本层的逻辑。组件的划分很容易让它们实现自己的角色和职责,也比较容易地开发,测试管理和维护。

我们需要这样的冗余,即使业务层没有处理业务规则,也要通过业务层来调用数据层,这叫 分层隔离 。对于某些功能,如果我们从表现层直接访问数据层,那么数据层后续的任何变动都将影响到业务层和表现层。

注意分层的 开闭原则 。如果某层是关闭的,那么每个请求都要经过着一层。相反,如果该层是开放的,那么请求可以绕过这一层,直接到下一层。

分层隔离有利于降低整个应用程序的复杂度。某些功能并不需要经过每一层,这时我们需要根据开闭原则来简化实现。

美高梅官方网站 1

本文是我在阅读O’Reilly免费的电子书 Software Architecture
Patterns过程中做的笔记。

污水池反模式(architecture sinkhole anti-pattern)

分层架构是 SOLID原则 的通用架构,当我们不确定哪种架构更合适的时候,分层架构将是一个很好的起点。我们需要注意防止架构陷入 污水池反模式(architecture
sinkhole anti-pattern) 。

在这个模式中,请求流只是简单的
穿过层次,不留一点云彩,或者说只留下一阵⻘青烟。比如说界面层响应了一个获得数据的请求。响应层把这
个请求传递给了业务层,业务层也只是传递了这个请求到持久层,持久层对数据库做简单的SQL查询获得用户的数据。这个数据按照原理返回,不会有任何的二次处理,返回到界面上。

每个分层架构或多或少都可能遇到这种场景。关键在于这样的请求有多少。80-20原则可以帮助你确定架构是
否处于反污水模式。大概有百分之二十的请求仅仅是做简单的穿越,百分之八十的请求会做一些业务逻辑操
作。然而,如果这个比例反过来,大部分的请求都是仅仅穿过层,不做逻辑操作。那么开放一些架构层会比较好。不过由于缺少了层次隔离,项目会变得难以控制。

首先这本书非常新,2015年3月30号订正后发布。其次将目前流行的几种架构详细进行了剖析和比较,除了传统的N层架构外,其它架构相当的前沿。并且,这篇小书连带封面才55页,短小精悍,值得一读。这本书的作者是
Mark
Richards,有30多年行业经验,19年软件集成,企业级架构的经验,大部分是Java平台,也出版了多本书和论文。

巨石应用(Monolith)

分层架构可以演变为 巨石应用(Monolith) ,导致代码库难以维护。

将所有功能都部署在一个web容器中运行的系统就叫做巨石型应用。巨石型应用有很多好处:IDE都是为开发单个应用设计的、容易测试——在本地就可以启动完整的系统、容易部署——直接打包为一个完整的包,拷贝到web容器的某个目录下即可运行。

美高梅官方网站 2

但是,上述的好处是有条件的:应用不那么复杂。对于大规模的复杂应用,巨石型应用会显得特别笨重:

  • 要修改一个地方就要将整个应用全部部署(PS:在不同的场景下优势也变成了劣势);

  • 编译时间过长;回归测试周期过长;

  • 开发效率降低等。

  • 巨石应用不利于更新技术框架,除非你愿意将系统全部重写(代价太高你愿意老板也不愿意)。

如果你没有时间去阅读这本书,那么不妨看一下本篇文章。
我在笔记中将书中的主要知识点都记录下来。

架构举例

我们看一下淘宝前几年的架构的例子:

美高梅官方网站 3

这是一个标准的分层的架构。每一层中又可以详细的分成更细的层,比如服务层。

美高梅官方网站 4

围着着这个主架构还有一些外围的产品。比如监控和审计。

不先进行正式的架构设计就直接开发对于程序员来说再普通不过了。没有清晰和很好的架构设计,大部分程序员和架构师实际上会采用传统的分层的架构模式,
自然地将代码模块分隔成几个包(package)。不幸地是,这种做法经常导致未能好好组织代码模块,这些模块缺乏清晰的角色,责任以及相互关系。这经常被成为大泥球反模式。

Tips:

  • 不同的阶段,不同的业务场景,不同的业务复杂度,不同的团队,适合不同的分层。

  • 有些分层是兼容低端情况(初创公司用起来也很美,还兼顾以后的发展和迭代),有些不兼容(团队层次达不到,玩不转)。

  • 分层将导致复杂度的上升。(博弈)

  • 注意接口和边界。(不然白分)

没有进行架构设计的应用程序通常是紧耦合的,玻璃心,难以改变,没有头绪。如果不理解应用的各个组件的内部工作方式的话很难看清它的架构特征。关于部署和维护的问题都很难回答:架构的规模如何?程序的性能如何?程序容易修改吗?程序的部署模型是怎么样?程序的响应如何?

事件驱动架构 (Event-Driven Architecture)

事件驱动架构(Event Driven
Architecture)是一种流行的分布式异步架构模式,用于创建可伸缩的应用程序。这种模式是自适应的,可用于小规模或者大规模的应用程序。它由高度解耦的,单一目的的事件处理组件组成,可以异步地接收和处理事件。

它包括两个主要的拓扑结构: 调停者拓扑(Mediator
Topology) 和 代理者拓扑(Broker
Topology) 。Mediator拓扑结构需要你在一个事件通过mediator时精心安排好几个步骤,而broker拓扑结构无需mediator,而是由你串联起几个事件。这两种拓扑架构的特征和实现有很大的不同,所以你需要知道哪一个适合你。

架构模式可以帮助你定义程序的基本特征和行为。例如一些架构模式很自然让程序成为大规模(scalable)的程序。有些模式让程序变得灵巧敏捷(agile)。知道这些架构的特征,优点和缺点,你就可以根据你特定的业务需求和目标从容的选择一种架构模式。

调停者拓扑(Mediator Topology)

Mediator拓扑结构适合有多个步骤的事件,需要安排处理层次。

例如购买一只股票,首先会校验这个交易,校验股票交易是否符合各种规定,将它交给一个经纪人,计算佣金,最后确认交易。所有这些都安排好各个步骤的顺序,决定它们是否串行还是并行。

通常,架构主要包含4种组件,事件队列(Event
Queue)、调停者(Mediator)、事件通道(Event
Channel)和事件处理器(Event
Processor)。客户端创建事件,并将其发送到事件队列,调停者接收事件并将其传递给事件通道。事件通道将事件传递给事件处理器,事件最终由事件处理器处理完成。

美高梅官方网站 5

事件流是这样开始的: 客户端发送一个事件到事件队列(event
queues)中,它用来将事件传送给event mediator。Event
mediator收到初始的事件后,会发送额外的一些异步事件给event
channels来执行处理的每个步骤。Event processors监听event
channels,接收事件并处理一些业务逻辑。

事件调停者不会处理也不知道任何业务逻辑,它只编排事件。事件调停者知道每种事件类型的必要步骤。业务逻辑或者处理发生在事件处理器中,事件通道、消息队列或者消息主题用于传递事件给事件处理器。事件处理器是自包含和独立的,解耦于架构。理想情况下,每种事件处理器应只负责处理一种事件类型。

这里有两种事件:初始事件和处理事件。Mediator会将初始事件编排成处理事件。它没有具体的业务逻辑,只是一个协调者,负责将初始事件转化成一个或者多个处理事件。

在事件驱动架构中有十几个甚至几百个事件队列都很正常。模式本身没有限定事件队列的实现方式。它可能是一个消息队列,一个web
service或者其它。

event channels
既可以是消息队列,也可以是消息topic,大部分是消息topic,这样可以由多个消息处理器(event
processor)处理同一个消息。

消息处理器包含实际的业务逻辑。每个消息处理器都是自包含的,独立的,高度解耦的,执行单一的任务。这种模式可能有一些变种。作为架构师,你应该理解每个实现的细节,确保这种解决方案适合你的需求。有一些开源的框架实现了这种架构,如Spring
Integration, Apache Camel, 或者 Mule ESB。

作为一位架构师,你总会为自己架构选择做解释,尤其你选择一个特别的架构模式的时候。O’Reilly的这本书提供了充足的信息来为你的架构选择提供证明。

代理者拓扑(Broker Topology)

喜欢 | 作者 韩陆 发布于 2016年3月30日. 估计阅读时间: 不到一分钟 |
道AI风控、Serverless架构、EB级存储引擎,尽在ArchSummit! 4 讨论

分享到: 微博 微信 Facebook Twitter 有道云笔记 邮件分享

稍后阅读我的阅读清单

【编者的话】本文来自Firat
Atagun的《架构演化中的软件设计原则》,文中给出了软件架构演化过程中出现的4种经典架构,就每种架构,分析了其主要特点并在几个度量维度给出结论。在文章的最后,Firat
Atagun给出了4种架构的多维对比。本文的完整演讲稿是架构演化中的软件设计原则。

1 分层架构

分层架构是最常见的架构,也被称为n层架构。多年以来,许多企业和公司都在他们的项目中使用这种架构,它已经几乎成为事实标准,因此被大多数架构师、开发者和软件设计者所熟知。

分层架构中的层次和组件是水平方向的分层,每层扮演应用程序中特定的角色。根据需求和软件复杂度,我们可以设计N层,但大多数应用程序使用3-4层。有太多层的设计会很糟糕,将导致复杂度的上升,因为我们必须维护每一层。在传统的分层架构中,分层包括表现层、业务或者服务层,以及数据访问层。
表现层负责应用程序的用户交互和用户体验(外观和视觉)。通常我们会使用数据传输对象(Data
Transfer Object)将数据带到这一层,然后使用视图模型(View
Model)渲染到客户端。业务层接收请求并执行业务规则。数据访问层负责操作各种类型的数据库,每个访问数据库的请求都要经过这一层。

分层无需知道其他层如何去做,比如业务层无需知道数据访问层是如何查询数据库的,相反,业务层在调用数据层的特定方法时,只需关注需要部分数据还是全部数据。这就是我们所说的关注点分离。这是非常强大的功能,每层负责其所负的责任。

分层架构中的核心概念是管理依赖。如果我们使用依赖倒置原则和测试驱动开发(Test
Driven
Development),我们的架构会有更好的健壮性。因为,我们要保证所有可能的用例都有测试用例。

我们需要这样的冗余,即使业务层没有处理业务规则,也要通过业务层来调用数据层,这叫分层隔离。对于某些功能,如果我们从表现层直接访问数据层,那么数据层后续的任何变动都将影响到业务层和表现层。

相关厂商内容

微信Android模块化架构重构实践 蘑菇街分布式消息中间件Corgi的架构演进
Serverless架构:一条SQL到一个服务有多远?
对抗复杂性,架构设计中可借鉴复用这些手段
阿里:风控场景的模型平台架构设计

相关赞助商

ArchSummit深圳2017,7月7-8日,深圳·华侨城洲际酒店,精彩内容抢先看

分层架构中的一个重要的概念就是分层的开闭原则。如果某层是关闭的,那么每个请求都要经过着一层。相反,如果该层是开放的,那么请求可以绕过这一层,直接到下一层。

分层隔离有利于降低整个应用程序的复杂度。某些功能并不需要经过每一层,这时我们需要根据开闭原则来简化实现。

分层架构是SOLID原则的通用架构,当我们不确定哪种架构更合适的时候,分层架构将是一个很好的起点。我们需要注意防止架构陷入污水池反模式。这种反模式描述了请求经过分层,但没做任何事或者只处理了很少的事。如果我们的请求经过所有分层而没有做任何事,这就是污水池反模式的征兆。如果20%的请求只是经过各层,而80%的请求实际做事,这还好,如果这个比率不是这样的,那么我们已经患上反模式综合征。

此外,分层架构可以演变为巨石应用(Monolith),导致代码库难以维护。

分层架构分析:

敏捷性:总体敏捷性是指对不断变化的环境作出反应的能力。由于其整体风格(Monolith)的性质,可能会变得难以应对通过所有层的变化,开发者需要注意依赖性和分层分离。

易于部署:大型应用程序的部署会是个麻烦。一个小要求,可能需要部署整个应用程序。如果能做好持续交付,可能会有所帮助。

可测试性:使用Mocking和Faking,每一层可以独立测试,因此测试上很容易。

性能:虽然分层应用程序可能表现良好,但是因为请求需要经过多个分层,可能会存在性能问题。

可伸缩性:因为耦合太紧以及整体风格(Monolith)的天生特质,很难对分层应用程序进行伸缩。然而,如果分层能够被构建为独立的部署,还是可以具备伸缩能力的。但是,这样做的代价可能很昂贵。

易于开发:这种模式特别易于开发。许多企业采用这种模式。大多数开发者也都知道、了解,并且可以轻松学习如何使用它。

2 事件驱动架构

事件驱动架构(Event Driven
Architecture)是一种流行的分布式异步架构模式,用于创建可伸缩的应用程序。这种模式是自适应的,可用于小规模或者大规模的应用程序。事件驱动架构可以与调停者拓扑(Mediator
Topology)或者代理者拓扑(Broker
Topology)一起使用。理解拓扑的差异,为应用程序选择正确的拓扑是必不可少的。

调停者拓扑

调停者拓扑需要编排多种事件。比如在交易系统中,每个请求流程必须经过特定的步骤,如验证、订单、配送,以及通知买家等。在这些步骤中,有些可以手动完成,有些可以并行完成。

通常,架构主要包含4种组件,事件队列(Event
Queue)、调停者(Mediator)、事件通道(Event
Channel)和事件处理器(Event
Processor)。客户端创建事件,并将其发送到事件队列,调停者接收事件并将其传递给事件通道。事件通道将事件传递给事件处理器,事件最终由事件处理器处理完成。

事件调停者不会处理也不知道任何业务逻辑,它只编排事件。事件调停者知道每种事件类型的必要步骤。业务逻辑或者处理发生在事件处理器中,事件通道、消息队列或者消息主题用于传递事件给事件处理器。事件处理器是自包含和独立的,解耦于架构。理想情况下,每种事件处理器应只负责处理一种事件类型。

通常,企业服务总线、队列或者集线器可以用作事件调停者。正确选择技术和实现能够降低风险。

代理者拓扑

不像调停者拓扑,代理者拓扑不使用任何集中的编排,它没有中心的Mediator。而是在事件处理器之间使用简单的队列或者集线器,事件处理器知道处理事件的下一个事件处理器。所有的事件串联起来通过一个轻量级的消息broker如RabbitMQ,ActiveMQ,HornetQ等。如果你的消息比较简单,不需要重新编排,就可以使用这种结构。

美高梅官方网站 6

如图所示,它包含两个组件broker和 event processor。broker中的event
channel可以是消息队列,消息topic或者它们的复合形式。每个event
processor负责处理事件,发布新的事件。

分层架构 (Layered Architecture)

举例

美高梅官方网站 7

在新浪微博的早期架构中,微博发布使用同步推模式,用户发表微博后系统会立即将这条微博插入到数据库所有粉丝的订阅列表中,当用户量比较大时,特别是明星用户发布微博时,会引起大量的数据库写操作,超出数据库负载,系统性能急剧下降,用户响应延迟加剧。

后来新浪微博改用异步推拉结合的模式,用户发表微博后系统将微博写入消息队列后立即返回,用户响应迅速,消息队列消费者任务将微博推送给所有当前在线粉丝的订阅列表中,非在线用户登录后再根据关注列表拉取微博订阅列表。

它是最通用的架构,也被叫做N层架构模式(n-tier architecture
pattern)。这也是Java
EE应用经常采用的标准模式。基本上是个程序员都知道它。这种架构模式非常适合传统的IT通信和组织结构,很自然地成为大部分应用的第一架构选择。

Tips

因其分布式和异步的性质,事件驱动架构的实现相对复杂,主要是由于它的异步和分布式特性。我们需要面对很多问题,比如网络分区、调停者失败、重新连接逻辑等。由于这是一个分布式且异步的模式,如果你需要事务,那就麻烦了,你得需要一个事务协调器。分布式系统中的事务非常难以管理,很难找到标准的工作单位模式。

一个考虑是这种模式对于单一的逻辑缺乏原子事务。所以你需要将原子事务交给一个事件处理器执行,跨事件处理器的原子事务是很困难的。

最困难的设计之一是事件处理器的创建,维护和管理。事件通常有特殊的约定(数据值和格式)。

模式描述

微内核架构 (Microkernel Architecture)

微内核架构(Microkernel architecture)模式也被称为插件架构(plugin
architecture)模式。可以用来实现基于产品的应用,
比如Eclipse,在微内核的基础上添加一些插件,就可以提供不同的产品,如C++,
Java等。

微内核包含两个组件: core system 和 plug-in
modules。应用逻辑被分隔成核心系统和插件模块,可以提供可扩展的,灵活的,特性隔离的功能。

美高梅官方网站 8

这种模式非常适合桌面应用程序,但是也可以在Web应用程序中使用。事实上,许多不同的架构模式可以作为整个系统的一个插件。对于产品型应用程序来说,如果我们想将新特性和功能及时加入系统,微内核架构是一种不错的选择。

微内核的架构模式可以嵌入到其它的架构模式之中。微内核架构通过插件还可以提供逐步演化的功能和增量开发。所以如果你要开发基于产品的应用,微内核是不二选择。

在分层架构中的组件被划分成几个层,每个层代表应用的一个功能。分层架构本身没有规定要分成多少层,大部分的应用会分成表现层,业务层,持久层和数据库层。小的应用有时候会将业务层和持久层合在一起,更大规模的应用可能会划分更多的层,比如调用外部服务的层。

微服务架构(Microservices architecture)

尽管微服务的概念还相当新,但它确实已经快速地吸引了大量的眼球,以替代整体应用和面向服务架构(SOA)。其中的一个核心概念是具备高可伸缩性、易于部署和交付的独立部署单元(Separately
Deployable
Units)。最重要的概念是包含业务逻辑和处理流程的服务组件(Service
Component)

不管你使用何种实现风格和拓扑,有几个通用的核心概念应用在这种架构模式上。首先是分隔发布单元(separately
deployed units)。

美高梅官方网站 9

如图所示,每一个微内核的组件都被分隔成一个独立的单元。微服务包含 服务组件(service
component )。不要考虑微内核的单个服务,而是最好考虑服务组件,从粒度上讲它可以是单一的模块或者一个一个大的应用程序,代表单一功能(提供天气预报或者图片存储)。

正确设计服务组件的粒度是一个很大的挑战。

另一个关键概念是微内核是分布式的。这意味着服务组件可能是远程方法(通过JMS,
AMQP, REST, SOAP,
RMI……等等)。分布式意味着这种模式可以建立大规模的应用。

另一个值得兴奋的特性是它可以从其它有问题的架构模式中演化出来,而不是直接创建出来等待问题发生。当你遇到一些无法解决的问题,特别是互联网企业的规模扩大时,是很好的引入微服务架构的时机。

一般会从两个模式中演化:

  • 一种就是一开始就是整体的应用,所有的模块都是紧耦合的。

  • 另外一种是 面向服务的架构模式(SOA,service-oriented architecture
    pattern) 。

SOA不是不好,但是太昂贵了,不好理解和实现。

每一层都有特定的角色和职能。

应用拆分

美高梅官方网站 10

这张图从三个维度概括了一个系统的扩展过程:

  • x轴,水平复制,即在负载均衡服务器后增加多个web服务器;

  • z轴扩展,是对数据库的扩展,即分库分表(分库是将关系紧密的表放在一台数据库服务器上,分表是因为一张表的数据太多,需要将一张表的数据通过hash放在不同的数据库服务器上);

  • y轴扩展,是功能分解,将不同职能的模块分成不同的服务。

从y轴这个方向扩展,才能将巨型应用分解为一组不同的服务,例如订单管理中心、客户信息管理中心、商品管理中心等等。

美高梅官方网站 11

实现方式

有很多实现微服务的方式。最通用最流行的三个方式是:

  • API REST-based

  • applicaiton REST-based

  • 中心化的消息

API REST-based
适合网站提供小规模的,自包含的服务。很多互联网网站都提供这样的服务,比如OAuth2服务。

美高梅官方网站 12

application
REST-based不同于上面的架构,客户端看到的是web界面或者富客户端程序,而不是调用API。UI层独立发布,可以访问服务组件。

美高梅官方网站 13

中心消息模式,它类似前面的模式,但是使用一个轻量级的消息broker取代RESTful的服务调用。这个轻量级的broker不会执行服务的编排,传输和路由,这和SOA不同,不要把它看作SOA的简化版

美高梅官方网站 14

分层架构的一个特性就是关注分离(separation of
concerns)。在层中的组件只负责本层的逻辑。组件的划分很容易让它们实现自己的角色和职责,也比较容易地开发,测试管理和维护。

内部服务之间的通信

内部服务之间的通信方式有两种:基于HTTP协议的同步机制(REST、RPC);基于消息队列的异步消息处理机制(AMQP-based
message broker)。

Dubbo 是阿里巴巴开源的分布式服务框架,属于同步调用,当一个系统的服务太多时,需要一个注册中心来处理服务发现问题,例如使用ZooKeeper这类配置服务器进行服务的地址管理:服务的发布者要向ZooKeeper发送请求,将自己的服务地址和函数名称等信息记录在案;服务的调用者要知道服务的相关信息,具体的机器地址在ZooKeeper查询得到。这种同步的调用机制足够直观简单,只是没有“订阅——推送”机制。

AMQP-based的代表系统是 Kafka 、 RabbitMQ 等。这类分布式消息处理系统将订阅者和消费者解耦合,消息的生产者不需要消费者一直在线;消息的生产者只需要把消息发送给消息代理,因此也不需要服务发现机制。

两种通信机制都有各自的优点和缺点,实际中的系统经常包含两种通信机制。例如,在分布式数据管理中,就需要同时用到同步HTTP机制和异步消息处理机制。

微服务架构解决了无架构的整体编码的应用的问题以及SOA的问题。同时它还可以提供实时的产品发布。它是一个分布式架构,也会有上面分布式的问题。

美高梅官方网站,关键概念

基于空间的架构 (Space-Based Architecture)

基于空间的架构有时候也被成为基于云的架构。

大部分的基于web的应用的业务流都是一样的。
客户端的请求发送给web服务器,然后是应用服务器,最后是数据库服务器。对于用户很小时不会有问题,但是负载增大时就会遇到瓶颈(想想抢火车票)。首先是web服务器撑不住,web服务器能撑住应用服务器又不行,然后是数据库服务器。通常解决方案是增加web服务器,便宜,简单,但很多情况下负载会传递给应用服务器,然后传递给数据库服务器。有时候增加数据库服务器也没有办法,因为数据库也有锁,有事务的限制。

基于空间的架构用来解决规模和并发的问题。

基于空间的架构最小化限制应用规模的影响。这个模式来自于tuple space,
分布式共享内存想法。要想大规模,就要移除中心数据库的限制,使用可复制的内存网格。应用数据保存在所有活动的处理单元的内存中,处理单元根据应用规模可以加入和移除。因为没有中心数据库,所以数据库的瓶颈可以解决。

这种模式有两个组件: 处理单元processing unit 和 虚拟化中间件virtualized
middleware 。

美高梅官方网站 15

处理单元包含应用程序。小的应用程序可以使用一个处理单元,大的应用程序可以被分隔成几个处理单元。处理单元还包括数据网格。

虚拟化中间件负责管理和通信。处理数据的同步和请求。

基于空间的架构是一个复杂而昂贵的模式。对于小型的负载可变的web应用很适合,但是对于大型的关系型数据库应用不是太适合。

注意每一层都是封闭的。这意味着Request必须经过每一层才能到达最底下一层。

比较

美高梅官方网站 16

美高梅官方网站 17

为什么不允许展示层直接访问数据库层呢,这样不是更快吗?这就是分层架构的另一个特征:层隔离(layers
of isolation)。

层隔离的概念意味着你对任何一层的改变都不会影响其它层。这很好理解。

层隔离也意味着一个层的组件并不会了解其它层的实现,或者知道很少。
比如业务层不需知道你持久层是由hibernate还是mybatis实现的。

分层架构也很容易增加新的层。
比如你想将一些通用的服务重构成一个服务层,比如通用图片处理,远程账户审计等,可以在业务层下增加一个服务层。它不会对展示层造成影响,也不会改变持久层的代码。

上面的这个例子带来一个问题,因为每一层丢失封闭的,业务层不得不通过服务层访问持久层,这没有天理啊。
所以有时候你会创建一个开放的层。这意味着上一层可以绕过这一层直接访问下一层。

美高梅官方网站 18

架构例子

我们看一下淘宝前几年的架构的例子。

这是一个标准的分层的架构。每一层中又可以详细的分成更细的层,比如服务层。

围着着这个主架构还有一些外围的产品。比如监控和审计。

架构考量

分层架构是一个可靠的通用的架构,对很多应用来说,如果你不确定哪种架构适合你的应用,可以用它作为一个初始架构。

第一个要注意的是污水池反模式(architecture sinkhole
anti-pattern).这个反模式是这样的,请求流简单的穿过几个层,每层里面基本没有做任何业务逻辑,或者做了很少的业务逻辑。比如一些JavaEE例子,业务逻辑层只是简单的调用了持久层的接口,本身没有什么业务逻辑。

每一层或多或少都有可能遇到这样的场景。关键是分析这样的请求的百分比是多少。80-20原则可以帮助你决定是否正在遇到污水池反模式。如果你的请求超过20%,你应该考虑让一些层变成开放的。

另一个需要考虑的是分层架构可能会让你的应用变得庞大,即使你的展示层和业务层可以独立发布(比如展示层使用单页技术框架AngularJS,
EmberJS)。

它的确会带来一些潜在的问题,比如分布模式复杂,健壮性下降,可靠性,性能和规模等。

模式分析

总体灵活性: 低

发布易用性: 低

可测试性: 高

性能: 低

规模扩展性: 低

开发容易度: 高

事件驱动架构 (Event-Driven Architecture)

事件驱动架构是一个流行的分布式异步架构模式,可以用来设计规模很大的应用程序。基于这种架构模式应用可大可小。它由高度解耦的,单一目的的事件处理组件组成,可以异步地接收和处理事件。

它包括两个主要的拓扑结构:mediator 和
broker。Mediator拓扑结构需要你在一个事件通过mediator时精心安排好几个步骤,而broker拓扑结构无需mediator,而是由你串联起几个事件。这两种拓扑架构的特征和实现有很大的不同,所以你需要知道哪一个适合你。

Mediator拓扑结构

Mediator拓扑结构适合有多个步骤的事件,需要安排处理层次。

例如购买一只股票,首先会校验这个交易,校验股票交易是否符合各种规定,将它交给一个经纪人,计算佣金,最后确认交易。所有这些都安排好各个步骤的顺序,决定它们是否串行还是并行。

它包括四个组件:event queues, an event mediator, event channels 和 event
processors。

事件流是这样开始的: 客户端发送一个事件到事件队列(event
queues)中,它用来将事件传送给event mediator。Event
mediator收到初始的事件后,会发送额外的一些异步事件给event
channels来执行处理的每个步骤。Event processors监听event
channels,接收事件并处理一些业务逻辑。

在事件驱动架构中有十几个甚至几百个事件队列都很正常。模式本身没有限定事件队列的实现方式。它可能是一个消息队列,一个web
service或者其它。

这里有两种事件:初始事件和处理事件。Mediator会将初始事件编排成处理事件。它没有具体的业务逻辑,只是一个协调者,负责将初始事件转化成一个或者多个处理事件。

event channels
既可以是消息队列,也可以是消息topic,大部分是消息topic,这样可以由多个消息处理器(event
processor)处理同一个消息。

消息处理器包含实际的业务逻辑。每个消息处理器都是自包含的,独立的,高度解耦的,执行单一的任务。

这种模式可能有一些变种。作为架构师,你应该理解每个实现的细节,确保这种解决方案适合你的需求。

有一些开源的框架实现了这种架构,如Spring Integration, Apache Camel, 或者
Mule ESB。

Broker拓扑架构

Broker不同于上面的结构,它没有中心的Mediator。所有的事件串联起来通过一个轻量级的消息broker如RabbitMQ,ActiveMQ,HornetQ等。如果你的消息比较简单,不需要重新编排,就可以使用这种结构。

如图所示,它包含两个组件broker和 event processor。

broker中的event channel可以是消息队列,消息topic或者它们的复合形式。

每个event processor负责处理事件,发布新的事件。

架构例子

在新浪微博的早期架构中,微博发布使用同步推模式,用户发表微博后系统会立即将这条微博插入到数据库所有粉丝的订阅列表中,当用户量比较大时,特别是明星用户发布微博时,会引起大量的数据库写操作,超出数据库负载,系统性能急剧下降,用户响应延迟加剧。后来新浪微博改用异步推拉结合的模式,用户发表微博后系统将微博写入消息队列后立即返回,用户响应迅速,消息队列消费者任务将微博推送给所有当前在线粉丝的订阅列表中,非在线用户登录后再根据关注列表拉取微博订阅列表。

架构考量

事件驱动架构模式实现起来相对复杂,主要是由于它的异步和分布式特性。这可能会带来一些分布式的问题,比如远程处理的可用性,缺乏响应,broker重连等问题。

一个考虑是这种模式对于单一的逻辑缺乏原子事务。所以你需要将原子事务交给一个事件处理器执行,跨事件处理器的原子事务是很困难的。

最困难的设计之一是事件处理器的创建,维护和管理。事件通常有特殊的约定(数据值和格式)。

模式分析

相关文章