《大型网站技术架构》读书笔记

阐述

是业务成就了技术,是事业成就了人,而不是相反

12306真正的问题其实不在于它的技术架构,而在于它的业务架构:12306根本就不应该在几亿中国人一票难求的情况下以窗口售票的模式在网上售票(零点开始出售若干天后的车票)。

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

云计算

越来越多的网站从建立之初就是搭建在大型网站提供的云计算服务基础之上,所需要的一切技术资源:计算、存储、网络都可以按需购买,线性伸缩,不需要自己一点一点地拼凑各种资源,综合使用各种技术方案逐步去完善自己的网站架构了。

模式

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

网站的技术目标

以实现网站高性能、高可用、易伸缩、可扩展、安全等各种技术架构目标。

分层

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

通过分层,可以更好地将一个庞大的软件系统切分成不同的部分,便于分工合作开发和维护;各层之间具有一定的独立性,只要维持调用接口不变,各层可以根据具体问题独立演化发展而不需要其他层必须做出相应调整。

分层架构是逻辑上的,在物理部署上,三层结构可以部署在同一个物理机器上,但是随着网站业务的发展,必然需要对已经分层的模块分离部署,即三层结构分别部署在不同的服务器上,使网站拥有更多的计算资源以应对越来越多的用户访问。

分割

如果说分层是将软件在横向方面进行切分,那么分割就是在纵向方面对软件进行切分。网站越大,功能越复杂,服务和数据处理的种类也越多,将这些不同的功能和服务分割开来,包装成高内聚低耦合的模块单元,一方面有助于软件的开发和维护;另一方面,便于不同模块的分布式部署,提高网站的并发处理能力和功能扩展能力。

分布式

分布式在解决网站高并发问题的同时也带来了其他问题。首先,分布式意味着服务调用必须通过网络,这可能会对性能造成比较严重的影响;其次,服务器越多,服务器宕机的概率也就越大,一台服务器宕机造成的服务不可用可能会导致很多应用不可访问,使网站可用性降低;另外,数据在分布式的环境中保持数据一致性也非常困难,分布式事务也难以保证,这对网站业务正确性和业务流程有可能造成很大影响;分布式还导致网站依赖错综复杂,开发管理维护困难。

分布式应用和服务,分布式静态资源,分布式存储,分布式计算,分布式配置,分布式锁

使用分布式虽然已经将分层和分割后的模块独立部署,但是对于用户访问集中的模块(比如网站的首页),还需要将独立部署的服务器集群化,即多台服务器部署相同应用构成一个集群,通过负载均衡设备共同对外提供服务。

缓存

缓存就是将数据存放在距离计算最近的位置以加快处理速度。缓存是改善软件性能的第一手段,现代CPU越来越快的一个重要因素就是使用了更多的缓存,在复杂的软件设计中,缓存几乎无处不在。大型网站架构设计在很多方面都使用了缓存设计。

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

降低耦合与消息队列

计算机软件发展的一个重要目标和驱动力是降低软件耦合性。事物之间直接关系越少,就越少被彼此影响,越可以独立发展。大型网站架构中,系统解耦合的手段除了前面提到的分层、分割、分布等,还有一个重要手段是异步,业务之间的消息传递不是同步调用,而是将一个业务操作分成多个阶段,每个阶段之间通过共享数据的方式异步执行进行协作。

在单一服务器内部可通过多线程共享内存队列的方式实现异步,处在业务操作前面的线程将输出写入到队列,后面的线程从队列中读取数据进行处理;在分布式系统中,多个服务器集群通过分布式消息队列实现异步,分布式消息队列可以看作内存队列的分布式部署。

消息队列好处,提高可用性,加快网站相应速度,消除并发访问的高峰,削锋平谷

高可用与冗余

冗余,主从热备,提高可用性

自动化

自动化,代码版本管理,静态代码检查,测试,部署,自动化监控,心跳检测,自动化故障转移,自动化降级,

安全

安全,加密,验证码,风控,编码,xss,sql,敏感信息过滤

微创新

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

架构的阐述

关于什么是架构,一种比较通俗的说法是“最高层次的规划,难以改变的决定”,这些规划和决定奠定了事物未来发展的方向和最终的蓝图。

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

性能优化(前端,应用层,服务层,数据层,代码)

也正是因为性能问题几乎无处不在,所以优化网站性能的手段也非常多,从用户浏览器到数据库,影响用户请求的所有环节都可以进行性能优化。在浏览器端,可以通过浏览器缓存、使用页面压缩、合理布局页面、减少Cookie传输等手段改善性能。

在应用服务器端,可以使用服务器本地缓存和分布式缓存,通过缓存在内存中的热点数据处理用户请求,加快请求处理过程,减轻数据库负载压力。也可以通过异步操作将用户请求发送至消息队列等待后续任务处理,而当前请求直接返回响应给用户。在网站有很多用户高并发请求的情况下,可以将多台应用服务器组成一个集群共同对外服务,提高整体处理能力,改善性能。

在代码层面,也可以通过使用多线程、改善内存管理等手段优化性能。在数据库服务器端,索引、缓存、SQL优化等性能优化手段都已经比较成熟。而方兴未艾的NoSQL数据库通过优化数据模型、存储结构、伸缩特性等手段在性能方面的优势也日趋明显。衡量网站性能有一系列指标,重要的有响应时间、TPS、系统性能计数器等,通过测试这些指标以确定系统设计是否达到目标。这些指标也是网站监控的重要参数,通过监控这些指标可以分析系统瓶颈,预测网站容量,并对异常指标进行报警,保障系统可用性。

网站需要长时间持续运行,还必须保证系统在持续运行且访问压力不均匀的情况下保持稳定的性能特性。

高可用与冗余

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

伸缩性(分布式和事件驱动手段)

所谓伸缩性是指通过不断向集群中加入服务器的手段来缓解不断上升的用户并发访问压力和不断增长的数据存储需求。

于应用服务器集群,只要服务器上不保存数据,所有服务器都是对等的,

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

事件驱动架构在网站通常利用消息队列实现,将用户请求和其他业务事件构造成消息发布到消息队列,消息的处理者作为消费者从消息队列中获取消息进行处理。通过这种方式将消息产生和消息处理分离开来,可以透明地增加新的消息生产者任务或者新的消息消费者任务。分布式服务则是将业务和可复用服务分离开来,通过分布式服务框架调用。新增产品可以通过调用可复用的服务实现自身的业务逻辑,而对现有产品没有任何影响。可复用服务升级变更的时候,也可以通过提供多版本服务对应用实现透明升级,不需要强制应用同步变更。

性能指标

网站性能是客观的指标,可以具体体现到响应时间、吞吐量等

前端优化

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

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

主要的优化手段有使用缓存加速数据读取,使用集群提高吞吐能力,使用异步消息加快请求响应及实现削峰,使用代码优化手段改善程序性能。

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

它是描述服务器或操作系统性能的一些数据指标。包括SystemLoad、对象与线程数、内存使用、CPU使用、磁盘与网络I/O等指标。这些指标也是系统监控的重要参数,对这些指标设置报警阈值,当监控系统发现性能计数器超过阈值时,就向运维和开发人员报警,及时发现处理系统异常。

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

浏览器访问优化,减少请求次数,合并静态资源,利用浏览器缓存,cachecontrol和expires,启用压缩,合理布局页面,样式放前,脚本放后,cdn,反向代理,减少cookie,

产品在设计之初就需要一个明确的定位:什么是产品要实现的功能,什么不是产品提供的特性。在产品漫长的生命周期中,会有形形色色的困难和诱惑来改变产品的发展方向,左右摇摆、什么都想做的产品,最后有可能成为一个失去生命力的四不像。

分布式通信,考虑通信协议,和数据格式

而其客户端路由算法一致性 Hash 更成为数据存储伸缩性架构设计的经典范式(参考本书第 6 章)。事实上,正是集群内服务器互不通信使得集群可以做到几乎无限制的线性伸缩,这也正是目前流行的许多大数据技术的基本架构特点。

代码优化,多线程,

从资源利用角度,多线程的使用原因,IO阻塞和多核

线程安全的解决方法,

无状态对象,即贫血对象,在方法内创建对象,方法内的局部变量,使用锁机制,资源服用,即单例和对象池

对于数据库连接对象,每次创建连接,数据库服务端都需要创建专门的资源以应对,因此频繁创建关闭数据库连接,对数据库服务器而言是灾难性的,同时频繁创建关闭连接也需要花费较长的时间。

Time33虽然可以较好地解决冲突,但是有可能相似字符串的HashCode也比较接近,如字符串“AA”的HashCode是2210,字符串“AB”的HashCode是2211。这在某些应用场景是不能接受的,这种情况下,一个可行的方案是对字符串取信息指纹,再对信息指纹求HashCode,由于字符串微小的变化就可以引起信息指纹的巨大不同,因此可以获得较好的随机散列,如图4.16所示。

以JVM为例,其内存主要可划分为堆(heap)和堆栈(stack)。堆栈用于存储线程上下文信息,如方法参数、局部变量等。堆则是存储对象的内存空间,对象的创建和释放、垃圾回收就在这里进行。通过对对象生命周期的观察,发现大部分对象的生命周期都极其短暂,这部分对象产生的垃圾应该被更快地收集,以释放内存,这就是JVM分代垃圾回收,其基本原理如图4.17所示。

原文地址:https://www.cnblogs.com/wuMing-dj/p/4949715.html