Skip to content

Latest commit

 

History

History
467 lines (236 loc) · 35.4 KB

大型网站技术架构.md

File metadata and controls

467 lines (236 loc) · 35.4 KB

大型网站技术架构

李智慧 - 教育学习榜-教育

本书通过梳理大型网站技术发展历程,剖析大型网站技术架构模式,深入讲述大型互联网架构设计的核心原理,并通过一组典型网站技术架构设计案例,为读者呈现一幅包括技术选型、架构设计、性能优化、Web安全、系统发布、运维监控等在内的大型网站开发全景视图。

好评袭来

本书从网站的架构设计、快速开发、高效部署、业务监控、服务治理、运维管理等多个角度描述了架构设计的相关重点,涉及的核心技术包括前端优化、CDN、反向代理、缓存、消息队列、分布式存储、分布式服务、NoSQL存储、搜索、监控、安全等一系列保证大型网站安全可靠运行的关键技术点。 c:149

推荐序一

传统的企业应用系统主要面对的技术挑战是处理复杂凌乱、千变万化的所谓业务逻辑,而大型网站主要面对的技术挑战是处理超大量的用户访问和海量的数据处理;前者的挑战来自功能性需求,后者的挑战来自非功能性需求;功能性需求也许还有“人月神话”聊以自慰,通过增加人手解决问题,而非功能需求大多是实实在在的技术难题,无论有多少工程师,做不到就是做不到。 c:162

所以很多人就很困惑:为什么很多看起来不是很复杂的网站,比如Facebook、淘宝,都需要大量顶尖高手来开发呢? c:30

宏观层面上,将网站架构的演化发展、架构模式、核心要素一一道来;微观层面上,将网站架构常用的分布式缓存、负载均衡、消息队列、分布式服务、甚至网站如何发布运维都逐一进行了阐述。 c:128

推荐序二

好的设计绝对不是模仿、不是生搬硬套某个模式,而是在对问题深刻理解之上的创造与创新,即使是‘微创新’,也是让人耳目一新的似曾相识。山寨与创新的最大区别不在于是否抄袭、是否模仿,而在于对问题和需求是否真正理解与把握。 c:264

性能、可用性、伸缩性、扩展性、安全性几个网站核心架构要素 c:119

序我为什么要写这本书

作为一个爱买书胜过爱读书的人 c:23

,预感到京东的服务器可能因为并发访问量过高,超过了系统的最大负载能力, c:27

能够正常访问购物车,却不能成功购买,问题应该是出在订单系统,B2C网站生成一个订单需要经历扣减库存、扣减促销资源、更新用户账户等一系列操作,这些操作大多是数据库事务操作,没有办法通过缓存等手段来减轻数据库服务器负载压力,如果事前没有设计好数据库伸缩性架构,那么京东的技术团队将遇到一个大麻烦。 c:182

12306作为一个运营不久的网站,缺乏大规模并发访问处理的经验,遇到一些问题其实不奇怪,不管花多少钱,经验教训都需要经历时间和挫折才能得到 c:55

希望软件工程师们在解决问题之前,能够认真思考自己面对的真正问题究竟是什么,有哪些技术方案可以选择,其基本原理是什么。 c:143

真正能解决问题的技术一定是简单的。 c:192

软件架构设计中常用的4+1视图模型,也是一种多角度描述软件系统设计的手段。 c:213

第1篇 概述

如何打造一个高可用、高性能、易扩展、可伸缩且安全的网站? c:166

1.1 大型网站软件系统的特点

好的互联网产品都是慢慢运营出来的,不是一开始就开发好的,这也正好与网站架构的发展演化过程对应。 c:151

1.2 大型网站架构演化发展历程

应用服务器需要处理大量的业务逻辑,因此需要更快更强大的CPU;数据库服务器需要快速磁盘检索和数据缓存,因此需要更快的硬盘和更大的内存;文件服务器需要存储大量用户上传的文件,因此需要更大的硬盘。 c:351

应用服务器则通过一个统一数据访问模块访问各种数据,减轻应用程序管理诸多数据源的麻烦。 c:78

既然每一个应用系统都需要执行许多相同的业务操作,比如用户管理、商品管理等,那么可以将这些共用的业务提取出来,独立部署。由这些可复用的业务连接数据库,提供共用业务服务,而应用系统只需要管理用户界面,通过分布式服务调用共用业务服务完成具体业务操作 c:77

1.3 大型网站架构演化的价值观

网站的价值在于它能为用户提供什么价值,在于网站能做什么,而不在于它是怎么做的,所以在网站还很小的时候就去追求网站的架构是舍本逐末,得不偿失的。小型网站最需要做的就是为用户提供好的服务来创造价值,得到用户的认可,活下去,野蛮生长。 c:302

1.4 网站架构设计误区

技术是用来解决业务问题的,而业务的问题,也可以通过业务的手段去解决。 c:302

1.5 小结

救世主定律:遇到问题,分析问题,最后总能解决问题。如果遇到问题就急匆匆地从外面挖一个高手,然后指望高手如探囊取物般轻松搞定,最后怕是只有彼此抱怨和伤害。许多问题只是看起来一样,具体问题总是要具体对待的,没有银弹,没有救世主。所以这个定律准确地说应该是“没有救世主定律”。 c:59

有些传统企业将自己的管理模式和经营理念也照搬到互联网领域——在技术方面的表现就是一开始就企图打造一个大型网站。 c:30

2 大型网站架构模式

每一个模式描述了一个在我们周围不断重复发生的问题及该问题解决方案的核心。这样,你就能一次又一次地使用该方案而不必做重复工作 c:339

2.1 网站架构模式

分层是企业应用系统中最常见的一种架构模式,将系统在横向维度上切分成几个部分,每个部分负责一部分相对比较单一的职责,然后通过上层对下层的依赖和调用组成一个完整的系统。 c:169

比较简单实用的分类算法有贝叶斯分类算法,这是一种利用概率统计方法进行分类的算法。 c:39

2.2 架构模式在新浪微博的应用

在新浪微博的早期架构中,微博发布使用同步推模式,用户发表微博后系统会立即将这条微博插入到数据库所有粉丝的订阅列表中,当用户量比较大时,特别是明星用户发布微博时,会引起大量的数据库写操作,超出数据库负载,系统性能急剧下降,用户响应延迟加剧。后来新浪微博改用异步推拉结合的模式,用户发表微博后系统将微博写入消息队列后立即返回,用户响应迅速,消息队列消费者任务将微博推送给所有当前在线粉丝的订阅列表中,非在线用户登录后再根据关注列表拉取微博订阅列表。 c:176

由于微博频繁刷新,新浪微博使用多级缓存策略,热门微博和明星用户的微博缓存在所有的微博服务器上,在线用户的微博和近期微博缓存在分布式缓存集群中,对于微博操作中最常见的“刷微博”操作,几乎全部都是缓存访问操作,可以获得很好的系统性能。 c:99

2.3 小结

山寨与创新的最大区别不在于是否抄袭,是否模仿,而在于对问题和需求是否真正理解与把握。 c:117

3 大型网站核心架构要素

一般说来,除了当前的系统功能需求外,软件架构还需要关注性能、可用性、伸缩性、扩展性和安全性这5个架构要素 c:386

3.2 可用性

网站高可用的主要手段是冗余,应用部署在多台服务器上同时提供访问,数据存储在多台服务器上互相备份,任何一台服务器宕机都不会影响应用的整体可用,也不会导致数据丢失。 c:213

3.4 扩展性

网站可伸缩架构的主要手段是事件驱动架构和分布式服务。 c:192

3.5 安全性

衡量网站安全架构的标准就是针对现存和潜在的各种攻击与窃密手段,是否有可靠的应对策略。 c:58

3.6 小结

性能、可用性、伸缩性、扩展性和安全性是网站架构最核心的几个要素,这几个问题解决了,大型网站架构设计的大部分挑战也就克服了。 c:118

第2篇 架构

网站性能是客观的指标,可以具体体现到响应时间、吞吐量等技术指标,同时也是主观的感受,而感受则是一种与具体参与者相关的微妙的东西,用户的感受和工程师的感受不同,不同的用户感受也不同。 c:163

4.1 网站性能测试

从用户角度,网站性能就是用户在浏览器上直观感受到的网站响应速度快还是慢 c:129

在实践中,使用一些前端架构优化手段,通过优化页面HTML式样、利用浏览器端的并发和异步特性、调整浏览器缓存策略、使用CDN服务、反向代理等手段,使浏览器尽快地显示用户感兴趣的内容、尽可能近地获取页面内容,即使不优化应用程序和架构,也可以很大程度地改善用户视角下的网站性能。 c:78

包括响应延迟、系统吞吐量、并发处理能力、系统稳定性等技术指标。主要的优化手段有使用缓存加速数据读取,使用集群提高吞吐能力,使用异步消息加快请求响应及实现削峰,使用代码优化手段改善程序性能。 c:128

测试一万次执行需要的总响应时间之和,然后除以一万,得到单次请求的响应时间。 c:49

TPS(每秒事务数)是吞吐量的一个常用量化指标,此外还有HPS(每秒HTTP请求数)、QPS(每秒查询数)等。 c:286

系统吞吐量和系统并发数,以及响应时间的关系可以形象地理解为高速公路的通行状况:吞吐量是每天通过收费站的车辆数目(可以换算成收费站收取的高速费),并发数是高速公路上的正在行驶的车辆数目,响应时间是车速。车辆很少时,车速很快,但是收到的高速费也相应较少;随着高速公路上车辆数目的增多,车速略受影响,但是收到的高速费增加很快;随着车辆的继续增加,车速变得越来越慢,高速公路越来越堵,收费不增反降;如果车流量继续增加,超过某个极限后,任何偶然因素都会导致高速全部瘫痪,车走不动,费当然也收不着,而高速公路成了停车场(资源耗尽)。 c:65

检查请求处理的各个环节的日志,分析哪个环节响应时间不合理、超过预期;然后检查监控数据,分析影响性能的主要因素是内存、磁盘、网络、还是CPU,是代码问题还是架构设计不合理,或者系统资源确实不足。 c:103

4.2 Web前端性能优化

通过设置HTTP头中Cache-Control和Expires的属性,可设定浏览器缓存,缓存时间可以是数天,甚至是几个月。 c:241

传统代理服务器位于浏览器一侧,代理浏览器将HTTP请求发送到互联网上,而反向代理服务器位于网站机房一侧,代理网站Web服务器接收HTTP请求。 c:48

当这些动态内容有变化时,通过内部通知机制通知反向代理缓存失效,反向代理会重新加载最新的动态内容再次缓存起来。 c:63

4.3 应用服务器性能优化

缓存的本质是一个内存Hash表,网站应用中,数据缓存以一对Key、Value的形式存储在内存Hash表中。Hash表数据读写的时间复杂度为O(1) c:64

一般说来,数据的读写比在2:1以上,即写入一次缓存,在数据更新前至少读取两次,缓存才有意义。 c:138

实践中,有的网站通过缓存热备等手段提高缓存可用性:当某台缓存服务器宕机时,将缓存访问切换到热备服务器上。但是这种设计显然有违缓存的初衷,缓存根本就不应该被当做一个可靠的数据源来使用。 c:54

如果因为不恰当的业务、或者恶意攻击持续高并发地请求某个不存在的数据,由于缓存没有保存该数据,所有的请求都会落到数据库上,会对数据库造成很大压力,甚至崩溃。一个简单的对策是将不存在的数据也缓存起来(其value值为null)。 c:116

分布式缓存指缓存部署在多个服务器组成的集群中,以集群方式提供缓存服务,其架构方式有两种,一种是以JBoss Cache为代表的需要更新同步的分布式缓存,一种是以Memcached为代表的不互相通信的分布式缓存。 c:73

Memcached采用一种集中式的缓存集群管理,也被称作互不通信的分布式架构方式。缓存与应用分离部署,缓存系统部署在一组专门的服务器上,应用程序通过一致性Hash等路由算法选择缓存服务器远程访问缓存数据,缓存服务器之间不通信,缓存集群的规模可以很容易地实现扩容,具有良好的可伸缩性。 c:92

数据只能存入一个比它大的chunk里,而一个chunk只能存一个数据,其他空间被浪费了 c:22

使用消息队列将调用异步化,可改善网站的扩展性 c:52

消息队列具有很好的削峰作用——即通过异步处理,将短时间高并发产生的事务消息存储在消息队列中,从而削平高峰期的并发事务。 c:88

任何可以晚点做的事情都应该晚点再做。 c:104

启动线程数=[任务执行时间/(任务执行时间-IO等待时间)]×CPU内核数 c:303

从编程角度,资源复用主要有两种模式:单例(Singleton)和对象池(Object Pool)。 c:130

一个可行的方案是对字符串取信息指纹,再对信息指纹求HashCode,由于字符串微小的变化就可以引起信息指纹的巨大不同,因此可以获得较好的随机散列 c:61

4.4 存储性能优化

为了改善数据访问特性,文件系统或数据库系统通常会对数据排序后存储,加快数据检索速度,这就需要保证数据在不断更新、插入、删除后依然有序,传统关系数据库的做法是使用B+树 c:127

B+树是一种专门针对磁盘存储而优化的N叉排序树,以树节点为单位存储在磁盘中,从根开始查找所需数据所在的节点编号和磁盘位置,将其加载到内存中然后继续查找,直到找到所需的数据。 c:59

应用程序(Client)需要写文件时,首先访问NameNode,请求分配数据块,NameNode根据管理的DataNode服务器的磁盘空间,按照一定的负载均衡策略,分配若干数据块供Client使用。 c:27

4.5 小结

归根结底,技术是为业务服务的,技术选型和架构决策依赖业务规划乃至企业战略规划,离开业务发展的支撑和驱动,技术走不远,甚至还会迷路。 c:175

5.1 网站可用性的度量与考核

对于大多数网站而言,2个9是基本可用,网站年度不可用时间小于88小时;3个9是较高可用,网站年度不可用时间小于9小时;4个9是具有自动恢复能力的高可用,网站年度不可用时间小于53分钟;5个9是极高可用性,网站年度不可用时间小于5分钟。 c:67

5.3 高可用的应用

所谓无状态的应用是指应用服务器不保存业务的上下文信息,而仅根据每次请求提交的数据进行相应的业务逻辑处理,多个服务实例(服务器)之间完全对等,请求提交到任意服务器,处理结果都是完全一样的。 c:204

集群环境下,Session管理主要有以下几种手段。 c:42

利用独立部署的Session服务器(集群)统一管理Session,应用服务器每次读写Session时,都访问Session服务器 c:63

这种解决方案事实上是将应用服务器的状态分离,分为无状态的应用服务器和有状态的Session服务器,然后针对这两种服务器的不同特性分别设计其架构。 c:68

5.4 高可用的服务

为了保证核心应用和功能的正常运行,需要对服务进行降级。降级有两种手段:拒绝服务及关闭服务。 c:90

因此必须在服务层保证服务重复调用和调用一次产生的结果相同,即服务具有幂等性。 c:89

5.5 高可用的数据

保证数据存储高可用的手段主要是数据备份和失效转移机制 c:81

CAP原理认为,一个提供数据服务的存储系统无法同时满足数据一致性(Consistency)、数据可用性(Availibility)、分区耐受性(PatitionTolerance,系统具有跨网络分区的伸缩性)这三个条件 c:89

CAP原理认为,一个提供数据服务的存储系统无法同时满足数据一致性(Consistency)、数据可用性(Availibility)、分区耐受性(Patition Tolerance,系统具有跨网络分区的伸缩性)这三个条件 c:144

数据热备可分为两种:异步热备方式和同步热备方式。 c:97

关系数据库热备机制就是通常所说的Master-Slave同步机制。Master-Slave机制不但解决了数据备份问题,还改善了数据库系统的性能,实践中,通常使用读写分离的方法访问Slave和Master数据库,写操作只访问Master数据库,读操作只访问Slave数据库。 c:95

失效转移操作由三部分组成:失效确认、访问转移、数据恢复。 c:102

系统确认一台服务器是否宕机的手段有两种:心跳检测和应用程序访问失败报告 c:99

对于应用程序的访问失败报告,控制中心还需要再一次发送心跳检测进行确认,以免错误判断服务器宕机 c:36

5.6 高可用网站的软件质量保证

比较流行的Web自动化测试工具是ThoughtWorks开发的Selenium。Selenium运行在浏览器中,模拟用户操作进行测试,因此Selenium可以同时完成Web功能测试和浏览器兼容测试。 c:151

在网站应用中强调的一个处理错误的理念是快速失败(fast failed),即如果系统在启动时发现问题就立刻抛出异常,停止启动让工程师介入排查错误,而不是启动后执行错误的操作。 c:96

目前网站应用开发中主要使用的是分支开发、主干发布的方式 c:53

其继任者提出了一个火车发布模型:将每个应用的发布过程看作一次火车旅程,火车定点运行,期间有若干站点,每一站都进行例行检查,不通过的项目下车,剩下的项目继续坐着火车旅行,直到火车到达终点(应用发布成功)。 c:24

5.7 网站运行监控

目前网站使用比较广泛的开源性能监控工具是Ganglia c:178

优雅降级是指网站为了应付突然爆发的访问高峰,主动关闭部分功能,释放部分系统资源,保证网站核心功能正常访问的一个手段。 c:65

6 永无止境:网站的伸缩性架构

所谓网站的伸缩性是指不需要改变网站的软硬件设计,仅仅通过改变部署的服务器数量就可以扩大或者缩小网站的服务处理能力。 c:150

6.1 网站架构的伸缩性设计

一般说来,网站的伸缩性设计可分成两类,一类是根据功能进行物理分离实现伸缩,一类是单一功能通过集群实现伸缩。前者是不同的服务器部署不同的服务,提供不同的功能;后者是集群内的多台服务器部署相同的服务,提供相同的功能。 c:229

横向分离(业务分割后分离):将不同的业务模块分离部署,实现系统伸缩性 c:38

当一头牛拉不动车的时候,不要去寻找一头更强壮的牛,而是用两头牛来拉车。 c:49

集群伸缩性又可分为应用服务器集群伸缩性和数据服务器集群伸缩性。 c:106

6.2 应用服务器集群的伸缩性设计

负载均衡是网站必不可少的基础技术手段,不但可以实现网站的伸缩性,同时还改善网站的可用性,可谓网站的杀手锏之一。 c:32

大型网站总是部分使用DNS域名解析,利用域名解析作为第一级负载均衡手段,即域名解析得到的一组服务器并不是实际提供Web服务的物理服务器,而是同样提供负载均衡服务的内部服务器,这组内部负载均衡服务器再进行负载均衡,将请求分发到真实的Web服务器上。 c:80

6.3 分布式缓存集群的伸缩性设计

和所有服务器都部署相同应用的应用服务器集群不同,分布式缓存服务器集群中不同服务器中缓存的数据各不相同,缓存访问请求不可以在缓存服务器集群中的任意一台处理,必须先找到缓存有需要数据的服务器,然后才能访问。这个特点会严重制约分布式缓存集群的伸缩性设计 c:66

必须让新上线的缓存服务器对整个分布式缓存集群影响最小,也就是说新加入缓存服务器后应使整个缓存服务器集群中已经缓存的数据尽可能还被访问到,这是分布式缓存集群伸缩性设计的最主要目标。 c:78

简单的路由算法可以使用余数Hash:用服务器数目除以缓存数据KEY的Hash值,余数为服务器列表下标编号。 c:23

一种解决办法是在网站访问量最少的时候扩容缓存服务器集群,这时候对数据库的负载冲击最小。然后通过模拟请求的方法逐渐预热缓存,使缓存服务器中的数据重新分布。但是这种方案对业务场景有要求,还需要技术团队通宵加班(网站访问低谷通常是在半夜)。 c:49

一致性Hash算法通过一个叫作一致性Hash环的数据结构实现KEY到缓存服务器的Hash映射 c:43

具体应用中,这个长度为232的一致性Hash环通常使用二叉查找树实现,Hash查找过程实际上是在二叉查找树中查找不小于查找数的最小数值。当然这个二叉树的最右边叶子节点和最左边的叶子节点相连接,构成环。 c:32

计算机的任何问题都可以通过增加一个虚拟层来解决。 c:132

那么在实践中,一台物理服务器虚拟为多少个虚拟服务器节点合适呢?太多会影响性能,太少又会导致负载不均衡,一般说来,经验值是150,当然根据集群规模和负载均衡的精度需求,这个值应该根据具体情况具体对待。 c:57

6.4 数据存储服务器集群的伸缩性设计

数据存储服务器必须保证数据的可靠存储,任何情况下都必须保证数据的可用性和正确性 c:52

而MySQL中存储着数据,要想保证集群扩容后数据一致负载均衡,必须要做数据迁移,将集群中原来机器中的数据迁移到新添加的机器中 c:35

同步完成时,即新机器中Schema数据和原机器中Schema数据一致的时候,修改Cobar服务器的路由配置,将这些Schema的IP修改为新机器的IP,然后删除原机器中的相关Schema,完成MySQL集群扩容。 c:12

从业务上回避分布式关系数据库的各种缺点:避免事务或利用事务补偿机制代替数据库事务;分解数据访问逻辑避免JOIN操作等。 c:109

一般而言,NoSQL数据库产品都放弃了关系数据库的两大重要基础:以关系代数为基础的结构化查询语言(SQL)和事务一致性保证(ACID)。而强化其他一些大型网站更关注的特性:高可用性和可伸缩性。 c:157

6.5 小结

救世主定律:遇到问题,分析问题,最后总能解决问题。如果遇到问题就急匆匆地从外面挖一个高手,然后指望高手如探囊取物般轻松搞定,最后怕是只有彼此抱怨和伤害。许多问题只是看起来一样,具体问题总是要具体对待的,没有银弹,没有救世主。所以这个定律准确地说应该是“没有救世主定律”。 c:112

7 随需应变:网站的可扩展架构

这些都有赖于网站的扩展性架构设计,就是在对现有系统影响最小的情况下,系统功能可持续扩展及提升的能力。 c:35

7.1 构建可扩展的网站架构

度量一个开发框架、设计模式、编程语言优劣的重要尺度就是衡量它是不是让软件开发过程和软件产品更加低耦合。 c:63

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

设计网站可扩展架构的核心思想是模块化,并在此基础之上,降低模块间的耦合性,提高模块的复用性。 c:188

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

事件驱动架构(Event Driven Architecture):通过在低耦合的模块之间传输事件消息,以保持模块的松散耦合,并借助事件消息的通信完成模块间合作,典型的EDA架构就是操作系统中常见的生产者消费者模式。 c:115

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

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

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

7.6 小结

马克思的劳动价值理论告诉我们,产品的内在价值在于劳动的时间,劳动的时间不在于个体付出的劳动时间,而在于行业一般劳动时间,资本家只会为行业一般劳动时间买单,如果你的效率低于行业一般劳动时间,对不起,请你自愿加班。 c:53

8.1 道高一尺魔高一丈的网站应用攻击与防御

XSS攻击即跨站点脚本攻击(Cross Site Script),指黑客通过篡改网页,注入恶意HTML脚本,在用户浏览网页时,控制用户浏览器进行恶意操作的一种攻击方式。 c:248

另外一种XSS攻击是持久型XSS攻击,黑客提交含有恶意脚本的请求,保存在被攻击的Web站点的数据库中,用户浏览网页时,恶意脚本被包含在正常页面中,达到攻击的目的 c:35

使用预编译手段,绑定参数是最好的防SQL注入方法。目前许多数据访问层框架,如IBatis,Hibernate等,都实现SQL预编译和参数绑定,攻击者的恶意SQL会被当做SQL的参数,而不是SQL命令被执行。 c:46

8.2 信息加密技术及密钥安全管理

信息加密技术可分为三类:单项散列加密、对称加密和非对称加密。 c:69

数字签名的过程则相反,签名者用自己的私钥对信息进行加密,然后发送给对方,接收方用签名者的公钥对信息进行解密,获得原始明文信息,由于私钥只有签名者拥有,因此该信息是不可抵赖的,具有签名的性质。 c:49

另一种方案是将加解密算法放在应用系统中,密钥则放在独立服务器中,为了提高密钥的安全性,实际存储时,密钥被切分成数片,加密后分别保存在不同存储介质中,兼顾密钥安全性的同时又改善了性能 c:64

8.3 信息过滤与反垃圾

基本上都是Trie树的变种,空间和时间复杂度都比较好的有双数组Trie算法等 c:48

在对过滤需求要求不完全精确的场景下,可用布隆过滤器代替Hash表。 c:37

可以看到,处理同样数量的信息,布隆过滤器只使用Hash表所需内存的1/8。但是布隆过滤器有可能导致系统误判(布隆过滤器检查在黑名单中,但实际却并未放入过)。因为一个邮箱地址映射的8个bit可能正好都被其他邮箱地址设为1了,这种可能性极小,通常在系统可接受范围内。但如果需要精确的判断,则不适合使用布隆过滤器。 c:22

9.2 淘宝网技术架构演化

业务快速发展,宝贵的开发资源应该投入到新业务开发上,而不是解决这些可以用付费产品搞定的基础技术问题上;成熟的付费产品和售后支持令业务和市场没有后顾之忧,可以全力以赴地拓展市场;对于一个快速发展的网站,特别是电子商务网站而言,严重宕机、重要用户数据丢失可能会极大地打击消费者信心,令网站发展平生波澜,而这些业界领先的产品经过多年的洗练,有较强的可用性保证。 c:36

在合适的场景下使用合适的产品,而不是最好的产品,所谓小脚穿大鞋,不但跑不快,还可能会摔跤。 c:60

辩证法关于事物发展的否定之否定及螺旋式上升的普遍规律,仿佛回到原点,但一切已经完全不同了。 c:48

9.3 小结

而有些路,走过以后,再回头,一览众山小! c:32

10.2 Wikipedia性能优化策略

所谓网站前端是指应用服务器(也就是PHP服务器)之前的部分,包括DNS服务、CDN服务、反向代理服务、静态资源服务等, c:57

后端优化最主要的手段是使用缓存,将热点数据缓存在分布式缓存系统的内存中,加速应用服务器的数据读操作速度,减轻存储和数据库服务器的负载。 c:55

11.1 分布式存储系统的高可用架构

保证高可用的主要手段是冗余:服务器热备,数据多份存储 c:48

11.2 不同故障情况下的高可用解决方案

空闲状态,只有在临时失效的时候,才会写入数据。任何时候该服务器都不会提供读操作服务。 c:19

12.2 秒杀系统的应对策略

为了避免用户直接访问下单页面URL,需要将该URL动态化,即使秒杀系统的开发者也无法在秒杀开始前访问下单页面的URL。办法是在下单页面URL加入由服务器端生成的随机数作为参数,在秒杀开始的时候才能得到。 c:106

12.3 秒杀系统架构设计

图12.5 秒杀系统的整体架构 c:14

13 大型网站典型故障案例分析

大型网站的架构师最有价值的地方不在于他们掌握了多少技术,而在于他们经历过多少故障。每一次故障都会给公司带来难以估计的利益损失,所以培养一个网站架构师的成本不单要看付了他多少薪水,给了他多少股票,还要看为他引起的故障买了多少次单。 c:66

13.2 高并发访问数据库引发的故障

首页不应该访问数据库,首页需要的数据可以从缓存服务器或者搜索引擎服务器获取。 ●首页最好是静态的。 c:71

首页不应该访问数据库,首页需要的数据可以从缓存服务器或者搜索引擎服务器获取。●首页最好是静态的。 c:156

13.3 高并发情况下锁引发的故障

但是某个需要远程调用的操作也被加了synchronized(this),这个操作只是偶尔会被执行,但是每次执行都需要较长的时间才能完成,这段时间锁被占用,所有的用户线程都要等待,响应超时,这个操作执行完后释放锁,其他线程迅速执行,超时解除。 c:35

13.4 缓存引发的故障

当缓存已经不仅仅是改善性能,而是成为网站架构不可或缺的一部分时,对缓存的管理就需要提高到和其他服务器一样的级别。 c:83

13.5 应用启动不同步引发的故障

在应用程序中加入一个特定的动态页面(比如只返回OK两个字母),启动脚本先启动JBoss,然后在脚本中不断用curl命令访问这个特定页面,直到收到OK,才启动Apache。 c:41

13.6 大文件读写独占磁盘引发的故障

存储的使用需要根据不同文件类型和用途进行管理,图片都是小文件,应该使用专用的存储服务器,不能和大文件共用存储。批处理用的大文件可以使用其他类型的分布式文件系统。 c:113

13.7 滥用生产环境引发的故障

访问线上生产环境要规范,不小心就会导致大事故。 c:15

13.8 不规范的流程引发的故障

●代码提交前使用diff命令进行代码比较,确认没有提交不该提交的代码。●加强code review,代码在正式提交前必须被至少一个其他工程师做过code review,并且共同承担因代码引起的故障责任。 c:59

13.9 不好的编程习惯引发的故障

●程序在处理一个输入的对象时,如果不能明确该对象是否为空,必须做空指针判断。●程序在调用其他方法时,输入的对象尽量保证不是null,必要时构造空对象(使用空对象模式)。 c:41

13.10 小结

软件设计有两种风格,一种是将软件设计得很复杂,以使其缺陷没那么明显;一种是将软件设计得很简单,以使其没有明显的缺陷 c:90

软件设计有两种风格,一种是将软件设计得很复杂,以使其缺陷没那么明显;一种是将软件设计得很简单,以使其没有明显的缺陷”。 c:53

14.1 关注人而不是产品

寻找一个值得共同奋斗的目标,营造一个让大家都能最大限度发挥自我价值的工作氛围。 c:155

14.2 发掘人的优秀

是事情成就了人,而不是人成就了事。指望优秀的人来帮自己成事,不如做成一件事让自己和参与的人都变得优秀。 c:111

发掘人的优秀远比发掘优秀的人更有意义。 c:104

14.3 共享美好蓝图

蓝图应该是表述清楚的:产品要做什么、不做什么、要达到什么业务目标,都需要描述清楚。 蓝图应该是形象的:产品能为用户创造什么价值、能实现什么样的市场目标、产品最终会长什么样,都需要形象地想象出来。 蓝图应该是简单的:不管内部还是外部沟通,都能一句话说明白:我们在做什么。 c:35

也许有人会说“你是在忽悠我吧,只是想让我努力工作而已”。青春总会逝去,人总是会死的,当有一天你白发苍苍回首往事,你会为无所事事而遗憾,但不会为被人忽悠而羞愧。批评马云忽悠的人,一定为马云在创建阿里巴巴的时候没有忽悠他成为创始人而遗憾。 c:57

14.4 共同参与架构

把架构和架构师凌驾于项目和项目组之上,只会让架构师变成孤家寡人,让架构曲高和寡。 c:14

1.不要只有架构师一个人拥有架构 c:16

让项目参与者对架构充分争论,大家越是觉得自己是项目架构的重要贡献者,就越是愿意对开发过程承担责任,越是愿意共同维护架构和改善软件。 c:38

14.5 学会妥协

不要企图在项目中证明自己是正确的,一定要记住,你是来做软件的,不是来当老大的。所以不要企图去证明自己了不起,永远也别干这种浪费时间、伤害感情的事。 c:106

14.6 成就他人

我们活着是为了成就我们自己,而要想成就自己,就必须首先成就他人。 c:58

15.1 发现问题,寻找突破

所谓问题,就是体验—期望,当体验不能满足期望,就会觉得出了问题。消除问题有两种手段:改善体验或者降低期望。降低期望只是回避了问题,而如果直面期望和体验之间的差距,就会发现问题所在,找到突破点。 c:127

15.2 提出问题,寻求支持

问题被发现,它只是问题发现者的问题,而不是问题拥有者的问题,如果想要解决一个问题,就必须提出这个问题,让问题的拥有者知道问题的存在。 c:28

给上司提封闭式问题,给下属提开放式问题 c:133

15.3 解决问题,达成绩效

在解决我的问题之前,先解决你的问题 c:47

后记

这是一本讲大型网站架构设计的书,但是大型网站不是设计出来的,而是逐步发展演化出来的。不要企图去设计一个大型网站! c:47