读书笔记-互联网创业核心技术(构建可伸缩的Web应用)

1 核心概念,单一服务器到更强的服务器

垂直伸缩

  • 通过使用RAID增加I/O吞吐能力
  • 通过切换SSD改善I/O访问速度
  • 通过增加内存减少I/O操作(意味着文件系统有更多的缓存空间,应用程序有更多的工作内存)
  • 通过升级/增加网络接口提高网络吞吐能力
  • 更新服务器获得更多处理器或者更多虚拟核
  • 主要制约:成本,当越过某个点后,垂直伸缩会变得格外昂贵;CPU速度;每台服务器的虚拟核数目;硬盘速度。

服务分离

  • 不同的物理机上安装不同的服务类型,比如FTP,DNS,缓存,等。
  • 功能分割:将整个Web应用切分成一组不同的功能模块,将他们独立部署。

内容分发网络(CDN)

CDN 缓存静态文件。用户将从最近的CDN服务器获取静态内容,进而加速页面加载时间。

分散访问流量:水平伸缩

通过增加服务器提升计算能力。

服务全球用户的伸缩性架构。

  • 使用GeoDNS服务:基于客户地理位置进行ip地址解析的DNS服务。用户会访问到离他最近的一个Web服务器,将网络延迟减到最小。
  • 边缘缓存(edge-cache)服务器:边缘缓存是一种距离用户较劲的HTTP缓存服务器,便于部分缓存用户的HTTP流量。

分层架构

  • 将不同功能划分到不同层次的架构。
  • 低层的组件暴露一组API给高层组件调用。
  • 每一层都消费其低层提供的服务,但是低层永远不会消费上层提供的服务。
  • 分层可以强制结构化并减少耦合,低层组件变得更简单和系统。越底层稳定性越强。

支持技术

  • Web周边,通常用一些第三方软件技术实现,比如消息队列,应用缓存,主数据存储,搜索引擎等。
  • 这些应该是一种即插即用的扩展组件,保证在组件进行更换时,整个架构不受影响。

2 软件设计原则

简单

简化从以下四个基本步骤进行

隐藏复杂与构建抽象

  • 系统很庞大时是无法保持整体简单的,能做的只是保持局部简单。
  • 达到局部简单,最主要的方式是确保任何单个的类/模块/应用的设计目标及工作原理都能被快速理解。
  • 好的设计原则是类之间的依赖关系尽量少。
  • 在庞大复杂的系统中,当创建一个独立的服务时,需要添加一个抽象层,所有的功能层都在这些抽象层基础上去实现,从而隐藏功能层的复杂性。

避免过度设计

  • 好的设计方法是可以在后期逐渐添加新的功能和特性,而不是一开始就开发一个超级大的系统。
  • 早期构建一个合理的抽象层次,然后迭代的增加新特性。

尝试测试驱动开发(TDD)

  • 先写测试代码,然后写功能实现代码。
  • 有助于工程师可以更好地把握工作重点,从用户视角看待问题,使开发的接口更简单清晰。

从软件设计的简化范例中学习

低耦合

  • 低耦合可以保证复杂性局部化。
  • 来更高层面上进行结构,意味着将系统分成多个应用,每个应用都只关注相对较小的一部分功能。这样每个应用就可以按需分别伸缩。
  • 促进低耦合:要在较高的抽象层面降低耦合度,需要让系统不同的部分接触面尽量少。
  • 避免不必要的耦合:一般来说,画系统架构设计图很容易暴露循环依赖,所以在设计阶段一定要画架构图。一个良好设计的模块儿叫扣图,看起来像一棵树,而不像一个社交网络图。
  • 低耦合范式:一个很好的低耦合设计例子是UNIX命令行编程及管道pipe用法。

不用重复自己

基于约定编程。

画架构图

  • 用例图:不考虑技术方案,仅仅关注业务需求,可以将功能特性和业务需求提炼出来。
  • 类图:展现独立模块的结构。一个典型的类图包含接口,类,关键方法名,以及他们的关系。依赖可以用一条线来表示,所以从类图上可以很容易的看出耦合关系。
  • 模块图:模块图描述了结构和依赖关系。他关注的抽象层次更高,可以认为是代码层面的缩略图,是类图的上面一层架构图,展示模块之间的依赖和交互。

单一职责

开闭原装

向扩展开放,向修改关闭。

依赖注入

  • 依赖注入的核心思想是知道的越少越好。
  • 依赖注入对类需要依赖的对象提供一个引用实例,而无需类自己创建依赖对象。

为伸缩而设计

  • 增加副本:通过增加副本,实现伸缩性,负载均衡。对于Web层,这样是最简单的,只需要增加服务器即可。
  • 功能分割:适用于各个层面,核心是发现系统的各个功能组成部分,然后将它们创建成为独立的子系统。
  • 数据分片:将不同的分片数据保存在不同的机器上,以保证每台服务器上存储的数据量都不会太大,也被称为无共享架构原则。

自愈设计

  • 设计软件一定要考虑高可用和系统自愈能力。
  • 高可用一般用几个9来衡量。
  • 系统自愈能力主要体现在系统宕机等情况下,无需人工干预,可以自动恢复工作,并修复必要的错误数据。

4 Web服务

Web服务设计

Web服务作为一种备用表示层

  • 其实就是前后端不分离,通常使用MVC框架开发。
  • 好处是可以延迟实现各种Web服务的代码,直到你证明了这个产品确实是可行的。
  • 在开发的早期阶段可以在代码层面快速增加新功能和应对变化,同时也降低了系统的总体复杂性。

API优先方式

  • 前后端分离开发,有助于客户端和服务端解耦,独立伸缩。
  • 需要避免过度设计
  • 业务逻辑的复杂性,从客户端代码推到了Web服务层。
  • 系统伸缩更容易,可以进行功能分割,将Web服务分割成一组更小的独立的服务。

务实的方式

  • 结合以上两种方式构建应用
  • 当你发现某个需求很容易就分离出一个独立的服务,而且这个功能也会被多个客户端调用,那么就可以考虑将其服务化。

Web服务类型

以功能为中心的服务

  • 是指能够调用远程机器上的功能或者对象方法,无需知道这些功能或者对象是如何实现的,以何种语言编写以及运行在什么样的架构上。
  • 将请求参数和数据序列化,然后传输到服务上,服务把结果返给你,本地再将结果进行反序列化,即可使用。
  • SOAP

以资源为中心的服务

REST服务

伸缩REST Web 服务

主要是把Web服务层按功能切分成比较小的粒度,然后增加备份,实现伸缩。

保持服务无状态

把Web服务所有的共享状态移出共享数据存储设备上,比如缓存,数据库,消息队列等。好处如下:

  • 可以基于每个请求进行流量分派。
  • 方便对Web服务节点操作:切换,关闭,移除,切换部署版本等,易于操作。
  • 系统伸缩性方便,比如使用负载均衡器实现自动伸缩。
缓存服务响应

通常在客户端和Web服务之间部署一个反向代理。做HTTP缓存。

功能分割

功能分割就是拆分出系统的子功能,构成一个独立的子系统。

5 数据存储层

MySQL伸缩性

复制

  • 主从复制,例如部署多台从服务器,实现分布式查询。
  • 主从配置方案:将只读操作分布在多个从服务器上;针对不同的查询使用不同的从服务器,例如慢查询一台,一般查询一台;增加可用性,实现一个零停机时间的备份
  • 主-主结构,AB两台机器互相复制数据,MySQL支持环形复制,一般不建议这么做,比较复杂,且数据不一致风险大。
  • 环形复制会导致系统可用性降低,失效恢复困难,额外增加复制延迟,主服务器越多,宕机概率越高。

数据分区/分片

选择分片键
  • 核心原理是将数据以某种方式切分,以便每台服务器都只存储一部分数据。
  • 或选择分片键和映射算法,将数据分布到多台服务器上。比如两个服务器分别存储用户ID为奇数和偶数的用户信息。
  • 优点:可以根据数据量对数据库进行水平伸缩;可以在应用层实现,而在数据层看到效果。
  • 缺点:无法对多分片数据进行联合查询;无法使用数据库的ac id事务;随着数据增长,分片键和服务器编号映射算法难度增加;往集群中添加新的服务器难度极大。
  • 可以利用一个独立的数据库存储用户和服务器编号的映射关系,方便在不同分片之间进行数据迁移。

6 缓存

缓存命中率

影响缓存命中率的因素:

  • 缓存键集合大小:尽量减少可能的缓存键数量,数量越少,命中率越高
  • 缓存可使用内存空间的大小,理论上能缓存的对象越多,命中率就越高
  • 平均生存时间(TTL),理论上缓存时间越长,命中率就越高

基于HTTP的缓存

HTTP 缓存头 Cache-Control

  • private 只能特定响应给请求用户,不能提供给其他用户
  • public 可以在用户间被共享
  • no-store 响应可以缓存在内部,不能持久化到磁盘
  • no-cache 响应不能被缓存
  • max-age 定义响应的TTL,缓存时间
  • no-transfer 响应不做任何修改,直接用缓存
  • Must-revalidate 一旦响应过于陈旧,不重新验证就不能返回给客户端
  • 要避免使用缓存相关的 HTML 元标记,因为他们不能用来控制中间缓存,还会带来混乱。

HTTP 缓存技术

  • 浏览器缓存
  • 缓存代理
  • 反向代理
  • CDN

7 异步处理

  • 同步处理和异步处理:
    简单来讲,同步处理是阻塞的,必须先做完一件事,才能做第二件事;异步处理是非阻塞的,第一件事做到一半可以在后台另开一个线程去做,直接做第二件事情。
  • 消息队列:实现异步处理的工具。有消息生产者创建消息,由消息队列存储消息,有消费者去对消息进行处理。一个可伸缩系统中的生产者和消费者通常是独立的进行或线程运行,二者解耦,且可以独立伸缩。

消息生产者

一般消息使用XML或JSON格式。

消息代理

消息队列有很多实现方式,比如最简单的共享文件夹,也可以是SQL数据库,也可以是支持接收、路由、持久化和发送消息的专用消息代理。消息代理是解耦生产者和消费者的关键元素。

消息消费者

实现模式主要有两种,周期模式和守护模式。路由方法主要有以下几种

  • 直接工作队列模型:消费者只需要指定队列的名称去消费信息,多个消费者竞争消费消息,很适合多个机器上分配一些耗时任务。主要适用于发送邮件,处理视频,调整图片大小或向第三方Web服务上传内容等。
  • 发布订阅模型:生产者发送消息到一个主题,而不是队列,消费者都可以获取这个主题的消息。
  • 定制路由规则:有些消息代理也支持各种形式的路由定制,可以更灵活的处理消息,比如:RabbitMQ中,可以绑定一个概念来创建灵活的路由规则(基于文本模式匹配),在ActivateMQ中,可以使用Camel扩展来创建更高级的路由规则。

消息协议

  • AMQP(高级消息队列协议):明确定义消息发布、消费和传输的协议,RabbitMQ和在ActivateMQ都支持。
  • STOMP(流式面向文本的消息协议):极简化的协议,无状态,类似HTTP的,基于文本的协议,在协议层不需要更多的性能开销,一些高级特性需要通过定制头信息来扩展实现,比如预取数量就是一个很好的特性,可以通过声明想批量获取的消息数来提高吞吐量。RabbitMQ和在ActivateMQ都支持。
  • JMS(Java消息服务):是一个Java消息标准,有语言限制。

消息基础设施

  • 将队列分隔成几组不同的服务器,这样独立的队列就不依赖于其他组件,你简单的通过添加机器实现水平伸缩。
  • RabbitMQ和ActiveMQ能胜任每秒数万级别消息的吞吐量,如果计划处理每秒10万级别的消息,需要自己制定分区机制,将负载分散到多个消息代理实例。

评估消息代理软件

  • 每秒发送的消息数。
  • 平均每条消息的大小。
  • 每秒消费的消息数。
  • 并发发布者数量。
  • 并发消费者数量。
  • 是否考虑消息持久化?
  • 是否需要消息通知,比如消费者崩溃的情况下,消息不丢失。

消息队列的好处

  • 异步处理。
  • 易伸缩。
  • 使峰值变平缓。
  • 隔离失效机器及自我修复。
  • 解耦。

消息平台比较

  • 亚马逊简单队列服务 SQS:具有无设置,无匹配,无维护,无意外的优点,使用成本最低,适合初创公司,吞吐量高。有消息大小限制,不保证顺序,有偶发的消息重发情况。
  • RabbitMQ:灵活性强,能动态地配置路由,实现生产者与消费者解耦,缺少局部消息排序和会坏消息支持。
  • ActiveMQ:用Java编写,可以使用Camel实现RabbitMQ高级路的一些复杂特性。不能使用远程api实现完全控制,发送大流量消息时,对峰值敏感,可能会因为那内存不足崩溃。

8 数据搜索

索引

  • 索引是结构的,按特定顺序排序的,并为特定类型的搜索进行优化。
  • 数据集在大小上减少了,因为索引比整个文本内容少很多,所以能很快的加载和处理。
  • 大部分索引都是排序的。一个简单快速搜索算法的例子就是二分查找算法。
  • 索引对搜索来说非常有用,但是他需要增加一些额外的开销。维护索引需要排序项来维护额外的数据结构,随着数据集增长,数据结构会比较大,代价比较高。
  • 添加索引需要仔细的规划,明确哪些数据值得索引。
  • 基数越高,索引性能越好。
  • 均匀分布时,索引性能更好。
  • 复合索引的索引字段顺序需要仔细考虑。

NoSQL数据建模

  • 键值数据存储:适用于一对一查询,例如Redis,Memcached常用于缓存。
  • 宽列数据存储:这些数据存储按照复合索引对数据建模,构建了排序列表,例如BigTable,HBase,Cassandra。
  • 面向文档的数据存储:允许构建更复杂的对象和索引,文档数据结构包含数组,映射和嵌套数据结构,比如JSON和XML。常用数据库有MongoDB,CouchDB,CouchBase。

搜索引擎

  • 全文本搜索使用倒排索引
  • 使用专业搜索引擎,比如Amazon CloudSearch,Azure Search,Elassticsearch,Solr,Sphinx。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值