作者:Larry
近期读了《大型网站技术架构-核心原理与案例分析》一书,这是2013年电子工业出版社出版的图书,作者是李智慧。该书通过梳理大型网站技术发展历程,剖析大型网站技术架构模式,深入讲述大型互联网架构设计的核心原理。概述的作者是阿里巴巴网站的亲历者,也见证了技术为了支持业务需求所作的不断进化和迭代,值得一读。书中提到的很多问题,其实云计算是天然能解决一部分的,譬如高可用、高扩展,高性能等。
下面是记录的读书笔记,以及书中的一些精华见解:
网站架构设计的误区:
1,一味追随大公司方案
2,为了技术而技术
3,企图用技术解决所有问题
一:网站架构模式:
1,分层:将软件再横向切分
挑战:必须合理规划层间边界和接口,禁止跨层调用和逆向调用
2,分割:将软件再纵向切分
将服务包装成“高内聚低耦合”的模块单元,便于开发维护,还便于分布式扩展和并发处理
3,分布式
分层和分割是为了进行分布式部署和服务。但也带来了其他问题:
(1)分布式服务严重依赖网络性能
(2)保持事务和数据一致性
(2)开发维护困难
4,集群
对分布式部署的服务和模块集群化管理,通过负载均衡向外提供服务,提高整个系统可用性
5,缓存
缓存就是将数据存放在离用户更近的地方,或者读取更快的地方来加快处理速度,减小用户的等待时间
CDN:网络把静态资源存放在离用户较近的服务器
反向代理:反向代理也可以存储用户的静态资源无需查询应用服务区就可以将资源返回给用户
本地缓存:应用服务器本机的缓存,可以缓存一些热点数据,但是缓存会跟应用服务进程形成内存的资源竞争
分布式缓存:可以用专门的服务器来缓存数据应用层通过网络访问缓存服务
6,异步
业务之间的消息传递不是同步调用,而是将一个业务分拆为几个阶段,每个阶段之间通过共享数据的方式异步执行进行协作。分布式系统通过分布式消息队列实现异步。这样可以实现高可用,更快的返回速度和削峰
7,冗余
为了提高可用性,应用服务器和数据库都应该有一定程度的冗余,数据库的热备份/冷备份,以及双活等,异地灾备
8,自动化
自动化发布:自动代码管理,自动化测试,自动化构建,自动化部署
自动化监控:自动化监控,自动化失效转移,自动化失效恢复,自动化降级,自动化资源管理
9,安全
通过密码手机验证码进行身份认证,对网络通信进行加密(HTTPS/SSL),使用验证码预防机器人程序攻击,IDS/IPS (入侵检测系统和入侵防御系统)
二:架构
架构定义:”有关软件整体结构和组件的抽象描述,用来指导大型软件系统各个方面的设计“。
除了系统的功能需求,还有性能,可用性,可扩展性,伸缩性,安全性这5个架构要素。
1,性能
衡量性能的指标有用户响应时间(RT),TPS,系统性能参数(Metrics)
优化性能的手段也很多,从前端到后端有:
- 浏览器端缓存,CSS布局,页面压缩等
- 利用CDN和反向代理缓存
- 应用服务器可以使用本地缓存和分布式缓存
- 异步操作将用户请求发给消息队列等待后续任务处理,当前请求直接返回
- 应用服务器集群增加并发支持
- 代码层面可以多线程,改善内存管理等
- 数据库优化可以挑战索引,读写分离,缓存,SQL优化等,或者使用NOSQL数据库
2,可用性
网站高可用的主要手段是“冗余”,应用部署在多台服务器上同时提供服务,数据存储在多个地方互相备份,任何一台服务器发生故障都不影响其他整体可用性。
除了冗余的运行环境,网站高可用还需要软件开发过程的质量保证。通过自动化代码审查,自动化测试,自动化发布,灰度发布等减少故障上线的可能性,避免带来更大故障范围。
3,伸缩性
所谓伸缩性就是“不断向集群里加入新的服务器来缓解不断上升的用户规模带来的并发访问压力,和不断增加的数据存储需求”
衡量伸缩性标准:
- 是否可以由多台服务器构成集群
- 是否能容易的向集群加入新的服务器
- 是否新加入的服务器可以提供无差别的服务 (无状态服务)
- 集群是否有服务器的总数限制
对于应用服务器集群,只要服务器上不保存数据,都是可以通过负载均衡社保向集群加入新服务器
对于缓存服务器集群,新加入的服务器可能导致缓存路由失效,需要改进缓存路由算法。(一致性哈希算法)
关系数据库集群,伸缩性比较困难,可以读写分离,一写多读(增加读的数据库实例),可以垂直切分-分库(把不同业务数据放到不同数据库集群),可以水平切分-分表(把大表拆分),使用Mycat/Cobar等关系型数据库分布式中间件。
NoSQL数据库:天然支持高伸缩性。
4,扩展性
衡量网站的可扩展性的标准:网站在增加新产品时,是否不会影响到现有产品,或者仅仅对现有产品少量修改就可以上线新产品。产品模块之间低耦合。
网站可伸缩架构主要手段是:
- 事件驱动架构:使用消息队列将用户请求和其他业务隔离开。
- 分布式服务(RESTFUL):将业务和通用服务分开,通过分布式框架调用,新增产品通过调用通用服务实现自身逻辑
5,安全性
安全性包括基础设备安全,网络安全,访问安全,数据安全等
三:网站高性能架构
1,性能测试:响应时间、并发数、吞吐量、性能计数器
2,Web前端优化
(1)浏览器端优化
- 减少HTTP请求个数,减少重复请求
- 使用浏览器缓存
- 合理页面布局:CSS放在页面最上面,JavaScript放到最下面。浏览器下载完CSS后才会对页面进行渲染,而JS在加载后会执行,并阻塞整个页面。
- 启动压缩GZIP
(2)CDN加速
(3)反向代理缓存
3,应用服务器性能优化
分布式缓存:
- 避免缓存“频繁修改的数据”,“非热点数据”;
- 缓存雪崩:缓存预热,服务降级,限流,过期时间设为随机
- 缓存穿透:把无效key的值设为NULL
异步操作:用消息队列改善响应速度
使用集群:负载均衡
代码优化:
多线程
资源复用:单例,对象池
数据结构
垃圾回收
4,存储性能优化
HDD vs SSD
RAID vs HDFS
四:网站高可用性架构
(1)网站可用性度量: SLA
(2)高可用的应用
应用服务器集群:应用层主要处理网站应用的业务逻辑,一个显著的特点是无状态性,所谓无状态就是指应用服务器不保存业务的上下文信息,而是根据每次请求提交的数据进行业务逻辑处理。多个服务器实例之间完全对等,提交到任何一个服务求处理的结果是一样的。通过负载均衡进行无状态服务的失效管理。
应用服务器的SESSION管理:
- SESSION绑定/SESSION粘滞:通过源地址HASH算法绑定同一台服务器处理一个用户的所有请求,必须要7层负载均衡
- 利用Cookie记录session上下文数据。
- SESSION服务器:利用独立部署的session服务器(分布式缓存或者数据库)管理所有session,所有应用服务器都通过session服务器来获得session信息,这种方案其实是把应用服务器的状态分离,分为无状态的应用服务器和有状态的session服务器。
(3)高可用的服务:
- 1,分级管理:高级别服务使用高配置机器,多AZ,同时在服务器部署上也要隔离服务,避免故障的连锁反应
- 2,超时设置:设置服务调用的超时时间,进行调度
- 3,异步调用:有点情况要考虑分布式事务一致性
- 4,服务降级:访问高峰时,服务性能下降。有拒绝服务(部分低优先级的调用被拒绝)和关闭功能(关闭部分不重要的服务)
- 5,幂等性设计:重复调用的结果相同
(4)高可用的数据
保证高可用数据的手段是数据备份和失效转移机制。
- 数据备份:保持多个数据备份,任意一个副本失效不会造成数据丢失
- 失效转移:当一个副本不可用时,可以切换到另外一个可用副本
(5)数据备份
异步热备方式:只要有一个副本写入完成就可以返回
同步热备方式:必须所有副本都写入完成才可以返回
五:网站的伸缩性架构
1,网站的伸缩性一般可以分为两类,一种是不同功能物理分离实现伸缩,另外一种是单一功能使用集群实现伸缩。
- 不同功能物理分离实现伸缩:不同的服务器部署不同的服务,提供不同的功能,横向分层或纵向业务分离
- 单一功能使用集群实现伸缩:集群里服务器部署相同的服务,提供相同的功能
2,负载均衡
- HTTP重定向负载均衡:负载重定向服务器是一台普通的应用服务器,其唯一功能就是根据用户的HTTP请求计算一台真实的Web服务器地址然后将该地址写入HTTP重定向响应(302状态码)给浏览器
- DNS解析域名负载均衡:在DNS域名服务器里配置多个应用服务器地址,根据地理位置返回最近的服务器地址
- 反向代理负载均衡:7层负载均衡服务器Ngix
- IP负载均衡:在网络层通过修改目标地址进行负载均衡,LVS。4层负载均衡
- 链路层负载均衡:在通信协议的数据链路层修改MAC地址进行负载均衡。LVS
3,负载均衡算法
轮询,加权轮询,源地址哈希,随机,最少链接
4,分布式缓存一致性哈希算法
一致性Hash算法,通过一个叫一致性hash环的数据结构实现Key到缓存服务器的映射。
5,数据存储服务的伸缩性设计
关系型数据库伸缩:
MYSQL可以利用数据库主从读写分离架构形成集群。数据库根据业务分库,不同的业务部署在不同的集群中。目前支持数据库分布式集群的中间件有Amoeba和Cobar(阿里)。
Cobar是一个分布式关系数据库访问代理,介于应用层和数据库之间。应用程序通过JDBC驱动访问Cobar集群,Cobar根据SQL内容和分库规则分解SQL,分发到不同的MYSQL集群不同的实例上执行(每个Mysql实例部署都是主/从架构,保证高可用)。然后Cobar将不同MYSQL集群的返回查询结果归并在一起返回上层应用。
Cobar是无状态的应用服务,可以使用负载均衡伸缩。
MySql中存储着数据,如果要想保证集群扩容后数据一致负载均衡,必须做数据迁移,将集群中原来数据库里的数据迁移到新增加的数据库。具体迁移那些数据,可以用一致性hash算法,尽量使要迁移的数据最少。实践中,Cobar利用了Mysql数据同步进行迁移,迁移不是以数据为单位,而是以Schema为单位。
NoSQL数据库伸缩:
很多NoSQL数据库设计时已经具有良好的伸缩性。
数据库扩展:
- 按业务功能不同分库 Database Federation
- Hard to cross query
- 数据库分片把同一数据集分到不同的数据库里 Database Sharding
- More complex in APP layer
- No limit on scalability
- Operation complexity/sophistication
- RDBMS or NoSQL
- 把一些数据移动到NoSQL数据库或者Graph数据库
六:网站的高扩展性架构
扩展性(Extensibility):指对现有系统影响最小的情况下,系统功能可持续扩展或提升的能力。表现在基础设施稳定不需要变更,应用之间较少依赖和耦合,对需求变更能敏捷响应。它是设计模式里的“开闭原则”。
伸缩性(Scalability):指系统能够通过增加(减少)自身资源规模的方式增强(减少)自己计算处理事务的能力。如果这种增减是成比例的,就叫做线性伸缩性。
1,利用分布式消息队列降低系统耦合性
2,利用分布式服务打造可复用的业务平台
一个巨无霸单体应用服务会给开发,维护,部署带来巨大的成本和麻烦。解决方案就是拆分,将模块独立部署,降低系统耦合性。拆分可以分为:
- 横向拆分:将复用的业务拆出来,独立部署为分布式服务,新增业务只用调用这些分布式服务,不需要依赖具体的模块代码,即可迅速搭建一个应用系统,而模块内业务逻辑变化时,只要对外接口不变就不会影响外部应用。
- 纵向拆分:通过梳理业务,将相关较少的业务剥离,成为独立的web应用。
3,可扩展的数据结构
七:网站的安全架构