系统可扩展性说明 系统可扩展性设计_系统架构

目录

可扩展性

可扩展性的定义

可扩展架构的核心思想

可扩展性架构的主要手段

利用分布式消息队列降低系统耦合性

事件驱动架构(Event Driven Architecture)

消息队列的优势

分布式消息队列

利用分布式服务打造可复用的业务平台

巨无霸系统及其问题

解决方案:横向拆分

WebService与分布式服务

分布式服务框架设计要点

分布式服务框架设计

利用开放平台建设网站生态圈


扩展性

可扩展性的定义

使网站能够快速响应需求变化,新需求改动对现有产品透明无影响,不需要任何改动或者改动很小。它是系统架构设计层面的开闭原则(对扩展开放,对修改关闭),架构设计考虑未来功能扩展,当系统增加新功能时,不需要对现有系统的结构和代码进行修改。

可扩展架构的核心思想

模块化,并在此基础上,降低模块间的耦合性,提高模块的复用性。【模块化,高内聚,低耦合,高复用】

可扩展性架构的主要手段

事件驱动架构:利用消息队列来实现,生产者和消费者是分离的,可以透明地添加新的消费者或者生产者。 => 降低系统耦合性

分布式服务:将业务和可复用服务分离出来,通过分布式服务框架调用。新增需求可以通过调用可复用的服务来实现。 => 提高模块的复用性

利用分布式消息队列降低系统耦合性

如果模块之间没有直接调用,那么新增模块或修改模块就对其它模块的影响最小,这样系统的可扩展性就会更好一些。

事件驱动架构(Event Driven Architecture)

通过在低耦合的模块之间传输事件消息,以保持模块的松散耦合,并借助事件消息的通信完成模块间的合作,典型的事件驱动架构就是操作系统中生产者消费者模式,而在分布式系统中,最常用的就是分布式消息队列。

消息队列的优势

1、提高系统响应时间,消息发送者不需要等待消息被处理就可以返回

2、削峰,网站访问高峰,可以将消息存储在消息队列中,然后根据自身负载控制消息处理速度,减少数据库等后端存储的负载压力

分布式消息队列

应用程序通过分布式消息队列接口发送消息,消息队列服务器收到消息后,先写入本地内存队列后立即返回给消息生产者。消息队列服务器根据消息订阅列表查找订阅该消息的消费端程序,然后将消息按先进先出的规则将消息通过远程通信接口发送给消费端程序。

系统可扩展性说明 系统可扩展性设计_扩展性_02

目前开源和商业的分布式消息队列产品很多,比如Kafka、ActiveMQ等。这些产品在可用性、伸缩性、数据一致性、性能和可管理性方面做了很多改善。

  • 伸缩性:消息队列服务器类似于无状态的服务器,新服务器加入集群后,通知生产者服务器更改消息队列服务器列表即可。【说的简单,实际是这样的吗?】
  • 可用性:在内存队列已满的情况下,会将消息写入磁盘,当内存队列处理完成后,再从磁盘中加载到内存队列中
  • 数据一致性:待消费端真正消费消息后,返回回执,然后消息队列服务器才会删除消息

利用分布式服务打造可复用的业务平台

使用分布式服务是降低系统耦合性的另外一个重要手段。如果说分布式消息队列通过消息对象分解系统耦合性,不同子系统处理同一消息;那么分布式服务则通过接口分解系统耦合性,不同子系统通过相同的接口描述进行服务调用。

巨无霸系统及其问题

随着业务发展,网站逐步演化,功能日渐复杂,开发、维护、部署越来越难。

  • 编译、部署困难:编译一次耗时太久,需要部署大量的服务【现在的GSP项目就是这样】
  • 代码分支管理困难:多个团队维护不同的模块,代码合并可能发生冲突,或各个模块间依赖问题
  • 数据库连接耗尽:每个服务5个连接,数据库实际上支撑不了太多连接【就像现在的GSP项目】
  • 新增业务困难:水太深,改了这个坏了别处,业务难以分析透彻

系统可扩展性说明 系统可扩展性设计_扩展性架构_03

解决方案:横向拆分

拆分,将模块独立部署,降低系统耦合性。

  • 纵向拆分:将大应用拆分为多个小应用,如果新增业务比较独立,则可以直接设计为一个独立的Web系统。 => 梳理业务,剥离业务形成独立Web应用
  • 横向拆分:将复用的服务拆分出来,独立部署为分布式服务,新增业务只需要调用这些分布式服务,不需要依赖具体的模块代码,即可快速搭建一个应用系统。而模块内业务逻辑变化的时候,只要接口保持一致就不会影响业务程序和其它模块。=> 识别可复用的服务、设计服务接口、规范服务依赖关系、分布式服务管理框架

系统可扩展性说明 系统可扩展性设计_扩展性_04

WebService与分布式服务

WebService曾是企业级应用开发的一把好手,用于整合异构系统及构建分布式系统。

WebService(Web服务)是指服务提供者将应用作为服务部署在Web上,通过使用Web服务描述语言(WSDL)来描述特定Web服务提供的功能。服务请求者在Web服务的注册机构中查找分布在Web站点上的Web服务,并自动实现与服务的绑定,完成数据交换,在这个过程中无需人工干预。

实现WebService需要相关技术标准的支持,目前支持Web Service的技术标准主要有:      

    1. XML:用于进行数据交换和表达的元语言标准,用来在Web Service中表示服务请求和响应的内容;

    2. UDDI(Universal Description, Discovery & Integration):用于Web Service注册与服务查找。

    3. WSDL(Web Service Description Language):用于描述Web Service的接口和操作功能。

    4. SOAP(Simple Object Access Protocol):为建立Web Service和服务请求之间的通信提供支持。

系统可扩展性说明 系统可扩展性设计_扩展性_05

以上内容摘自《系统架构设计师教程》。

WebService虽然有成熟的技术规范和产品实现(比如Apache CXF),也在企业级开发中有很多成功案例,但也有如下缺点:

  • 臃肿的注册与发现机制
  • 低效的XML序列化手段
  • 开销相对较高的HTTP远程通信
  • 复杂的部署与维护手段

这导致WebService难以满足大型网站对系统高性能、高可用、易部署、易维护的要求。

分布式服务框架设计要点

对于大型网站而言,除了WebService所提供的服务注册与发现、服务调用等标准库功能外,还需要分布式服务框架提供如下特性:

  • 负载均衡:部署多个实例组成集群,通过负载均衡进行访问
  • 失效转移:服务不可用时,可以自动切换到其它可用实例上
  • 高效远程通信:大型网站每日调用次数达亿计,高效的远程通信,使得其不会成为系统性能瓶颈
  • 整合异构系统:不同语言开发的服务,可以进行整合
  • 应用侵入少:尽量减少对原有应用的侵入
  • 版本管理:支持多版本管理、多版本部署发布
  • 实时监控:监控服务提供者和调用者的各项指标,为运维提供支持

分布式服务框架设计

国内较为成功的开源分布式服务框架是阿里巴巴Dubbo,其架构设计如下:

服务消费者程序:通过服务接口使用服务,而服务接口通过代理加载具体的服务,具体服务可以是本地代码模块,也可以是远程服务,因此对应用侵入较少;应用程序只需要调用服务接口,服务框架根据配置自动调用本地或远程实现。

服务框架客户端:通过注册中心加载服务提供者列表,查找需要的服务接口,并根据配置的负载均衡策略将服务调用请求发送到某台服务提供者服务器。如果服务调用失败,客户端模块会自动从服务提供者列表中选择一个可用的服务重新请求,实现服务的自动失效转移,保证服务高可用。

系统可扩展性说明 系统可扩展性设计_扩展性_06

Dubbo的远程通信模块支持多种通信协议和序列化协议,使用NIO通信框架,具有较高的网络通信性能。

利用开放平台建设网站生态圈

大型网站为了更好地服务用户,开发更多的增值服务,会把网站内部的服务封装成一些调用接口开放出去,供第三方开发者调用,这个提供开放接口的平台称作开放平台。比如钉钉开放平台、微信开放平台等。

开放平台是网站内部与外部交互的接口,外部需要面对众多的第三方开发者,内部需要面对网站内部诸多的业务服务。虽然每个网站业务场景和需求各不相同,但是开发平台的架构设计却大同小异。具体如下:

系统可扩展性说明 系统可扩展性设计_分布式服务_07

  • Open API:开放平台暴露出来给第三方开发者使用的一组API,其形式可以是Restful、WebService、RPC等各种形式
  • 协议转换:将各种API输入转换为内部服务可以识别的形式,或者将内部服务的返回封装成API的格式
  • 安全:身份识别、权限控制、分级带宽访问限制
  • 审计:记录第三方应用的访问情况,并进行监控、计费等
  • 路由:将开放平台的各种访问路由映射到具体的内部服务上
  • 流程:将一组离散的服务组成一个上下文相关的新服务,隐藏服务细节,提供统一接口供开发者调用