定义
扩展性,就是在对系统影响最小的情况下,网站的功能可以持续的拓展以及提升的能力。这就是拓展性。上一篇文章我讲解了伸缩性的网站架构如何设计,相信大家可能对伸缩性和拓展性这两个概念经常会有误用,其实许多工程师都会有混淆两者的概念,会用拓展性表示伸缩性。下面我来总结下区别:
拓展性
指对现有系统影响最小的情况下,系统功能可持续扩展或提升的能力。表现在系统基础设施稳定不需要经常变更,应用之间较少依赖和耦合,对需求变更可以敏捷响应。它是系统架构设计层面的开闭原则(对扩展开放,对修改关闭),架构设计考虑未来功能扩展,当系统增加新功能时,不需要对现有系统的结构和代码进行修改。
伸缩性
指系统能够通过增加(减少)自身资源规模的方式增强(减少)自己计算处理事务的能力。如果这种增减是成比例的,就被称作线性伸缩性。在网站架构中,通常指利用集群的方式增加服务器数量、提高系统的整体事务吞吐能力。
如何构建一个可拓展的网站架构呢??
开发一个低耦合的系统是软件设计的终极目标之一,这一目标至今驱动我们软件开发技术的创新和发展。从各种软件系统工具到各种开发框架,,从汇编语言到面向过程的开发语言,都体现了软件系统低耦合这一设计目标,低耦合的系统就意味着更容易扩展,低耦合的模块更容易复用,一个低耦合的系统设计会让开发过程和维护变得更轻松和容易管理。
但是低耦合不意味着完全没有关系。如何分解系统的不同模块、如何定义各个模块的接口,如何复用不同的模块构造成一个完整的系统是软件设计中最有挑战的部分。一个优秀的软件架构师最大的价值不在于掌握多少先进的技术,而在于具有将一个大系统切分成N个低耦合的子模块的能力,这些子模块包含横向的业务模块,也包含纵向的基础技术模块。
核心
设计网站可扩展架构的核心思想是模块化,并在此基础之上,降低模块间的耦合性,提高模块的复用性。
网站通过分层和分割的方式进行架构伸缩,分层和分割也是模块化设计的重要手段,利用分层和分割的方式将软件分割为若干个低耦合的独立的组件模块,这些组件模块以消息传递及依赖调用的方式聚合成一个完整的系统。
在大型网站中,这些模块通过分布式部署的方式,独立的模块部署在独立的服务器(集群)上,从物理上分离模块之间的耦合关系,进一步降低耦合性提高复用性。
在降低了耦合性和提高了复用性之后,网站就具备可拓展性,更容易拓展了。
那么在模块进行分布式部署之后,模块之间的聚合如何实现呢??
主要通过两种: 分布式消息队列和分布式服务
一、利用分布式消息队列降低系统耦合性
如果模块之间不存在直接调用,那么新增或修改模块对其他模块影响就很小,这一系统可拓展性会更好。
模块之间的交互可以使用事件驱动架构,通过在低耦合的模块之间传输事件消息,以保持模块的松散耦合,并借助事件消息的通信完成模块间的合作,典型的EDA架构就是操作系统的生产者消费者模式。在大型网站系统中,最常用的手段就是分布式消息队列,如图所示:![](https://img.haomeiwen.com/i4017523/4bd8b615f224ed31.png)
消息队列使用分布--订阅模式。消息发送发布一个消息,其他的消息消费者监听到消息(或者说事件)之后,会进行处理。
可以看到两者之间互不关联,这是异步处理。对于新增的业务,只要对该类消息感兴趣,就可以订阅,对原有系统和其他业务没有影响,从而实现可拓展设计。
消息接受者在对消息进行过滤、处理、包装后,构造成一个新的消息类型,将消息继续发送出去,等待其他消息接受者订阅处理该消息。因此基于事件(消息对象)驱动的业务架构可以是一系列的流程。
同时消息队列还具备削峰的作用。
分布式的消息队列
队列是一种先进先出的数据结构,分布式消息队列可以看作将这种数据结构部署到独立的服务器上,应用程序可以通过远程访间接口使用分布式消息队列,进行消息存取操作,进而实现分布式的异步调用 , 基本原理如图![](https://img.haomeiwen.com/i4017523/188fcd2aed85b72f.png)
消息生产者应用程序通过远程访问接口将消息推送给消息队列服务器,消息队列服务器将消息写入本地内存队列后立即返回成功响应给消息生产者。消息队列服务器根据消息订阅列表查找订阅该消息的消息消费者应用程序,将消息队列中的消息按照先进先出(FIFO)的原则将消息通过远程通信接口发送给消息消费者程序。
目前开源的有很多,但是普通通用且出名的就这几款:
RabbitMQ、KafKa、RocketMQ等等。
这些消息队列在可用性、伸缩性、数据一致性、性能和可管理性方面都做了很多的改善。
比如:
伸缩性方面,每加一台消息队列服务器,消息队列是无状态的,我们只要在消息生产者的服务列表加一台即可。
可用性方面,如果消息队列的服务器内存满了,会将消息写入磁盘,消息消费完后,会从磁盘读取加载到内存中,继续处理。
为了避免消息队列服务器宕机造成消息丢失,会将消息成功发送到消息队列的消息存储在消息生产者服务器,等消息真正被消息消费者服务器处理后才删除消息。在消息队列服务器宕机后,生产者服务器会选择分布式消息队列服务器集群中其他的服务器发布消息。
二、利用分布式服务打造可复用的业务平台
设计可拓展性架构的另一种重要手段就是使用分布式服务。如果说分布式消息队列通过消息对象分解系统耦合性,不同子系统处理同一 个消息;那么分布式服务则通过接口分解系统耦合性,不同子系统通过相同的接口描述进行服务调用。
随着网站功能的日益复杂, 网站应用系统会逐渐成为一个巨无霸,如图7.3所示。一个应用中聚合了大量的应用和服务组件,这个巨无霸给整个网站的开发、维护、部署都带来了巨大的麻烦。![](https://img.haomeiwen.com/i4017523/b112ebe50691e964.png)
这种系统架构有很多问题:
1.编译部署库存
2.代码分支管理困难
3.新增业务,也就是拓展困难。
。。。
我们能做的就是将这些模块拆分。
纵向拆分: 将大应用拆分成几个小模块。
横向拆分: 将复用的业务拆分开,独立部署为分布式服务。新增业务只需要调用这些分布式服务,不需要依赖具体的代码。
纵向拆分相对较为简单,通过梳理业务,将较少相关的业务剥离,使其成为独立的Web应用。而对于横向拆分,不但需要识别可复用的业务,设计服务接口,规范服务依赖关系,还需要一个完善的分布式服务管理框架。
对于分布式服务要求具备的一些特性包括:
1.服务注册与发现
2.服务调用
3.负载均衡
4.失效转移
5.通信协议高效
6.对业务侵入较小
7.服务监控与管理
,,,,
现在java业界通用的基本都是springcloud和dubbo。
以dubbo为例:
![](https://img.haomeiwen.com/i4017523/58b5238f364489b0.png)
服务消费者程序通过服务接口使用服务,而服务接口通过代理加载具体服务,具体服务可以是本地的代码模块,也可以是远程的服务,因此对应用较少侵入:应用程序只需要调用服务接口,服务框架根据配置自动调用本地或远程实现。
服务框架客户端模块通过服务注册中心加载服务提供者列表(服务提供者启动后自动向服务注册中心注册自己可提供的服务接口列表),查找需要的服务接口,并根据配置的负载均衡策略将服务调用请求发送到某台服务提供者服务器。如果服务调用失败,客户端模块会自动从服务提供者列表选择一 个可提供同样服务的另一 台服务器重新请求服务,实现服务的自动失效转移,保证服务高可用。
Dubbo 的远程服务通信模块支持多种通信协议和数据序列化协议,使用 NIO 通信框架,具有较高的网络通信性能。
可拓展的数据结构
关于网站的可拓展性设计,除了在软件系统层面的通过分层拆分来将大模块拆分成一个个小模块,分布式部署后,使用消息队列来降低耦合和使用分布式服务提高可复用性来达到构建出的系统可拓展之外,我们还可以在数据库层面去设计,设计可拓展的数据结构。
传统的关系数据库为了保证关系运算(通过SQL语句)的正确性,在设计数据库表结构的时候,就需要指定表的schema字段名称,数据类型等,并要遵循特定的设计范式。这些规范带来的一个问题就是僵硬的数据结构难以面对需求变更带来的挑战,有些应用系统设计者通过预先设计一 些冗余字段来应对,不过显然这是一种糟糕的数据库设计。
于是出现了NOSQL的数据结构。无需修改表结构就可以新增字,段呢?许多 NoSQL 数据库使用的 Column Family (列族)设计就是一 个解决方案。
关于NoSQL的相关东西我就不该进行描述了,大家可以看我上一篇文章。
NoSQL的伸缩性架构设计部分
ColumnFamily 最早在Google的Bigtable 中使用,这是一 种面向列族的稀疏矩阵存储格式。
![](https://img.haomeiwen.com/i4017523/a6dbfddc126657ef.png)
这是一个学生的基本信息表,不同学生的联系方式各不相同,选修的课程也不同,而且在将来会有更多联系方式和课程加入到这张表,如果按照传统的关系数据库设计,无论提前预设多少冗余字段都会捉襟见肘,疲于应付。
而使用支持ColumnFamily结构的NoSQL数据库,创建表的时候,只需要指定ColumnFamily的名字,无需指定字段(Column),可以在数据写入时再指定,通过这种方式,数据表可以包含数百万的字段,使得应用程序的数据结构可以随意扩展。而在查询时,可以通过指定任意字段名称和值进行查询。
最后一种
利用第三方开放平台,大型网站为了更好地服务自己的用户,开发更多的增值服务,会把网站内部的服务封装成一些调用接口开放出去,供外部的第三方开发者使用,这个提供开放接口的平台被称作开放平台。第三方开发者利用这些开放的接口开发应用程序(APP)或者网站,为更多的用户提供价值。
文章参考:
《大型网站技术架构核心原理与实践》
网友评论