有
许多类型的软件体系结构各有利弊。 接下来,我们将讨论其中最受欢迎的功能,并讨论我们向微服务的过渡。
/ libreshot / PD软件架构的类型
分层架构
这是最常见的体系结构之一。 在此基础上,构建了许多大型框架-Java EE,Drupal,Express。 这种架构最著名的例子也许就是
OSI网络模型。
该系统分为多个级别,每个级别仅与两个相邻的级别交互。 因此,通常位于交互链末端的对数据库的查询顺序地通过每个“层”。
体系结构
并不意味着任何强制性的级别-可以有三个,四个,五个或更多。 大多数情况下,使用三层系统:表示层(客户端),逻辑层和数据层。
关于多层架构的书籍和文章已不计其数。 对其优缺点也有不同的看法。
优点:此体系结构的每个级别执行一组严格受限的功能(不会逐层重复),并且不知道其他级别如何安排。 因此,级别的“内容”可以更改,而不会出现层之间全局冲突的风险。
通常,多层应用程序如此广泛,以至于需要为其开发创建特殊的模板生成器。 例如,
用于Visual Studio的LASG提供了几种代码生成方法,这些方法可以自动执行例行任务并帮助构建应用程序层。
缺点:在编程中,有一种说法是,可以通过添加另一个抽象级别来解决任何问题。 但是,这种方法最终会导致代码的组织不良,并使开发人员感到困惑。
另一个问题由此产生-低速。 在不使用业务逻辑的情况下,许多信息开始层层传递。 这个问题有时
被称为下沉反模式,当无用操作的数量开始超过有用的操作时,这种设计模式就会出现。
在多层系统上查找错误也
可能很困难 。 在进入数据库之前,信息会遍历各个级别(因为数据库是最终组件)。 如果由于某种原因该信息已损坏(或在运行过程中丢失),则为了查找错误,您必须分别分析每个级别。
适合度:- 创建需要快速部署的新应用程序。 这是一种“通用模板”。
在1cloud中开始研究虚拟基础架构提供商的内部系统时,我们使用了这种特殊类型的架构。 最初,我们没有创建能够处理成千上万用户流量的IaaS服务的任务。 我们决定迅速在市场上推出该产品,并开始发展客户群,并解决可扩展性问题(现在,我们将所有系统转移到微服务架构,这将在后面讨论)。
在开发人员中, 有一种观点认为从项目开始的第一天就没有必要为巨大的负载做准备(编写面向未来的软件)。 应用程序或服务的实际要求可能与预期有所不同,并且业务目标可能会更改 。 因此,着眼于遥远的未来编写的代码有可能成为技术债务。 - 根据O'Reilly的说法,分层架构是许多企业应用程序的自然选择。 由于公司(尤其是大型公司)通常共享能力:有一个团队负责前端,有一些人负责后端,依此类推。 这意味着将应用程序自然地划分为多个级别:一些开发人员在客户端上工作,其他开发人员在逻辑上工作。
康威(Conway)的法律 (早在1967年制定)也规定了组织结构与应用程序开发方法之间的类似关系。 上面写着:“开发系统时,组织被迫遵守重复公司内部通信结构的方案。”
面向事件的架构
在这种情况下,开发人员会在发生任何事件时规定程序的行为(反应)。 系统中的事件被认为是其状态的重大变化。
您可以在车厢里买车来类比。 当汽车找到新的拥有者时,其状况从“待售”变为“已售”。 此活动启动了售前准备过程-安装其他设备,检查技术条件,清洗等。
事件驱动的系统通常包含两个组件:事件源(代理)及其使用者(接收器)。 通常也有两种类型的事件:发起事件和消费者响应的事件。
Java Swing库是实现此体系结构的一个示例。 如果该类需要有关事件的警报,则开发人员将实现所谓的侦听器-ActionListener(他“捕获”相应的事件),并将其附加到该事件可以生成的对象上。
Wiki提供了此机制的以下实现代码:
public class FooPanel extends JPanel implements ActionListener { public FooPanel() { super(); JButton btn = new JButton("Click Me!"); btn.addActionListener(this); this.add(btn); } @Override public void actionPerformed(ActionEvent ae) { System.out.println("Button has been clicked!"); } }
体系结构的优势:由于应用程序由大量异步模块组成(它们不具有彼此的实现信息),因此易于扩展。 这样的系统被组装为构造函数-您无需注册依赖项,只需实现一个新模块即可。 此外,异步模型还可以提高应用程序性能。
缺点:这种应用程序的异步特性使调试变得复杂。 一个事件可以一次触发多个动作链。 如果有很多这样的链条,那么
可能很难理解到底是什么导致了故障。 为了解决这个问题,我们
必须解决错误处理的困难条件。 从这里开始,日志记录的问题随之而来-日志
难以构造。
适用于:- 创建异步系统。 这是显而易见的,因为架构本身包含大量异步模块。
- 可用于创建UI。 网页充当容器,每个组件都在其中被隔离并响应某些用户操作。
- 在各种信息系统之间组织消息传递。
微内核架构
这种类型的体系结构包含两个组件:系统核心和插件。 插件负责业务逻辑,内核负责管理它们的加载和卸载。
作为微内核体系结构的示例,O'Reilly的书
提供了 Eclipse IDE。 这是一个简单的编辑器,用于打开文件,允许对其进行编辑并运行后台进程。 但是,通过添加插件(例如Java编译器),其功能得以扩展。
微内核架构曾一次将Symbian操作系统用于移动设备(开发于2012年停止)。 在她的微内核中有一个任务调度程序,内存管理系统和驱动程序,以及负责电话通信的文件系统和组件充当插件。
体系结构的优势:将应用程序从一个环境
移植到另一个环境很容易,因为只需要修改微内核。 高级别策略和低级别机制的分离简化了系统支持并确保了其可扩展性。
缺点:如果插入太多模块,则会降低应用程序性能。 但是,在插件数量和微核任务数量之间
找到平衡 (通常只包含经常使用的代码)可能会
成问题 。
提前(在开发应用程序之前)确定微核代码的最佳片段化程度也是困难的。 后来改变方法几乎是不可能的。
适用于:- 创建可被大量人使用的可扩展应用程序。 例如,iPhone OS具有“微内核”的根源-它的开发人员从Mach (这是微内核的第一个示例)中汲取了灵感。
- 创建应用程序,将基本方法和高级规则清楚地分开。
- 开发具有动态变化的规则集的系统,这些规则集必须经常更新。
微服务
类似于事件驱动的体系结构和微内核。 但是,当可以将各个应用程序任务轻松地划分为
独立于小功能的
服务时,可以使用它们。 这些服务可以用不同的编程语言编写,因为它们使用REST API(例如,使用
JSON或
Thrift )相互通信。
开发人员决定将代码按什么比例划分,但是“
创建微服务”一书的作者Sam Newman建议您为微服务分配尽可能多的代码行,以使团队能够在两周内重现。 据他介绍,这将避免过多的建筑“膨胀”。
微服务通常是在所谓的容器中启动的。 这些容器可通过网络访问其他微服务和应用程序,编排系统将它们全部管理:示例包括Kubernetes,Docker Swarm等。
优点:微服务架构简化了应用程序扩展。 要实现新功能,只需编写新服务即可。 如果不再需要该功能,则可以禁用微服务。 每个微服务都是一个单独的项目,因此很容易在开发团队之间分配有关它们的工作。
在Martin L. Abbott的书《可伸缩性的艺术》中,详细了解微服务系统的伸缩机制。
缺点:很难找到错误。 与单片系统不同(当所有功能都在同一内核中时),可能很难确定请求为何“下降”。 有关详细信息,您必须转到“有罪”过程的日志(如果有多个,则问题会更加严重)。
这为微服务之间的消息传输增加了额外的开销。 根据我们的估计,网络成本的增长可以达到25%。
另一个缺点是
需要忍受最终一致性(
从长远来看是一致性 )的概念。 微服务有自己的数据仓库,其他微服务可以访问它们。 有关此数据更改的信息不会立即通过系统分发。 因此,当某些微服务(尽管时间非常短)的数据过时时,就会出现这种情况。
使用地点:- 在高负荷的大型项目中。 例如,流平台使用微服务。 内容交付系统和其他支持服务可以相互独立缩放,以适应负载变化。
- 在使用“混合”资源的系统中。 如果应用程序的一部分需要更多的处理器时间,第二部分需要更多的内存,则将它们划分为微服务是有意义的。 然后可以将它们托管在不同的计算机上-分别具有强大的CPU或大量的内存。
- 需要安全性时 。 由于微服务是隔离的并通过API进行通信,因此可以确保仅传输特定服务所需的信息。 在使用密码或支付卡数据时,这一点很重要。
我们为什么要在1cloud中切换到微服务
正如我们已经说过的,我们提供的服务(
私有云 ,
虚拟服务器 ,
对象云存储等)的基础是多层架构。 她表现出良好的一面,但现在她的扩展能力开始耗尽。
我们正在成为越来越多的合作伙伴,他们可以基于我们的特许经营平台提供解决方案。 有些远程站点和服务很难从一个角度进行管理(特别是,我们的设备位于
俄罗斯,哈萨克斯坦和白俄罗斯的多个数据中心)。
为了使扩展现有功能和引入新功能更加容易,我们将整个基础架构转移到
1cloud中的微服务上。

我们希望将它们分成单独的模块,而不是从一个复杂的数据库中获得N个简单的数据库。 因此,在新架构中,每个功能都将具有一个单独的数据库。 它在支持和开发方面更加方便和高效。
我们将能够在多个开发人员(公司的重点专长)之间划分服务工作,并有效地横向扩展-必要时,我们只需连接新的微服务即可。
我们的客户还将获得许多优势。 由于微服务未相互连接,因此当特定服务失败时,只有微服务将不可用,其余所有服务将继续正常运行。 此外,即使我们的服务出现全球性下降,控制面板也将继续工作。
来自哈萨克斯坦和白俄罗斯(以及我们将在其开设代表处的其他国家/地区)的客户将注意到界面的速度和响应能力有了显着提高,因为控制面板位于本地。
已经做了什么
到目前为止,我们仅实施了第一个试点项目:“监视服务”。 其余服务将在2018年底-2019年初转移到新的轨道。
同时,新架构为下一阶段奠定了技术基础-迁移到容器。 现在,我们使用Windows基础结构,并切换到容器,我们需要将所有累积的代码重写为.NetCore并将其传输到Linux。
我们计划在2019年初开始新的过渡,并在明年年底完成。
用简单的话说一下关于建筑值得记住的东西- 多级体系结构 -应用程序分为多个级别,每个级别执行一组严格定义的功能。 每个级别都可以单独修改。 缺点包括代码速度低和难以发现错误。
适用于需要快速推向市场的开发应用程序。 常用于创建企业服务。 - 面向事件的体系结构 -在这里,开发人员规定了系统对任何事件的反应。 例如,如果接收到数据,则将其写入文件。 由于所有事件处理程序都不了解彼此的实现,因此基于事件的体系结构的应用程序易于扩展。 但是,调试此类系统很困难-单个动作可能一次导致多个动作链(很难理解是哪个动作导致了故障)。
用于创建异步系统,图形界面和消息传递系统的组织。 - 微内核架构 -由两个关键组件组成:插件和内核。 插件负责业务逻辑,内核负责加载和卸载它们。 职责分离简化了系统支持。 但是,它会影响性能-它直接取决于连接和活动模块的数量。
它适用于开发可被大量人员使用的可扩展应用程序,以及具有经常需要更新的一组规则的系统(插件可确保易于更新)。 - 微服务架构 -应用程序分为功能-微服务。 每个微服务都是具有自己的业务逻辑的独立组件。 这些组件使用API相互通信。 这样的应用程序易于开发(可以在开发团队之间分配工作),但是却很难调试。
用于要求高安全性的大型项目中。
我们还在1cloud博客上写些什么: