高并发、秒杀场景下的优化思路

优化原则

系统技术设计原则

  1. 先解决核心问题,预测未来可能出现的问题,先行的规划与设计(好系统是迭代出来的)
  2. 对现有系统有方案,对未来系统有预案
  3. 无状态:对单次请求的处理,不依赖其他的请求
  4. 拆分原则:系统原则、功能维度、读写原则、切面(CDN等)、模块(基础架构组等)

系统业务设计原则
防重(幂等)原则、模块复用原则、可追溯原则、反馈原则、备份原则

软件质量衡量标准
功能性、效能性,兼容性、易用性、可靠性(容错)、安全性、可维护性、可移植性

系统衡量指标

  • 吞吐量(TPS、QPS)
  • 并发数(并发用户数、并发连接数、并发请求数、并发线程数)
  • 平均响应时间(RT) 阿姆达尔定理 (1-a)+a/n

客户端优化

资源优化

资源:样式文件、脚本文件、图片、视频、文本等等
可从资源获取、资源处理、资源展示等方面进行优化

  1. 有些固有规则可存放在客户端(计算规则、预估价格等)
  2. 减少数据的传输,不必要的 cookie 可不传输
  3. 压缩资源
    • js 文件删除无效语义,注释等
    • css 文件语义合并
    • 客户端 http head 中加参数:accept-encoding: gzip, deflate, br 表示客户端可以接受的压缩内容格式,服务端响应:head: Content-Encoding:gzip,在服务器做一些手动压缩
  4. 减少请求(图片可使用雪碧图、baseb4 图片等)

连接优化

  1. http 没有长短连接一说,长短连接是针对tcp的,http 是针对请求和响应模式的,只要服务端给了响应,本次http连接就结束。http1.1 发请求的时候,在请求头中添加:Connection: keep-alive 可复用底层tcp的长连接
  2. 长轮询:发现服务端没有变化的话,那么将当前请求挂起一段时间,如果没有变化,一直等到超时,如果有变化,则返回

缓存优化

页面资源在客户端、各级代理(中间各个节点)的缓存

 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:只要缓存的,不要服务器的资源

缓存更新不及时解决方案

  1. 更新文件名,发布上线一个文件,这个文件名是变的,那么缓存的文件就失效了
  2. 验证缓存的有效期(基于最后修改时间或版本号进行验证)

缓存模式

  • Cache-Aside 查询缓存,存在返回,不存在查询数据库
  • Read-Through 从缓存读数据
  • Write-Through 程序只和缓存交互且只能通过缓存写数据,并立即写入数据库中(一个事务里面)
  • Write-Behind 程序只和缓存交互且只能通过缓存写数据,一段时间后写入数据库

解析优化

  1. 优化正常解析流程,缩小回流和重绘的范围(流式布局下前面元素变了,页面会发生重绘),可将页面布局分为几块
  2. 创新解析流程,使用虚拟dom(Virtual DOM),比较前后两个dom的区别
    根据当前数据生成一个描述当前dom结构的虚拟dom,然后数据发送变化时,又会生成一个新的虚拟dom,而这两个虚拟dom恰恰保存了变化前后的状态。然后通过diff算法,计算出两个前后两个虚拟dom之间的差异,得出一个更新的最优方法(哪些发生改变,就更新哪些)。可以很明显的提升渲染效率以及用户体验

加载优化

  • 懒加载
    加载最基础的元素,以后在根据用户的操作,进行局部加载。将原来一次性要加载的内容拆分成多次加载
  • 预加载
- 同一域名
<link rel="preload" href="xxx.png"> 针对当前页面,更早的去下载资源
<link rel="prefetch" href="xxx.png"> 针对下一页,如果下一个页面存在比较大的资源,当前页面处理完,浏览器闲置的时候去加载该资源

- 不同域名
1. 减少域名解析(dns缓存)
2. DNS 预解析 在当前页面完成对下一个域名的解析,在下一个页面直接使用预解析之后的结果

架构优化

静态服务器、统一缓存管理服务、DNS等


服务端优化

DNS - 域名系统

域名解析成IP地址,相当于web服务器,挂着一个分布式数据库,提供CRUD功能

A(Adderss):域名和IP的对应关系 
CName(Canonical Name):域名和域名的对应关系 
NS(name server):域名和能解析此域名的域名服务器的对应关系
域名解析流程

浏览器 -> 操作系统(hosts)-> LDNS(本地dns缓存) -> 根域名服务器 -> 顶级域名服务器 -> 权限域名服务器
在这里插入图片描述

以www.baidu.com为例,主要通过五个步骤进行域名解析

  1. 浏览器访问 www.baidu.com,询问本地 DNS 服务器是否缓存了该网址解析后的 IP 地址。
  2. 如果本地 DNS 服务器没有缓存的话,就去 root-servers.net 根服务器查询该网址对应的 IP 地址。
  3. 根服务器返回顶级域名服务器的网址 gtld-servers.net,然后本地 DNS 服务器去顶级域名服务器查询该网址对应的 IP 地址。
  4. 顶级域名服务器返回 www.baidu.com 主区域服务器的地址,然后本地 DNS 服务器去 www.baidu.com 权限域名服务器查询此域名对应的 IP 地址。
  5. 本地 DNS 服务器拿到 www.baidu.com 解析后的 IP 地址后,缓存起来以便备查,然后把解析后的 IP 地址返回给浏览器。

最常见的通用顶级域名有7个,即:com(公司企业),net(网络服务机构),org(非营利组织),int(国际组织),gov(美国的政府部门),mil(美国的军事部门)。

DNS 优化
  1. 提前做好DNS缓存
  2. 域名对应多个IP
  3. 通过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 应用场景

适用

  1. css、js、img 等 html骨架中包含的静态资源
  2. app 内需要的img、html等资源
  3. 音视频点播资源
  4. 大文件下载

不适用

  1. 私密商业数据,
  2. 包含有逻辑的请求
  3. 需要鉴权
  4. 长连接
  5. reactor模型
  6. 即时通讯

秒杀问题解决方案

  1. 应对瞬时大流量的冲击

秒杀场景都是供不应求,往往请求很对,最终生成订单的请求不多,也就是有效请求不多,所以前后端可以采用限流方案

  • 前端限流
    • 可以随意丢弃请求,直接返回失败(红包雨时可按随机数等策略丢弃一些请求,只有少数请求到达后端返回红包金额)
    • 活动前置灰抢购按钮,防止产生无效的流量
    • 防暴击
    • 动静分离,多做静态化,引入DNS
  • 后端限流
    • 令牌桶算法
    • IP访问限制
    • 用户黑名单
    • 参与资格校验
    • 熔断降级
    • 引入缓存,提前预热
    • 消息队列,流量削峰
  1. 超卖、少卖
  • 超卖问题:
    使用乐观锁进行变更,保证数据的安全性
  • 少卖问题
    • 使用定时任务,定期同步缓存和数据库中的数据
    • 使用定时任务,定时取消超时未支付的订单并恢复库存
  1. 高可用
  • 秒杀服务器独立部署,资源充足的情况下可以考虑针对秒杀活动单独部署一套环境,剥离一些可能无用的业务逻辑(优惠券、积分、红包等)
  • 后台服务集群化,引入 lvs 和 nginx 等负载均衡技术
  1. 恶意请求
  • 使用加密算法去做url,通过前端代码获取真实的url进行请求
  • IP 黑名单限制
  • 增加算术或图形验证码辨别是否真实请求

相关资源

优化高并发的常见十种解决办法
高并发场景下的优化处理
秒杀整体架构图
负载均衡 LVS vs Nginx 对比!还傻傻分不清?
从网络底层原理来告诉你为什么LVS比Nginx和HAproxy更高效
网络知识之----http七层协议

### 回答1: 对于高并发场景下的商品秒杀,我的设计思路是采用分布式架构,将请求分散到多个服务器上进行处理,同时使用缓存技术和消息队列来提高系统的性能和可靠性。具体来说,可以采用以下措施: 1. 使用缓存技术:将商品信息、用户信息等常用数据缓存在内存中,减少数据库的访问次数,提高系统的响应速度。 2. 使用消息队列:将用户的请求放入消息队列中,异步处理,避免请求堆积,提高系统的并发能力。 3. 限流措施:设置访问频率限制,防止恶意攻击和过度消耗系统资源。 4. 数据库优化:使用数据库连接池、索引等技术来提高数据库的性能和并发能力。 5. 分布式架构:将请求分散到多个服务器上进行处理,避免单点故障和系统崩溃。 通过以上措施的综合应用,可以有效地提高系统的性能和可靠性,实现高并发场景下的商品秒杀。 ### 回答2: 在高并发场景下实现商品秒杀需要考虑几个方面的设计思路。 首先,为了提高系统的并发能力,可以通过分布式架构来设计。将商品库存等信息分散到多台服务器上,通过负载均衡来均衡并发访问请求,减轻单个服务器的压力。 其次,为了防止超卖问题,可以使用分布式锁来保护商品库存的减少操作。当一个用户发起抢购请求时,先获取锁进行商品数量减少的操作,在减少成功后再进行下一步操作,否则释放锁。这样可以保证只有一个用户可以成功购买商品。 另外,为了提高系统的响应速度,可以使用缓存来减少数据库的压力。将商品信息或者库存信息缓存在内存中,用户访问时直接读取缓存中的数据,而不是直接访问数据库。当商品抢购成功后,再对缓存中的数据进行更新。 此外,为了防止恶意请求,可以使用验证码来进行人机验证。在用户参与秒杀之前,先输入验证码进行验证,只有验证通过后才能参与秒杀活动。 最后,可以通过限制每个用户的参与次数来平衡系统压力。例如,设置每个用户只能参与一次秒杀活动,这样可以避免少数用户通过机器人等方式进行大量请求,从而导致系统崩溃。 综上所述,高并发场景下实现商品秒杀需要通过分布式架构、分布式锁、缓存、验证码和限制参与次数等多种设计思路来提高系统的并发能力、保证数据一致性、提高响应速度,并防止恶意请求。 ### 回答3: 在高并发场景下实现商品秒杀,主要需要考虑以下几个方面的设计思路: 1. 分布式系统架构:为了应对高并发的请求,需要使用分布式系统架构,将请求分散到不同的服务器节点上进行处理。可以采用主从架构或集群架构来实现。 2. 缓存优化:为了提高系统的响应速度,在秒杀开始前将商品信息加载到缓存中,并使用缓存技术如Redis等进行商品库存管理。当用户请求秒杀时,先从缓存中读取商品信息,减轻数据库的压力,并且可以设置缓存的过期时间,避免商品库存信息不一致的问题。 3. 队列消息机制:秒杀场景涉及到同时并发大量的请求,使用队列消息机制可以缓解高并发带来的压力。当用户下单时,将用户请求放入消息队列中,再由消息队列异步地处理用户的秒杀请求。 4. 限流措施:为了避免系统过载导致崩溃,需要对用户请求进行限流处理。可以使用令牌桶算法或漏桶算法来控制系统的请求处理速率,以保证系统的可用性。 5. 数据库优化秒杀涉及到大量的数据库操作,针对这一情况可以进行数据库的优化。例如,可以使用数据库连接池来提高数据库连接的效率,同时对数据库进行垂直切分或水平分片等策略,使得数据库能够承载更高的并发请求。 总之,在高并发场景下实现商品秒杀需要从系统架构、缓存优化、消息队列、限流措施和数据库优化等多个方面进行综合考虑,以提高系统的性能和稳定性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值