网站的可扩展架构

扩展性:

指对现有系统影响最小的情况下,系统功能可持续扩展或提升的能力。表现在系统基础设施稳定不需要经常变更,应用之间较少依赖和耦合,对需求变更可以敏捷响应。它是系统架构设计层面的开闭原则(对扩展开放,对修改关闭),架构设计考虑未来功能扩展,当系统增加新功能时,不需要对现有系统的结构和代码进行修改。

7.1构建可扩展的网站架构

开发低耦合系统是软件设计的最终目标之一,这一目标驱动着软件开发技术的创新与发展,从软件与硬件的第一次分离到操作系统的诞生;从汇编语言到面向过程的开发语言,再到面向对象的编程语言;从各种软件工具到各种开发框架;无不体现着降低软件系统耦合性这一终极目标。可以说,度量一个开发框架,设计模式,编程语言优劣的重要尺度就是衡量它是不是让软件开发过程和软件产品更加低耦合。

显而易见,低耦合的系统更容易扩展,低耦合的模块更容易复用,一个低耦合的系统设计也会让开发过程和维护变得更加轻松和容易管理。一个复杂度为100的系统,如果能够分解成没有耦合度的两个子系统,那么每个子系统的复杂度不是50,而可能是25.当然,完全没有耦合就是没有关系,也就无法组合出一个强大的系统。那么如何分解系统的各个模块,如何定义各个模块的接口,如何复用组合不同的模块造成一个完整的系统,这是软件设计中最优跳转的部分。

软件架构师最大的价值不在于掌握多少先进的技术,而在于具有将一个大系统切分为N个低耦合的子模块的能力,这些子模块包含横向的业务模块,也包含纵向的基础技术模块。这种能力一部分源自专业的技术和经验,还有一部分源自架构师对业务场景的理解,对人性的把握,甚至对世界的认知。

设计网站可扩展架构的核心思想是模块化,并在此基础在,降低模块间的耦合性,提高模块的复用性。在大型网站中,这些模块通过分布式部署的方式,独立的模块部署在独立的服务器集群上,从物理上分离模块之间的耦合关系,进一步降低耦合性提高复用性。

模块分布式部署以后具体聚合方式主要有分布式消息队列和分布式服务

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

如果模块之间不存在直接调用,那么新增模块或者修改模块就对其他模块影响最小,这样系统的可扩展性无疑更好一些。

7.2.1事件驱动架构

事件驱动架构:通过在低耦合的模块之间传输事件消息,以保持模块的松散耦合,并借助事件消息的通信完成模块间合作,典型的EDA架构就是操作系统中常见的生产者消费者模式。在大型网站架构中,具体实现手段很多,最常用的是分布式消息队列:

消息队列利用发布-订阅模式工作,消息发送者发布消息,一个或多个消息接受者订阅消息。消息发送者是消息源,在对消息进行处理后将消息发送至分布式消息队列,消息接受者从分布式消息队列获取该消息后继续进行处理。可以看到,消息发送者和消息接受者之间没有直接耦合,消息发送者将消息发送至分布式消息队列即结束对消息的处理,而消息接受者只需要从分布式消息队列获取消息后进行处理,不需要知道该消息从何而来。对新增业务,只要对该类消息感兴趣,即可订阅该消息,对原有系统和业务没有任何影响,从而实现网站业务的可扩展设计。

消息接受者在对消息进行过滤,处理,包装后,构造成一个新的消息类型,将消息继续发送出去,等待其他消息接受者订阅处理该消息。因此基于事件(消息对象)驱动的业务架构可以使一系列的流程。

由于消息发送者不需要等待消息接受者处理数据就可以返回,系统具有更好的响应延迟;同时,在网站访问高峰期,

7.2.2分布式消息队列

队列是一种先进先出的数据结构,分布式消息队列可以看做将这种数据结构部署到独立的服务器上,应用程序可以通过远程访问接口使用分布式消息队列,进行消息存取操作,进而实现分布式的异步调用。

消息生成者应用程序通过远程访问接口将消息推送给消息队列服务器,消息队列服务器将消息写入本地内存后立即返回成功响应给消息生产者。消息队列服务器根据消息订阅列表查找订阅该消息的消息消费者应用程序,将消息队列中的消息按照先进先出的原则将消息通过远程通信接口发送给消息消费者程序。

伸缩性方面,由于消息队列服务器上的数据可以看做是被即时处理的,因此类似于无状态的服务器,伸缩性设计比较简单。将新服务器加入分布式消息队列集群中,通知生产者服务器更改消息队列服务器列表即可。

可用性方面,为了避免消费者进程处理缓慢,分布式消息队列服务器内存空间不足造成的问题,如果内存队列已满,会将消息写入磁盘,消息推送模块在将内存队列消息处理完后,将磁盘内容加载到内存队列继续处理。

为了避免消息队列服务服务器宕机造成消息丢失,会将消息成功发送到消息队列的消息存储在消息存储在消息生产者服务器,等消息真正被消息消费者服务器处理后才删除消息。在消息队列服务器宕机后,生产者服务器会选择分布式消息队列服务器集群中其他的服务器发布消息。

分布式消息队列可以很复杂,比如可以支持ESB(企业服务总线),支持SOA(面向服务的架构)等;也可以很简单,比如用MySQL也可以当做分布式消息队列:消息生产者程序将消息当做数据记录写入数据库,消息消费者程序查询数据库并按记录写入写入时间戳排序,就实现了一个分布式消息队列,而且这个消息队列使用成熟的MySQL运维手段,也可以达到比较高的可用性和性能指标。

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

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

网站应用系统会逐渐成为一个巨无霸。这种应用系统会带来很多问题,编译部署困难,代码分支管理困难,数据库连接耗尽,新增业务困难等。

解决方案就是拆分,将模块独立部署,降低系统耦合性。拆分可以分为横向拆分和纵向拆分。

纵向拆分:将一个大应用拆分为多个小应用,如果新增业务较为独立,那么就直接将其设计部署为一个独立的Web系统。

横向拆分:将复用的业务拆分出来,独立部署为分布式服务,新增业务只需要调用这些分布式服务,不需要依赖具体的模块代码,即可以快速搭建一个应用系统,而模块内业务逻辑变化的时候,只要接口保持一致就不会影响业务程序和其他模块。

纵向拆分相对较为简单,通过梳理业务,将较少相关的业务剥离,使其成为独立的Web应用。而对于横向拆分,不但需要识别可复用的业务,设计服务接口,规范服务以来关系,还需要一个完善的分布式服务管理框架。

7.3.1 大型网站分布式服务的需求与特点

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

负载均衡,失效转移,高效的远程通信,整合异构系统(网站服务可能会使用不同语言开发并部署于不同的平台),对应用最少入侵,版本管理,实时监控等。

7.3.2分布式服务框架设计

大型网站需要更简单更高效的分布式服务框架构建其SOA。Facebook利用Thrift管理其分布式服务,服务的注册,发现及调用都通过thrift完成,但是对于一个大型网站可以使用的分布式服务框架,仅有Thrift还远远不够,遗憾的是,Facebook没有开源其基于Thrift的分布式服务框架。目前国内有较多成功实施案例的开源分布式服务框架是阿里的Dubbo

我们分析下Dubbo的架构设计:

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

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

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

  

猜你喜欢

转载自blog.csdn.net/qq_37113604/article/details/88235502
今日推荐