网站的可扩展架构

1、可伸缩与可扩展—傻傻分不清楚

  上篇笔记咱们学习了可伸缩架构,但在实际场合中,包括许多架构师也经常混淆可伸缩和可扩展,用可扩展表示伸缩性。那么在此,跟随做者咱们来理清这两个概念,避免咱们之后对其傻傻分不清楚。html

  (1)扩展性Extensibiltiy数据库

  指对现有系统影响最小的状况下,系统功能可持续扩展或提高的能力。咱们不由想到了面向对象中一大原则:开闭原则,对扩展开放,对修改封闭。也就说,当系统新增一个功能时,不须要对现有系统的结构和代码进行修改。服务器

  (2)伸缩性(Scalability数据结构

  指系统可以经过增长(或减小)自身资源规模的方式加强(或减小)本身计算事务的能力。在网站架构中,一般是指利用集群的方式增长服务器数量,从而提升系统的总体事务吞吐能力。架构

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

2、利用分布式消息队列下降系统耦合性

  上面咱们提到说要分离模块之间的耦合,若是模块之间不存在直接调用,那么新增模块或者修改模块就对其余模块的影响最小,这样系统的可扩展性无疑会更好一些。那么,有没有一种架构是基于如此考虑而设计的呢?因而,咱们将眼光转向一个名叫“事件驱动”的架构。异步

2.1 事件驱动架构

  根据事件驱动架构(Event Driven Architecture)的定义:经过在低耦合的模块之间传输消息,以保持模块的松散耦合,并借助事件消息的通讯完成模块间合做。典型的EDA架构就是操做系统中常见的生产者消费者模式。在大型网站架构中,具体实现手段有不少,可是最多见的是分布式消息队列数据库设计

  如上图所示,消息队列利用发布—订阅模式工做,消息发送者发布消息,一个或多个消息接受者订阅消息。消息发送者是消息源,在对消息进行处理后发送至分布式消息队列,消息接收者从分布式消息队列获取该消息后继续进行处理。能够明显看出,发送者与接受者之间没有直接耦合,消息发送者只需将消息发送给分布式消息队列即操做结束,而消息接受者也只须要从分布式消息队列获取消息后进行处理,不须要知道该消息从何而来。所以,对于新增业务,只要对该类消息感兴趣,便可订阅该消息,对原有系统和业务没有任何影响,从而实现网站业务的可扩展设计分布式

2.2 分布式消息队列

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

  如上图所示,咱们能够明确三个步凑:

  ①消息生产者应用程序经过远程访问接口将消息推送给消息队列服务器,消息队列服务器将消息写入本地内存队列后立刻返回成功响应给消息生产者。

  ②消息队列服务器根据消息订阅列表查找订阅该消息的消费者应用程序,将消息队列中的消息按照先进先出的原则将消息经过远程通讯接口发送给消费者应用程序;

  ③消费者应用程序接收到推送过来的消息以后进行相关的一系列处理,过程终止;

PS:那么,有没有这样一种状况:消息队列服务器宕机后致使消息丢失。事实上,这种状况的确存在于实际的运维过程当中。那么,咱们如何来避免呢?这时,做者给出了一个方案:若是消息队列服务器宕机形成消息丢失,会将消息成功发送到消息队列的消息存储在消息生产者服务器,等消息真正被消息消费者服务器处理后才删除消息。在消息队列服务器宕机后,生产者服务器会选择分布式消息队列服务器集群中其余的服务器发布消息。

另外,有关于分布式消息队列的实践能够采用NoSQL产品来构建,例如Redis就提供了队列数据类型,能够方便地构建分布式消息队列,若是你有兴趣,也能够参阅个人另外一篇博文:《使用Redis做为消息队列服务应用场景案例

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

  若是说分布式消息队列经过消息对象分解系统耦合性,不一样子系统处理同一个消息;那么分布式服务则经过接口分解系统耦合性,不一样子系统经过相同的接口描述进行服务调用。

3.1 巨无霸的应用系统带来的问题

  网站由小到大的演化过程当中,表现为整个网站是由单一系统逐步膨胀发展变化而来的,随着网站功能的日益复杂,网站应用系统会逐渐成为一个巨无霸,以下图所示。能够看出,一个应用中聚合了大量的应用和服务组件,这个巨无霸给整个网站的开发(编译麻烦、代码分支管理困难)、维护(新增业务困难)和部署(部署困难)都带来了巨大的麻烦。

3.2 拆分,拆分仍是拆分

  解决方案仍是咱们屡次提到的拆分,将模块独立部署,下降系统耦合性。拆分又分为:横向拆分和纵向拆分。这里咱们再次回顾一下这两种方式:

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

  (2)横向拆分:将能够复用的业务拆分出来,独立部署为分布式服务,新增业务只须要调用这些分布式服务便可,不须要依赖于具体的模块代码。若是模块内业务逻辑发生变化时,只要接口保持一致就不会影响业务程序和其余模块。

4、可扩展的数据结构

  传统的关系数据库为了保证关系运算(经过SQL语句)的正确性,在设计表结构的时候就须要制定表的Schema—字段名称、数据类型等,还要遵循制定的设计范式(例如:1NF、2NF、3NF等等)。这些规范带来的一个问题就是僵硬的数据结构难以面对需求变动带来的挑战,有些系统设计者经过预先设计一些冗余字段来应付(在我所实习的一年里,我见过不少次这种设计,虽然能够解决问题,但从设计学来讲,真的好Shit),但这显然是一种糟糕的数据库设计。

  那么,有木有办法可以作到可扩展的数据结构设计呢?是否能够不须要修改表结构就能够新增字段呢?答案是确定的,目前许多NoSQL数据库使用的ColumnFamily列族)设计就是一个解决方案。ColumnFamily最先在Google的BigTable中使用,这是一种面向列族的稀疏矩阵存储格式。或许这么说你们仍是不明白,但能够经过下图来理解:

  这是一个学生基本信息表,不一样学生的联系方式不一样,选修的课程也不一样,并且在未来会有更多的联系方式和课程加入这张表,若是按照传统的数据库设计,不管提早预设多少冗余字段都不够用,捉襟见肘,疲于应付。而是用ColumnFamily结构的NoSQL数据库,建立表的时候,只须要指定ColumnFamily的名字,无需指定字段(Column),能够在数据写入时再指定,经过这种方式,数据表能够包含数百万的字段,使应用程序的数据结构能够随意扩展

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

  网站的价值在于为他的用户创造价值,大型网站为了更好地服务本身的用户,会开发更多的增值服务,会把网站内部的服务封装一些调用接口开放出去,供外部的第三方开发者使用,这个提供开放接口的平台被称做开放平台。第三方开发者利用这些开放的接口开发应用程序(APP)或者网站,为更多的用户提供价值。这样一来,网站、用户、第三方开发者相互依赖,造成一个网站的生态圈,即为用户提供更多的价值,也提升了网站和第三方开发者的竞争能力和盈利能力。

  目前BAT等国内互联网巨头都建设有本身的开放平台,力图利用本身庞大的用户群吸引第三方开发者,打造一个更加庞大的航母战斗群,在市场竞争中呼风唤雨,立于不败之地。

相关文章
相关标签/搜索