网站技术架构
《大型网站技术架构》笔记,2013
大型网站软件系统的特点:高并发用户,大流量访问;高可用(7×24小时提供服务);海量数据(上传到服务器上的数据很多);用户分布广泛,网络情况复杂;安全环境恶劣(互联网的开放性);需求变更快,发布频繁;渐进式发展。大型网站架构主要解决的就是由高并发访问和海量数据带来的一系列问题。
技术选型、架构设计、性能优化、web安全、系统发布、运维监控
网站的架构设计,快速开发,高效部署,业务监控,服务治理,运维管理
前端优化,CDN,反向代理,缓存,消息队列,分布式存储,分布式服务,NoSQL 存储,搜索,监控,安全等关键技术
分布式缓存,负载均衡,消息队列,分布式服务,网站的发布运维
高可用,高性能,易扩展,可伸缩,安全
了解网站技术架构最基本的驱动力,理解基础的架构设计原理和架构方案的选择。在解决问题之前,就能思考自己面对的真正问题究竟是什么、有哪些技术方案可以选择、其基本原理是什么。好的设计绝对不是模仿,也不是生搬硬套,而是基于对问题和需求的深刻理解而产生的创造和创新。
我们要学的,就是前人总结和积累出的那些通用的、经过验证的、且成熟的局部解决方案。除了知道它们是什么外,更要理解其内部逻辑和底层原理,因为在真正实践的时候很难有一模一样的场景,都是需要我们针对具体问题具体分析和应用的。
软件架构设计中常用的 4+1 视图模型,可以从多角度描述软件系统设计。
发展历程
网站架构的发展历程,在迭代中逐步演变。
初始阶段
只需要一台服务器就足够了,因为此时没有太多人访问
应用程序、数据库和文件等所有资源都放在一台服务器上
将应用和数据分离
目的:改善网站的并发处理能力和数据存储空间
整个网站需要 3 台服务器,不同服务器对硬件资源的要求不同
应用服务器:更快更强大的 CPU,需要处理大量的业务逻辑
数据库服务器:更快的硬盘和更大的内存,需快速磁盘检索和数据缓存
文件服务器:更大的硬盘,需要存储大量用户上传的文件
应用服务器集群
目的:改善网站的并发处理能力,让应用服务器的负载压力不再成为整个网站的瓶颈
通过负载均衡调度服务器,将来自用户浏览器的访问请求分发到应用服务器集群中的任何一台服务器上,从而分担原有服务器的访问和存储压力
缓存
目的:减少数据库的访问压力,提高网站的数据访问速度
网站使用的缓存分为两种:
本地缓存:在应用服务器上。访问速度会更快些,但是受应用服务器的内存限制,其缓存的数据量有限,而且会出现和应用程序争内存的情况。此外,单一应用服务器能处理的请求连接有限,在网站访问高峰期应用服务器会成为整个网站的瓶颈
远程缓存:在专门的分布式缓存服务器上。可以使用集群的方式部署大内存的服务器作为专门的缓存服务器,可以在理论上做到不受内存容量限制的缓存服务
CDN 和反向代理
目的:加速网站响应
基本原理都是缓存。都是为了尽早地返回数据给用户,一方面可以加快用户的访问速度,另一方面也能减轻后端服务器的负载压力
区别在于:
CDN 部署在网络提供商的机房。使用户在请求网站服务时,可以从距离自己最近的网络提供商的机房获得数据
反向代理部署在网站的中心机房。当用户请求到达中心机房后,首先访问的服务器是反向代理服务器,如果反向代理服务器中缓存着用户请求的资源,就将其直接返回给用户
数据库读写分离
目的:改善数据库的负载压力,让数据库的负载压力不再成为网站的瓶颈
背景:使用了缓存之后,仍然会有部分读操作和全部写操作需要访问数据库
大部分主流数据库都提供了“主从热备”功能,通过配置两台数据库主从关系,可以将一台数据库服务器的数据更新同步到另一台服务器上。利用数据库的该功能,可以实现数据库的读写分离
应用服务器在写数据的时候访问主数据库,主数据库通过“主从复制”机制将数据更新同步到从数据库,这样当应用服务器读数据的时候,就能通过从数据库获得数据
此时,数据库从一台服务器拆分成了两台服务器
通常会在应用的服务器端使用专门的数据访问模块,便于让数据库读写分离的时候对应用程序是透明的
NoSQL 和搜索引擎
背景:需要支持复杂的数据存储和检索,网站需要采用一些非关系数据库技术(如 NoSQL)和非数据库查询技术(如搜索引擎)
NoSQL 和搜索引擎都是源自互联网的技术手段,对可伸缩的分布式特性具有更好的支持。应用服务器则通过一个统一的数据访问模块访问各种数据,从而减轻应用程序管理诸多数据源的麻烦
业务拆分
将整个网站业务分成不同的产品线,从而让不同的业务团队负责
将一个网站拆分成许多不同的应用,每个应用独立部署维护。应用之间可以通过消息队列进行数据分发,也可以通过访问同一个数据存储系统来构成一个关联的完整系统
分布式服务
目的:解决数据库连接资源不足,拒绝服务的问题
背景:随着业务拆分越来越小,存储系统越来越庞大,应用系统的整体复杂度将呈指数级增加,部署维护也会越来越困难。由于所有的应用都要和数据库系统建立连接,而在数万台服务器规模的网站中,这些连接的数目会是服务器规模的平方
将共用的业务提取出来,独立部署,由这些可复用的业务连接数据库。通过分布式服务调用共用业务服务,从而完成具体的业务操作
分布式文件系统和 分布式数据库系统
分布式数据库是网站数据库拆分的最后手段,只有在单表数据规模非常庞大的时候才使用。不到不得已的时候,网站更常用的数据库拆分手段是“业务分库”,即将不同业务的数据库部署在不同的物理服务器上
时至今日,大型网站的架构演化方案已经非常成熟了,各种技术方案也逐渐产品化,计算、存储、网络等都可以按需购买,线性伸缩(都是搭建在云计算服务基础之上)。理解成熟的网站架构技术方案的来龙去脉和历史渊源,在技术选型和架构决策的时候,才能有的放矢,直击要害。
设计误区
网站架构的设计误区:
一味地追随大公司的解决方案:大公司的经验和成功模式固然重要,值得学习借鉴,但如果因此而变得盲从,那在架构演化的道路上迟早会迷路
为了技术而技术:网站是为了业务而存在的,除此之外毫无意义
企图用技术解决所有问题:虽然技术是用来解决业务问题的,但有时业务的问题也可以通过业务的手段来解决,即调整产品策略
大型网站都是从小型网站发展而来的。网站的意义在于它能为用户提供什么价值,而不在于它是怎么做的。所以,在网站还很小的时候就去追求网站的架构,是舍本逐末得不偿失的。小型网站最需要做的就是为用户提供好的服务,得到用户的认可,活下去,野蛮生长。
技术还是得依靠业务的发展,是业务成就了技术,是事业成就了人。对于创业团队,最重要的是先梳理清楚业务问题,而不是一味地仿照成功的互联网公司打造技术平台,这无疑是南辕北辙缘木求鱼。在技术选型和架构设计中,脱离网站业务发展的实际,一味地追求时髦的新技术,可能会将网站技术发展引入崎岖小道,架构之路也会越走越难。
架构模式
在程序设计和架构设计领域,模式正变得越来越受人关注。模式的关键在于模式的可重复性,问题和场景的可重复性带来解决方案的可重复使用。正确地使用模式可以更好地利用业界和前人的思想和实践,用更少的时间开发出更好的系统,同时也有助于提高设计者自身的水平。
分层
应用层、服务层、数据层
分层架构必须合理地规划层次边界和接口,在开发过程中要严格遵循分层架构的约束,禁止跨层次的调用和逆向调用
分层架构是逻辑上的,理论上三层结构可以部署在同一个物理机器上
分割
分模块。将不同的功能和服务分割开来,包装成高内聚低耦合的模块单元
分布式
分布式意味着可以使用更多的计算机完成相同的功能,计算机越多,CPU、内存、存储资源也就越多,能够处理的并发访问和数据量也就越大
常用的分布式方案:分布式应用和服务、分布式静态资源、分布式数据和存储(传统的关系数据库+各种 NoSQL 产品)、分布式计算(Hadoop 及其 MapReduce 分布式计算框架),以及分布式配置(线上服务器配置实时更新)、分布式锁(分布式环境下实现并发和协同)、分布式文件系统(支持云存储)等
带来的问题:影响性能(服务调用必须通过网络)、服务器宕机的概率会越大、保持数据的一致性变得困难、网站的依赖变得复杂
集群
多台服务器部署相同的应用,构成一个集群,通过负载均衡设备共同对外提供服务
需考虑:负载均衡设备、系统的失效机制
即使是访问量很小的分布式应用和服务,也至少要部署两台服务器构成一个小的集群,以提高系统的可用性
缓存
CDN(部署在离用户最近的网络服务商)、反向代理(部署在网站的前端,常用来缓存网站的静态资源)、本地缓存(应用服务器本地)、分布式缓存
使用缓存的两个前提条件:数据访问热点不均衡、数据有有效期
异步
系统解耦的手段,除了分层、分割、分布之外,还有异步。 业务之间的消息传递不是同步调用,而是将一个业务操作分成多个阶段,每个阶段之间通过共享数据的方式异步执行进行协作。
单一服务器内部(多线程共享内存队列) 分布式系统(多个服务器集群通过分布式消息队列)
异步架构是典型的生产者消费者模式,两者不存在直接调用,只要保持数据结构不变,彼此的功能实现就可以随意变化而不互相影响,这对网站扩展新功能是非常便利的
使用异步消息队列的特性: 提高系统可用性(当服务器发生故障时) 加快网站响应速度(写入消息队列即可返回) 消除并发访问高峰(用消息队列当缓冲以避免对整个网站造成大负载)
相应的问题:可能会影响到用户体验、业务流程
冗余
服务器冗余运行、数据冗余备份(冷备份+热备份)、灾备数据中心
访问和负载很小的服务也必须部署至少两台服务器构成一个集群
自动化
发布过程:自动化代码管理、自动化测试、自动化安全检测、自动化部署
线上运维(服务器宕机、程序bug、存储空间不足、突然爆发的访问高峰等):自动化监控、自动化报警、自动化失效转移、自动化失效恢复、自动化降级、自动化分配资源
安全
身份认证(密码+手机验证码)、对网络通信进行加密、验证码识别(防止机器人攻击),以及常见的网站攻击(XSS攻击+SQL注入)、信息过滤(垃圾信息+敏感信息)、对交易的风险控制
架构要素
软件架构:有关软件整体结构和组件的抽象描述,用于指导大型软件系统各个方面的设计。
一般来说,除了系统的功能需求之外,软件架构还需要关注性能、可用性、伸缩性、扩展性和安全性这 5 个架构要素。
性能
衡量指标:响应时间、TPS、系统性能计数器等
优化手段非常多,从浏览器到数据库,影响用户请求的所有环节都可以进行性能优化
浏览器端(浏览器缓存、页面压缩、合理布局页面、减少 cookie 传输等)
缓存层面
CDN(将网站的静态内容分发至离用户最近的网络服务商机房)
反向代理(在网站机房缓存热点文件)
应用服务器端(服务器本地缓存、分布式缓存)
应用服务器层面
异步操作(将用户请求发送至消息队列)
应用服务器集群
代码层面(多线程、改善内存管理)
数据库层面
数据库服务器端(索引、缓存、SQL 优化等)
NoSQL 数据库(优化数据模型、存储结构、伸缩特性等)
可用性
目标:当服务器宕机的时候,服务或者应用依然可用
衡量方法:假设系统中任何一台或多台服务器宕机以及出现各种不可预期的问题时,系统整体是否依然可用
主要手段就是冗余,即把应用部署在多台服务器上同时提供访问,把数据存储在多台服务器上互相备份
应用服务器集群(一个前提是应用服务器上不能保存请求的会话信息,否则服务器宕机后会话丢失,即使将用户的请求转发到其它服务器上也无法完成业务处理)
存储服务器(实时备份,当服务器宕机时将数据访问转移到可用的服务器上,并进行数据恢复)
开发过程的质量保证:预发布验证、自动化测试、自动化发布、灰度发布等手段
伸缩性
伸缩性是指通过不断地向集群中加入服务器的手段,来缓解不断上升的用户并发访问压力和不断增长的数据存储需求
衡量标准:是否可以用多台服务器构建集群,是否容易向集群中添加新的服务器,加入新的服务器后是否可以提供和原来的服务器无差别的服务,集群中可容纳的总的服务器数量是否有限制
应用服务器集群(只要服务器上不保存数据,所有的服务器都是对等的)
缓存服务器集群(需要注意缓存路由算法,保证缓存数据的可访问性)
关系数据库(虽然支持数据复制、主从热备等机制,但是很难做到大规模集群的可伸缩性,因此关系数据库的集群伸缩性方案必须在数据库之外实现,通过路由分区等手段将部署有多个数据库的服务器组成一个集群)
NoSQL 数据库产品(其先天就是为海量数据而生的,因此其对伸缩性的支持通常都非常好,可以做到在较少运维参与的情况下实现集群规模的线性伸缩)
扩展性
衡量标准:网站能否快速响应需求变化(网站的功能需求)
主要手段:
事件驱动架构(通常利用消息队列实现)
分布式服务(将业务和可复用服务分离开来,通过分布式服务框架调用)
开放平台接口(第三方开发者)
安全性
目的:保护网站不受恶意访问和攻击,保护网站的重要数据不被窃取
衡量标准:针对现存和潜在的各种攻击和窃密手段,是否有可靠的应对策略
Last updated