文章目录
优化原则
客户端优化
资源优化
连接优化
缓存优化
解析优化
加载优化
架构优化
服务端优化
秒杀问题解决方案
优化原则
系统技术设计原则
先解决核心问题,预测未来可能出现的问题,先行的规划与设计(好系统是迭代出来的)
对现有系统有方案,对未来系统有预案
无状态:对单次请求的处理,不依赖其他的请求
拆分原则:系统原则、功能维度、读写原则、切面(CDN等)、模块(基础架构组等)
系统业务设计原则 防重(幂等)原则、模块复用原则、可追溯原则、反馈原则、备份原则
软件质量衡量标准 功能性、效能性,兼容性、易用性、可靠性(容错)、安全性、可维护性、可移植性
系统衡量指标
吞吐量
(TPS、QPS)
并发数
(并发用户数、并发连接数、并发请求数、并发线程数)
平均响应时间
(RT) 阿姆达尔定理 (1-a)+a/n
客户端优化
资源优化
资源 :样式文件、脚本文件、图片、视频、文本等等 可从资源获取、资源处理、资源展示等方面进行优化
有些固有规则可存放在客户端(计算规则、预估价格等)
减少数据的传输,不必要的 cookie 可不传输
压缩资源
js 文件删除无效语义,注释等
css 文件语义合并
客户端 http head 中加参数:accept-encoding: gzip, deflate, br
表示客户端可以接受的压缩内容格式,服务端响应:head: Content-Encoding:gzip
,在服务器做一些手动压缩
减少请求(图片可使用雪碧图、baseb4 图片等)
连接优化
http 没有长短连接一说,长短连接是针对tcp的,http 是针对请求和响应模式的,只要服务端给了响应,本次http连接就结束。http1.1 发请求的时候,在请求头中添加:Connection: keep-alive
可复用底层tcp的长连接
长轮询:发现服务端没有变化的话,那么将当前请求挂起一段时间,如果没有变化,一直等到超时,如果有变化,则返回
缓存优化
页面资源在客户端、各级代理(中间各个节点)的缓存
headers: Cache-Control:public,max-age=10,no-transform
public (服务器设置):各级都能缓存
private(服务器设置):只能客户端缓存,中间各级都不缓存
no-cache(服务器和客户端都可以设置):可以缓存,但是不直接使用缓存,需要去服务器中验证
no-store(服务器和客户端都可以设置):哪都不要存
max-age = 秒,缓存可以存活的时间
s-maxage = 秒,在各个节点存活的时间,如果是客户端存储忽略
must-revalidate:服务器重新验证之前,不可以使用该资源
proxy-revalidate:各级节点有效
no-transform:不能压缩图像
only-if-cached:只要缓存的,不要服务器的资源
缓存更新不及时解决方案
更新文件名,发布上线一个文件,这个文件名是变的,那么缓存的文件就失效了
验证缓存的有效期(基于最后修改时间或版本号进行验证)
缓存模式
Cache-Aside 查询缓存,存在返回,不存在查询数据库
Read-Through 从缓存读数据
Write-Through 程序只和缓存交互且只能通过缓存写数据,并立即写入数据库中(一个事务里面)
Write-Behind 程序只和缓存交互且只能通过缓存写数据,一段时间后写入数据库
解析优化
优化正常解析流程,缩小回流和重绘的范围(流式布局下前面元素变了,页面会发生重绘),可将页面布局分为几块
创新解析流程,使用虚拟dom(Virtual DOM),比较前后两个dom的区别 根据当前数据生成一个描述当前dom结构的虚拟dom,然后数据发送变化时,又会生成一个新的虚拟dom,而这两个虚拟dom恰恰保存了变化前后的状态。然后通过diff算法,计算出两个前后两个虚拟dom之间的差异,得出一个更新的最优方法(哪些发生改变,就更新哪些)。可以很明显的提升渲染效率以及用户体验
加载优化
懒加载 加载最基础的元素,以后在根据用户的操作,进行局部加载。将原来一次性要加载的内容拆分成多次加载
预加载
- 同一域名
针对当前页面,更早的去下载资源
针对下一页,如果下一个页面存在比较大的资源,当前页面处理完,浏览器闲置的时候去加载该资源
- 不同域名
1. 减少域名解析(dns缓存)
2. DNS 预解析 在当前页面完成对下一个域名的解析,在下一个页面直接使用预解析之后的结果
架构优化
静态服务器、统一缓存管理服务、DNS等
服务端优化
DNS - 域名系统
将域名解析成IP地址,相当于web服务器,挂着一个分布式数据库,提供CRUD功能
A(Adderss):域名和IP的对应关系
CName(Canonical Name):域名和域名的对应关系
NS(name server):域名和能解析此域名的域名服务器的对应关系
域名解析流程
浏览器 -> 操作系统(hosts)-> LDNS(本地dns缓存) -> 根域名服务器 -> 顶级域名服务器 -> 权限域名服务器
以www.baidu.com为例,主要通过五个步骤进行域名解析
浏览器访问 www.baidu.com,询问本地 DNS 服务器是否缓存了该网址解析后的 IP 地址。
如果本地 DNS 服务器没有缓存的话,就去 root-servers.net 根服务器 查询该网址对应的 IP 地址。
根服务器返回顶级域名服务器的网址 gtld-servers.net,然后本地 DNS 服务器去顶级域名服务器 查询该网址对应的 IP 地址。
顶级域名服务器返回 www.baidu.com 主区域服务器的地址,然后本地 DNS 服务器去 www.baidu.com 权限域名服务器 查询此域名对应的 IP 地址。
本地 DNS 服务器拿到 www.baidu.com 解析后的 IP 地址后,缓存起来以便备查,然后把解析后的 IP 地址返回给浏览器。
最常见的通用顶级域名有7个,即:com(公司企业),net(网络服务机构),org(非营利组织),int(国际组织),gov(美国的政府部门),mil(美国的军事部门)。
DNS 优化
提前做好DNS缓存
域名对应多个IP
通过DNS做负载均衡(存在时效性问题,无法灵活使用)
CDN - 内容分发网络
CDN的基本原理是广泛采用各种缓存服务器,将这些缓存服务器分布到用户访问相对集中的地区或网络中,在用户访问网站时,利用全局负载技术将用户的访问指向距离最近的工作正常的缓存服务器上,由缓存服务器直接响应用户请求。 可根据配置的规则来确定需要缓存的信息
内容分发流程
1.用户向浏览器输入www.baidu.com 这个域名,浏览器第一次发现本地没有dns缓存,需要获取域名的ip地址
查找本机host文件
查找本机dns缓存
向网络连接中设置的dns服务器发送请求
把ip缓存到本机
2.www.baidu.com 这个域名配置智能dns解析
3.CDN网络中的智能DNS系统解析域名,起到负载均衡和高可用的作用,返回给用户合理的ip,可用的->附近的->响应最快的->负载低的
4.用户向该IP节点(CDN服务器)发出请求;
5.由于是第一次访问,CDN服务器会向源web站点请求,并缓存内容;
内容提交
ttl超时
cdn服务器向源服务器获取资源
6.请求结果发给用户,后续有相同的请求时可直接从CDN服务器上返回
每个CDN节点由两部分组成
其实就是一个负载均衡器 lvs 或 nginx,配合keepalived做到入口高可用,代理或转发请求到内网节点,做负载均衡
CDN 应用场景
适用
css、js、img 等 html骨架中包含的静态资源
app 内需要的img、html等资源
音视频点播资源
大文件下载
不适用
私密商业数据,
包含有逻辑的请求
需要鉴权
长连接
reactor模型
即时通讯
秒杀问题解决方案
应对瞬时大流量的冲击
秒杀场景都是供不应求,往往请求很对,最终生成订单的请求不多,也就是有效请求不多,所以前后端可以采用限流方案
前端限流
可以随意丢弃请求,直接返回失败(红包雨时可按随机数等策略丢弃一些请求,只有少数请求到达后端返回红包金额)
活动前置灰抢购按钮,防止产生无效的流量
防暴击
动静分离,多做静态化,引入DNS
后端限流
令牌桶算法
IP访问限制
用户黑名单
参与资格校验
熔断降级
引入缓存,提前预热
消息队列,流量削峰
超卖、少卖
超卖问题: 使用乐观锁进行变更,保证数据的安全性
少卖问题
使用定时任务,定期同步缓存和数据库中的数据
使用定时任务,定时取消超时未支付的订单并恢复库存
高可用
秒杀服务器独立部署,资源充足的情况下可以考虑针对秒杀活动单独部署一套环境,剥离一些可能无用的业务逻辑(优惠券、积分、红包等)
后台服务集群化,引入 lvs 和 nginx 等负载均衡技术
恶意请求
使用加密算法去做url,通过前端代码获取真实的url进行请求
IP 黑名单限制
增加算术或图形验证码辨别是否真实请求
相关资源
优化高并发的常见十种解决办法 高并发场景下的优化处理 秒杀整体架构图 负载均衡 LVS vs Nginx 对比!还傻傻分不清? 从网络底层原理来告诉你为什么LVS比Nginx和HAproxy更高效 网络知识之----http七层协议