可伸缩设计
系统的伸缩性是架构中最重要的技术,即使用服务器的集群功能,通过不断向集群中添加服务器来增强整个集群的处理能力。
“伸”即架构的规模和服务器的规模不断扩大。
架构的伸缩性设计
架构的伸缩性设计可以分成两类,一类是根据功能进行物理分离实现伸缩,另一类是单一功能通过集群实现伸缩。前者是不同的服务器部署不同的服务,提供不同的功能;后者是集群内的多台服务器部署相同的服务,提供相关的功能。
架构的物理分离分为如下两种。
◎ 纴向分离:根据功能模型的不同将系统分离,一般分为展示层、应用层、服务层和数据层。
◎ 横向分离:根据业务模型的不同,可以将业务纴向进行分离。
对集群规模的调整指通过负载均衡动态增减服务器的数量,如图5.9所示。
图5.9
应用服务的伸缩性设计
应用服务器的伸缩性,指的是HTTP请求分发装置可以感知或者配置集群的服务器数量,还可以及时发现集群中新上线或下线的服务器,并能向新上线的服务器分发请求,停止向已下线的服务器分发请求。这种HTTP请求分发装置被称为负载均衡服务器。
负载均衡是网站必不可少的基础技术,不但可以实现网站的伸缩性,还可以改善网站的可用性,是网站的重要技术。负载均衡的具体技术实现也多种多样,从硬件实现到软件实现,从商业产品到开源,应有尽有,但实现负载均衡的基础技术不外乎如下几种。
(1)HTTP 重定向负载均衡。HTTP 重定向服务器是一台普通的应用服务器,其唯一功能就是根据用户的 HTTP 请求计算出一台真实的服务器地址,并将该服务器地址写入HTTP 重定向响应中(重定向响应状态码为 302)返回给用户的浏览器。用户的浏览器在收到响应之后,根据返回的信息重新发送一个请求到真实的服务器上。
(2)DNS域名解析负载均衡。在利用DNS处理域名解析请求的同时进行负载均衡是另一种常用的方案。每次域名解析请求都会根据负载均衡算法计算一个不同的 IP 地址并返回,这样在 A 记录中配置的多台服务器就构成了一个集群,可以实现负载均衡。DNS域名解析负载均衡的优点是将负载均衡工作交给DNS,省略了网络管理的麻烦,缺点就是DNS可能缓存A记录,不受网站控制。事实上,大型网站总是部分使用DNS域名解析,作为第1级负载均衡手段,再在内部做第2级负载均衡。
(3)反向代理负载均衡。反向代理可以缓存资源,改善网站性能。事实上,反向代理也可以做负载均衡,由于反向代理服务器在HTTP层面转发请求,因此也叫作应用层负载均衡,其优点是部署简单,缺点是可能导致成功系统的瓶颈。
(4)IP负载均衡。指网络层通过修改请求目标地址进行负载均衡,在用户请求数据包到达负载均衡服务器后,负载均衡服务器在操作系统内核获取网络数据包,根据负载均衡算法计算得到一台真实的We b服务器的地址,然后将数据包的I P地址修改为真实的We b服务器的地址,不需要通过用户进程处理。在真实的 We b 服务器处理完毕后,相应的数据包回到负载均衡服务器,负载均衡服务器再将数据包源地址修改为自身的 IP 地址发送给用户的浏览器。
这里的关键在于真实的 We b 服务器的相应数据包如何返回给负载均衡服务器:一种方案是负载均衡服务器在修改目标 IP 地址的同时修改源地址,将数据包源地址改为自身的IP,即源地址转换(SNAT);另一种方案是将负载均衡服务器同时作为真实物理服务器的网关服务器,这样所有的数据都会到达负载均衡服务器。
IP负载均衡在内核进程中完成数据分发,较反向代理均衡有更好的处理性能。但由于所有请求响应的数据包都需要经过负载均衡服务器,因此负载均衡的网卡带宽成为系统的瓶颈。
(5)数据链路层负载均衡。这种数据传输方式又被称为三角传输模式,负载均衡数据在分发过程中不修改IP地址,只修改目标MAC地址,通过将真实物理服务器集群所有机器的虚拟IP地址和负载均衡服务器的IP地址配置为一致的IP地址,来达到负载均衡,这种负载均衡方式又被称为直接路由方式。在用户的请求到达负载均衡服务器后,负载均衡服务器将请求数据的目标MAC地址修改为真实的Web服务器的MAC地址,不修改数据包目标I P地址,因此数据可以正常到达目标Web服务器,该服务器在处理完数据后可以经过网管服务器而不是负载均衡服务器直接到达用户的浏览器。
分布式缓存的伸缩性设计
在分布式缓存服务器集群中,不同服务器中的缓存数据并不相同,对缓存的访问请求,不能在缓存服务器集群中的任意一台上处理,必须先找到缓存中有需要数据的服务器,才能进行访问。这会严重制约分布式缓存集群的伸缩性设计,因为新上线的缓存服务器没有缓存数据,而已下线的缓存服务器还缓存着网站的许多热点数据。
分布式缓存集群伸缩性设计的最主要目标就是让新上线的缓存服务器对整个分布式缓存集群的影响最小,也就是说在新加入缓存服务器后,应使在整个缓存服务器集群中已经缓存的数据尽可能被访问到。
数据存储的伸缩性设计
数据存储服务器集群的伸缩性对数据的持久性和可用性都提出了更高的要求。具体来说,可以分为关系数据库集群的伸缩性设计和NoSQL数据库的伸缩性设计。
在关系数据库集群的伸缩性设计中,主要的关系数据库都支持数据复制功能,使用这个功能可以对数据库进行简单伸缩。另外,除了利用数据库进行主从读写分离,也可以利用业务分隔模式使不同业务的数据表部署在不同的数据库集群上,即数据分库。但这种方式的制约条件是跨库不能进行Join操作。在大型网站的实际应用中,即使使用了分库和主从复制,对一些单表数据量很大的表还需要进行分片,
将一张表拆开且分别存储在多个数据库中。
NoSQL 主要指非分布式的非关系数据库设计模式。一般而言,NoSQL 数据库产品都放弃了关系数据库的两大重要基础:以关系代数为基础的结构化查询语言(SQL)和事物一致性保证(ACID),但是强化了高可用性和可伸缩性。
可扩展性设计
扩展性是指在对现有系统影响最小的情况下,系统功能可持续扩展或提升的能力。设计架构可扩展的核心思想是模块化,并在此基础上降低模块间的耦合性,提供模块的复用性。对模块通过分布式部署,将独立的模块部署在独立的服务器上(集群),从物理上分离模块之间的耦合关系。模块在分布式部署后的具体聚合方式主要有分布式消息和分布式服务这两种。
通过消息降低系统的耦合性
如果在模块之间不存在直接调用,那么新增模块或者修改模块对其他模块影响最小,这样系统的可扩展性无疑更好一些。事件驱动框架指通过在低耦合的模块之间传输事件消息,以保持模块的松散耦合,并借助事件消息的通信完成模块间的合作,典型的架构就是生产者消费者模式。在大型网站架构中具体的实现手段很多,最常用的就是分布式消息队列,消息队列利用发布-订阅模式工作:消息发送者发布消息,一个或者多个消息接收者订阅消息。由于消息发送者不需要等待消息接收者处理数据就可以返回,所以系统具有更好的响应延迟;同时,在网站访问高峰期间,消息可以被暂时存储在消息队列中等待处理,减轻了数据库等后端存储的负载压力。
通过分布式服务提供可复用的业务
使用分布式服务是降低系统耦合性的另一个重要手段。例如,分布式消息队列通过消息规避系统的耦合性,由不同的子系统处理同一个消息;分布式服务则通过接口分解系统的耦合性,不同的子系统通过相同的接口描述进行服务调用。大型系统的分布式服务的需求与特点为:负载均衡、失效转移、高效的远程通信、整合异构系统、对应用最小入侵、版本管理和实时监控。
目前,国内有较多成功实施案例的开源分布式服务框架是阿里巴巴的Dubbo,服务消费程序通过服务接口使用服务,而服务接口通过代理加载具体服务,具体服务可以是本地的代码模块,也可以是远程的服务,因此对应用入侵较小;应用程序需要调用服务接口,服务框架则根据配置自动调用本地或远程实现。
服务框架的客户端模块通过服务注册中心加载服务提供者列表(服务提供者在启动后主动向服务注册中心注册自己可提供的服务接口列表),查找需要的服务接口,并根据配置的负载均衡策略将服务调用请求发送到某台服务提供者的服务器。如果服务调用失败,则客户端模块会自动从服务提供者列表中选择一个可提供同样服务的另一台服务器重新请求服务,实现服务的自动失效转移,保证高可用服务。
建立开放平台
大型系统为了更好地服务自己的用户,开放了更多的增值服务,会将系统内部的服务封装成一些调用接口开放出去,供外部的第三方开发者使用,这种提供开放接口的平台被称作开放平台。开放平台是系统内部和外部交互的接口,在外部需要面对众多的第三方开发者,在内部需要面对系统内诸多的业务服务。虽然每个系统的业务场景和需求都不相同,但开发平台的架构设计大同小异。开发平台的要求如下。
◎ API 接口:是开发平台暴露给开发者使用的一组 API,其形式可以是 RESTful、WebService和RPC等形式。
◎ 协议转换:将各种 API 输入转换成内部服务可以识别的形式,并将内部服务的返回封装成API格式。
◎ 安全:除了一般应用需要的身份识别、权限控制等安全手段,开放平台还需要配置分级的访问带宽限制,以保证资源被公平合理地使用。
◎ 审计:记录第三方应用的访问情况并进行监控、计费等。
◎ 路由:将开放平台的各种访问路由映射到具体的内部服务。
◎ 流程:将一组离散的服务组织成一个上下文相关的新服务,隐藏服务的细节,提供统一的接口供开发者调用。
本文给大家讲解的内容是程序员架构修炼:架构设计,可伸缩设计与可扩展性设计
- 觉得文章不错的朋友可以转发此文关注小编;
- 感谢大家的支持