《大型网站技术架构》笔记:架构之可扩展
扩展性是指对现有系统影响最小的情况下,系统功能可持续扩展或提升的能力。表现在系统基础设施不需要经常变更,应用之间较少依赖和耦合,为需求变更可以敏捷响应。它是系统架构设计层面的开闭原则(对扩展开发,对修改关闭)。当系统增加新功能时,不需要对现有系统的结构和代码进行修改。
设计网站可扩展架构的核心思想是模块化,并在此基础之上,降低模块间的耦合性,提高模块的复用性。一般,通过分层和分割将软件分割为若干个低耦合的独立组件模块,这些组件模块以消息传递以依赖调用的方式聚合成一个完整的系统。在大型网站中,这些模块通过分布式部署的方式,独立的模块部署在独立的服务器(集群)中,从物理上分离模块之间的耦合关系,进一步降低耦合性提高复用性。
模块分布式部署后,具体聚合方式主要有分布式消息队列和分布式服务。
分布式消息队列
分布式消息队列是事件驱动架构的实现。事件驱动架构是指通过在低耦合的模块之间传输事件消息,以保持模块的松散耦合,并借助事件消息的通信完成模块间合作。消息队列利用发布-订阅模式工作。
</br>分布式消息队列可以看作将队列这种先进先出的数据结构部署到独立的服务器上,应用程序通过远程访问接口使用分布式消息队列,进行消息的存取操作,进而实现分布式的异步调用。</br>
分布式消息队列基本原理:消息生产者应用程序通过远程访问接口将消息推送给消息队列服务器,消息队列服务器将消息写入本地内存队列后立即成功响应给消息生产者。消息队列服务器根据消息订阅列表查找该消息的消息消费者应用程序,将消息队列中的消息按照先进先出的原则将消息通过远程通信接口发送给消息消费者程序。
- 伸缩性
消息队列服务器类似于无状态的服务器,将新服务器加入分布式消息队列服务器集群后,通知生产者服务器更改消息队列服务器列表即可。 - 可用性
分布式消息队列服务器如果内存队列已满,会将消息写入磁盘,消息推送模块在将内存消息队列消息处理完以后,再将磁盘内容加载到内存队列继续处理。
为避免某台消息队列服务器宕机造成消息丢失,会将消息成功发送到消息队列的消息保存在消息生产者服务器,等消息真正被消息消费者服务器处理后才删除消息。在消息服务器宕机后,生产者服务器会选择分布式消息队列服务器集群中的其他服务器发布消息。 - 主要产品
Apache ActiveMQ、RabbitMQ、 Kafka等。
分布式服务
分布式服务是通过接口分解系统耦合性,不同子系统通过相同的接口描述进行服务调用。将一个应用系统通过横向拆分和纵向拆分为多个独立模块,各个独立模块独立部署。
纵向拆分是指主要是指业务的拆分,通过梳理业务,使其成为独立的Web应用。而横向拆分是指将复用的业务拆分出来,独立部署为分布式服务,新增业务只需要调用这些分布式服务。
对横向拆分而言,不仅要识别可复用的业务,设计服务接口,规范服务依赖关系,还要一个完善的分布式服务管理框架。因此,分布式服务主要解决的问题就是怎么管理这些服务以及服务之间的通信等。
这个分布式服务管理框架要具有以下特点:
- 负载均衡
对于热门服务,要部署在集群上。分布式服务管理框架要能够支持请求者使用可配置的负载均衡算法访问服务,使服务提供者集群实现负载均衡。 - 失效转移
可复用的服务通常被多个应用调用,一旦该服务不可用,影响很大。分布式服务管理框架要支持服务提供者的失效转移机制,当某个服务实例不可用时,就将访问切换到其他服务实例上。 - 高效的远程通信
服务调用非常频繁,远程通信不高效会成为整个系统性能的瓶颈。 - 整合异构系统
网站服务可能使用不同语言并部署在不同平台,分布式服务管理框架要整合这些异构的系统。 - 对应用侵入少
- 版本管理
分布式服务管理框架要支持服务多版本发布,服务提供者先升级接口发布新版本的服务,并同时提供旧版本的服务供请求调用,当请求者调用接口与升级后才可以关闭旧版本服务。 - 实时监控
分布式服务管理框架需要监控服务提供者和调用者的各项指标,提供运维和运营支持。
WebService
WebService是一种企业级分布式服务框架,用以整合异构系统及构建分布式系统。
主要原理:服务提供者通过Web服务描述语言(Web Service Description Language,WSDL)向注册中心(Service Broker)描述自身提供的服务接口属性,注册中心使用UDDI(Universal Description, Discovery and Integerration,统一描述、发现和集成)发布服务提供者提供的服务。服务请求者从注册中心检索到服务信息后,通过简单对象访问协议(Simple Object Access Protocol ,SAOP)和服务提供者通信,使用相关服务。
缺点:臃肿的注册与发现机制;低效的XML序列化手段;开销相对较高的HTTP远程通信;复杂的部署与运维手段。
这些问题导致WebService不符合大型网站对分布式服务框架的要求。
基于Thrift的分布式服务框架
Facebook没有开源。尽管Thrift本身是一个开源的远程服务调用框架,但本身功能并不符合大型网站对分布式服务框架的要求。
阿里的Dubbo
- 对应用侵入少:应用程序只需要调用服务接口,Dubbo根据配置自动调用本地或远程实现。
- 自动失效转移:服务提供者启动后自动向服务注册中心注册自己可提供的服务接口列表。Dubbo客户端通过服务注册中心加载服务提供者列表,查找服务接口。当有调用请求时,Dubbo客户端根据配置的负载均衡策略将其发送到某台服务提供者服务器。如果服务调用失败,Dubbo客户端会自动从服务提供者列表选择一个可提供同样服务的另一条服务器重新请求服务,实现服务的自动失效转移。
- 高效的远程通信:使用NIO通信框架,支持多种通信协议和数据序列化协议。
可扩展的数据结构
为解决传统数据库僵硬的数据结构问题(无法随意扩展字段等),很多NoSQL使用列族(ColumnFamily)设计。
支持列族(ColumnFamily)的NoSQL数据库在创建表的时候,只需要指定ColumnFamily的名字,无需指定字段,可以在数据写入时再指定。通过这种方式,数据表可以包含数百万的字段,使得应用程序的数据结构可以随意扩展。而在查询时,可以通过指定任意的字段名称和值进行查询。
利用开发平台建设网站生态圈
开放平台是指大型网站为了更好的服务自己的用户,开发更多的增值服务,把网站内部的服务封装成一些调用接口开放出去,供外部的第三方开发者使用,这个提供开放接口的平台就是开放平台。