【读书笔记】大型网站技术架构:核心原理与案例分析

众多阿里人强烈推荐的,书也的确是本好书,实战也很厉害,书里的很多详细的例子都是作者多年的经验总结的,建议多看几遍。

第一章,大型网站架构演化

  1. 使用缓存改善网站性能。本地和远程分布式缓存,前者快但是会跟应用争夺资源。

  2. 使用应用服务器集群改善网站的并发处理能力。是网站可伸缩集群架构设计中比较成熟的一种。

  3. 数据库读写分离,提供主从热备功能,一台专门写,另外一台读,实时同步数据。

  4. 使用反向代理和CDN加速网站响应,都是缓存。区别在于CDN部署在网络提供商的机房,使用户在请求网站服务时,可以从距离自己最近的网络提供商机房获取数据;而反向代理则部署在网站的中心机房,当用户请求到达中心机房后,首先访问的服务器是反向代理服务器,如果反向代理服务器中缓存着用户请求的资源,就将其直接返回给用户。

  5. 分布式数据库是网站数据库拆分的最后手段,只有在单表数据规模非常庞大的时候才使用。不到不得已时,网站更常用的数据库拆分手段是业务分库,将不同业务的数据库部署在不同的物理服务器上。

  6. 使用NoSQL和搜索引擎

  7. 技术不能解决所有的问题,不能凡事生搬硬套互联网思维。技术是为业务服务的,很多问题比如12306用抢票的形式卖票,把压力放在技术端是不正确的,应该从业务角度考虑问题,技术只是一个工具,而不应该万能的。

第二章,大型网站架构模式

  1. 不仅仅便于开发维护,对高并发也有很大的益处。因此在网站规模还很小的时候就应该采用分层的架构,这样将来网站做大时才能有更好地应对。

  2. 分层是横向的切分,分割是纵向的,是指业务的分割,比如购物,论坛,等可以分为不同的团队维护。

  3. 两者都是为了更好的分布式服务,但是分布式牺牲了部分性能,还有一台宕机就不可用,那么不能一味为了分布式而分布式。

  4. 分布式方式有以下几种,分开部署,静态资源独立域名动静分离(由用户体验团队做这个维护),分布式数据库和nosql,hadoop等分布式计算。此外,还有可以支持网站线上服务器配置实时更新的分布式配置;分布式环境下实现并发和协同的分布式锁;支持云存储的分布式文件系统等。

  5. 集群,即使是访问量很小的分布式应用和服务,也至少要部署两台服务器构成一个小的集群,目的就是提高系统的可用性。

  6. 缓存,cdn,反向代理,本地缓存,分布式缓存。

  7. 异步,提高可用性,加快访问速度,消除并发的访问高峰。异步可能会对体验不太好,需要产品的支持。

  8. 冗余。数据库主从,冷备份➕热备份。大型事故对数据中心进行灾备。

  9. 自动化。自动代码管理,测试,安全检测,部署,监控,报警,失效转移关闭,自动恢复重启,自动化降级(就是对不合理的访问不重要的服务进行关闭,阻止访问等。将负载维持在正常的水平)

  10. 安全。加密,检验,阻止攻击,风险控制。

 

第三章,大型网站核心架构要素

  1. 除了当前的系统功能需求外,软件架构还需要关注性能、可用性、伸缩性、扩展性和安全性这5个架构要素,架构设计过程中需要平衡这5个要素之间的关系以实现需求和架构目标。

  2. 性能:在浏览器端,可以通过浏览器缓存、使用页面压缩、合理布局页面、减少Cookie传输等手段改善性能。还有cdn。其他见第二章。

  3. 可用性。几万台服务器总会有宕机的,那么如何高可用呢,答案是冗余,多台服务器数据备份。还有集群可以很快切换到其他服务器处理,但是一个前提条件是应用服务器上不能保存请求的会话信息。否则服务器宕机,会话丢失,即使将用户请求转发到其他也不行。除了运行环境,网站的高可用还需要软件开发过程的质量保证。通过预发布验证、自动化测试、自动化发布、灰度发布等手段,减少将故障引入线上环境的可能,避免故障范围扩大。

  4. 伸缩性。所谓伸缩性是指通过不断向集群中加入服务器的手段来缓解不断上升的用户并发访问压力和不断增长的数据存储需求。应用服务器,只要不保存数据,加入新的很容易,用合适的负载均衡就可以。对于缓存服务器集群,如果应用严重依赖缓存,那么增加新的服务器可能网站崩溃,需要改进缓存路由算法。关系型数据库很难做到大规模集群的可伸缩性,因此关系数据库的集群伸缩性方案必须在数据库之外实现。通过路由分区等手段将部署有多个数据库的服务器组成一个集群。至于nosql天生为海量而生,较少运维参与的情况下实现集群规模的线性伸缩。

  5. 扩展性。主要手段是事件驱动架构和分布式服务。前者通过消息队列实现业务需求,后者则依赖于高可用可复用的模块。

 

第二篇,架构

第四章,瞬时响应,网站的高性能架构

  1. 吞吐量,类似高速的收费个数,车速快车子少吞吐量小,车子变多车速变慢,吞吐量是一个很快变大的过程,随着越来越多的车子,堵车了,收费反而少了,最终如果继续增加,瘫痪了,没费可收了。系统崩溃。

  2. 性能计数器。它是描述服务器或操作系统性能的一些数据指标。包括System Load、对象与线程数、内存使用、CPU使用、磁盘与网络I/O等指标。

  3. 性能测试是一个总称,具体可细分为性能测试、负载测试、压力测试、稳定性测试。

  4. Web前端性能优化,浏览器加载、网站视图模型、图片服务、CDN服务等,主要优化手段有优化浏览器访问、使用反向代理、CDN等。一,浏览器访问优化,减少http请求(减少HTTP的主要手段是合并CSS、合并JavaScript、合并图片),浏览器缓存(更新时不要同时更新),压缩比如gzip,但是会对服务器和浏览器有压力,要权衡。css放在最上面,js最下面。减少 cookie传输。二,cdn加速。就是物理距离最近的一个运营商缓存。三,反向代理。除了安全功能,代理服务器也可以通过配置缓存功能加速Web请求。

  5. 应用服务器性能优化。一,分布式缓存。二八定律,不可以滥用,至少修改至少被读过至少两次。缓存雪崩,就是缓存不可用的时候,数据库也承受不了那么大的压力,重启也恢复不了。有的网站用热备来解决,但是违背了初衷,缓存本来就不是一个可靠的数据源。分布式缓存服务器集群,将缓存数据分布到集群多台服务器上可在一定程度上改善缓存的可用性。只要部分数据重新从数据库获取就行了。缓存预热,就是预加载。缓存穿透,对恶意访问不存在的数据这种,也可以放到缓存,减少数据库的压力,只不过是null罢了。

  6. 嗯Memcached采用一种集中式的缓存集群管理,也被称作互不通信的分布式架构方式。缓存与应用分离部署,缓存系统部署在一组专门的服务器上,通过路由算法访问数据,伸缩性也很好。虽然近些年许多NoSQL产品层出不穷,在数据持久化、支持复杂数据结构、甚至性能方面有许多产品优于Memcached,但Memcached由于其简单、稳定、专注的特点,仍然在分布式缓存领域占据着重要地位。

  7. 集群啊,异步啊,都是手段,代码优化包括以下几点:多线程(注意线程安全,比如锁,比如使用局部对象被别人访问到),资源复用(减少开销很大的资源的创建和销毁,使用线程池),数据结构啊,比如hash,垃圾回收

  8. 存储性能优化:b+树,lsm树,HDFS配合MapReduce等并行计算框架进行大数据处理时,可以在整个集群上并发读写访问所有的磁盘,无需RAID支持。raid用于关系型数据库和文件系统,上面那个用于非关系型和分布式文件系统。

  9. 总结:想要解决高并发的问题,肯定会导致低并发的时候有一定性能的影响。用户体验的快或是慢,可以通过技术手段改善,也可以通过优化交互体验改善。

 

第五章,万无一失,网站的高可用架构

  1. 网站可用性度量,四个9比如qq,是一年不可用时间不得超过53分钟,太苛刻了,twitter不超过两个9。三个9较高可用,九个小时。

  2. 实现高可用架构的主要手段是数据和服务的冗余备份及失效转移。

  3. 高可用的应用:负载均衡有一定的缺点,不能管理好session,有没有可用性高、伸缩性好、性能也不错,对信息大小又没有限制的服务器集群Session管理方案呢,session服务器。分为无状态的应用服务器和有状态的Session服务器

  4. 高可用的服务:服务器分级,重要的模块用好的处理快的服务器,超时设置,异步调用,服务降级(拒绝服务,按照优先级,twitter采用随机的方式,刷新下就好了,挺逗的。或者关闭服务,比如双十一,关闭评论啊,查询订单等功能),幂等性(必须在服务层保证服务重复调用和调用一次产生的结果相同,即服务具有幂等性。)此处不懂。

  5. 高可用的数据。大型网站一定程度牺牲数据一致性,保证可用性和伸缩性。

  6. 高可用软件质量保证。自动化测试,预发布验证(但是因为是真实db所以数据可能会有问题,比如用一块钱测试结果大量用户也用这个来购买),版本发布(Git是迟早的事),自动化发布(火车模型),灰度发布(每次发布一部分服务器,有问题只回滚这部分服务器就行:也可以用于测试,相当于ab两个版本共同运行,可以做数据对比)。

  7. 网站运行监控:采集(日志等),服务器性能监控(Ganglia工具,有曲线图),运行数据报告(平均响应延迟时间,缓存命中率,要在具体的业务场景下写程序收集),监控管理(风险预警,设置报警阈值,不要在服务器宕机才发现),失效转移,功能降级(活动时关闭非核心功能,能做到自动更好)

 

第六章,永无止境,网站的可伸缩架构

  1. 伸缩有两种,一种不同功能物理分离实现。比如流程上的不同部分,数据库啊,缓存啊,基础技术啊,可复用业务啊,这是纵向。还有横向,比如前台系统,财务系统,订单系统等。

  2. 第二种,单一功能通过集群规模实现伸缩。又可分为应用服务器集群伸缩性和数据服务器集群伸缩性。后者又分为缓存和存储。

  3. 应用服务器的集群设计:负载均衡能够识别新加入的和下线的服务器,进行正确的分发。一,HTTP重定向负载均衡,优点是比较简单。缺点是浏览器需要两次请求服务器才能完成一次访问,性能较差;一般使用较少。二,dns域名解析负载均衡,也有缺点,更改生效太慢,而且控制权在域名服务商。大型网站总是部分使用DNS域名解析,利用域名解析作为第一级负载均衡手段。三,反向代理负载均衡。四,ip,五,数据链路层。

  4. 负载均衡算法:轮询,加权轮询,随机,最少连接,源地址散列。

  5. 分布式缓存集群的伸缩性设计:一,Memcached,如果不需要考虑缓存服务器集群伸缩性,余数Hash几乎可以满足绝大多数的缓存路由需求。目前比较流行的算法是一致性Hash算法。命中率随着基数越大,越高。

  6. 数据存储服务器集群的伸缩性设计。一,关系型数据库,除了读写分离(就是分主从),分库(不同业务模块放在不同的库),还有分片就是cobar,Cobar的伸缩有两种:Cobar服务器集群的伸缩和MySQL服务器集群的伸缩。二,NoSQL数据库的伸缩性设计。HBase为可伸缩海量数据储存而设计,实现面向在线业务的实时数据访问延迟。

  7. 伸缩性设计又是复杂的,没有通用的、完美的解决方案和产品,网站伸缩性往往和可用性、正确性、性能等耦合在一起。

 

第七章,随需应变:网站的可扩展架构

  1. 分布式消息队列:事件驱动架构(Event Driven Architecture):通过在低耦合的模块之间传输事件消息,以保持模块的松散耦合,并借助事件消息的通信完成模块间合作。比较著名的如Apache ActiveMQ等,

  2. 利用分布式服务打造可复用的业务平台。目前国内有较多成功实施案例的开源分布式服务框架是阿里巴巴的Dubbo。配置负载均衡,可以自动失效,较高的网络通信性能。

  3. 可扩展的数据结构:有没有办法能够做到可扩展的数据结构设计呢?无需修改表结构就可以新增字段呢?许多NoSQL数据库使用的ColumnFamily(列族)设计就是一个解决方案。

 

第八章, 固若金汤:网站的安全架构

  1. Xss攻击,sql注入啊,crf啊等等

  2. 信息加密技术可分为三类:单项散列加密(Md5啊,sha啊,用来生成信息摘要)、对称加密(是加解密使用同一个密钥,远程通信的情况下如何安全的交换密钥是个难题,如果密钥丢失,那么所有的加密信息也就没有秘密可言了。)和非对称加密(通常用在信息安全传输,数字签名等场合。)

  3. 在实际应用中,常常会混合使用对称加密和非对称加密。先使用非对称加密技术对对称密钥进行安全传输,然后使用对称加密技术进行信息加解密与交换。而有时,对同一个数据两次使用非对称加密,可同时实现信息安全传输与数字签名的目的。

  4. 密钥安全管理:一种方案是把密钥和算法放在一个独立的服务器上,成本大,传输性能消耗。另一种,方法在应用,密钥则放在独立服务器中,切片,加密后分别保存在不同存储介质中。多个服务器中,密钥申请者、密钥管理者、安全审核人员通过密钥管理控制台管理更新密钥,每个人各司其事,没有人能查看完整的密钥信息。

  5. 信息过滤与反垃圾。敏感词汇识别,文本匹配,一,简单的正则表达式,二,空间和时间复杂度都比较好的有双数组Trie算法等。另一种更简单的实现是通过构造多级Hash表进行文本匹配。还有降噪,比如多余的符号等

  6. 垃圾文件识别,用分类算法,贝叶斯等,这种算法还可以进行文本分类。

  7. 电子商务风险控制。机器自动风控,比如规则引擎,统计模型,比如机器学习算法。

 

第三篇,案例

第九章,淘宝网的架构演化案例分析

  1. 维基百科,查询量大,第一层cdn服务器缓存,距离用户最近,快去返回。其次squid服务器缓存,无需到达后端apache。这两点是前端性能优化。后端呢?后端优化最主要的手段是使用缓存,将热点数据缓存在分布式缓存系统的内存中,加速应用服务器的数据读操作速度,减轻存储和数据库服务器的负载

  2. Doris,海量分布式存储系统。跟主流的NoSQL系统HBase相比(Doris0.1 vs.HBase0.90),Doris具有相似的性能和线性伸缩能力,并具有更好的可用性及更友好的图形用户管理界面。存储集群,备份数据可以细分子集群内备份即可。一般而言,服务器之间通信越少,就越少依赖,发生故障时互相影响就越少,集群的可用性就越高。

  3. 网购秒杀系统架构设计。秒杀系统最好独立部署,比如独立域名等,不要影响正常的系统。页面静态化,不用查询数据库和后端。将秒杀商品页面缓存在CDN,同样需要和CDN服务商临时租借新增的出口带宽。这个厉害了,动态生成随机下单页面URL,秒杀开始的时候才能得到真正的下单页面,不会提前透露。下单尽量简单,地址可以不填,按照提交订单为准,地址可以修改。怎么控制按钮的显示,前端处理,当秒杀开始的时候生成一个新的JavaScript文件并被用户浏览器加载,控制秒杀商品页面的展示。如何控制只有一个订单提交,减少多次压力,只有少数用户能进入下单页面,其他用户直接进入秒杀结束页面。

  4. 大型网站典型故障案例分析:一,写日志也会引发故障,日志输出级别至少为Warn,并且检查log输出代码调用,调用级别要符合其真实日志级别。有些开原第三方也会不恰当输出error日志。

  5. 二,高并发访问数据库引发的故障。首页频繁调用一个sql,即使有索引。首页应该是静态的,用缓存之类。

  6. 三,高并发情况下锁引发的故障。锁一般是简单操作,获得锁,迅速处理后释放。比较长的操作不可用锁,即使访问频率低,万一哪天访问量上去了呢。

  7. 四,缓存引发的故障。一般来说,缓存地位比较低,也疏于管理和关注。如果缓存已经成为系统必不可少的一部分,比如分布式缓存,那么就要提高缓存的管理级别。不过现如今缓存都是比较重要的一部分了。

  8. 五,应用启动不同步引发的故障。启动先后顺序需要关注,最好有启动成功日志,便于下一个应用知道并处理。

  9. 六,大文件读写独占磁盘引发的故障。图片这种小文件和大文件几百m的那种分开处理,比如单独的分布式文件系统。

  10. 七,滥用生产环境引发的故障。很好理解,生产环境的处理都要慎重,开后门或者压力测试都要谨慎又谨慎,多次审核评审等。

  11. 八,不规范的流程引发的故障。随意注释代码,都需要经过测试。还有代码评审,要到位。

  12. 九,不好的编程习惯引发的故障。空指针,居然唯一的被点名的代码,说明太多人吃过亏了,并且持续不断吃亏中,注意啊。空判断的逻辑。

 

第四篇,架构师

第14章,架构师领导艺术

  1. 跟别人讨论事情的时候,要求同存异,不要一味证明自己是正确的,目的是把事情做好,让别人理解自己,也去理解别人。

  2. 我们活着不是为了工作,不是为了做设计、写程序,这些不是我们生活的目的。我们活着是为了成就我们自己,而要想成就自己,就必须首先成就他人。

  3. 推动一件事,遇到问题大家下意识躲避。一,把“我的问题”表述成“我们的问题”。二,给上司提封闭式问题,给下属提开放式问题。上司问,a和b哪个更好,下属,就是你怎么看。三,指出问题而不是批评人。四,我非常赞同你的方案,不过我有一个小小的建议……”

  4. 解决问题。1.在解决我的问题之前,先解决你的问题。解决了之后可以再塞点自己的东西。

 

你可能感兴趣的:(架构)