![](https://img-blog.csdnimg.cn/20201014180756927.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
秒杀系统
fengyu900909
这个作者很懒,什么都没留下…
展开
-
24 秒杀系统 | 防刷技术 | 防刷方案分析
防刷 秒杀令牌、秒杀大闸、队列泄洪、令牌桶算法都只能限制总流量,但无法控制黄牛流量,识别黄牛流量是个非常重要的议题;要识别出黄牛、黑客、接口模拟器的流量,并实施拦截; 传统防刷方案 限制会话 通过会话的标识,比如 JSESSIONID,token,限制一个会话,在同一秒/分钟内,接口调用的次数;针对多会话接入绕开,限制会话的方案是没有效果的;比如一个黄牛可能会开很多个会话/token 去接入系统...转载 2022-05-02 15:10:49 · 421 阅读 · 0 评论 -
23 秒杀系统 | 限流技术 | 令牌桶算法
为什么要设计限流方案 就是限制流量,让一部人用户能下单,一部分用户不能下单,从而避免大流量把系统冲挂了;流量远比想象的多,即使预估的再多,活动的真实流量也可能比预估的多;系统活着比挂了要好,系统活着能服务小部分用户,系统挂了一个用户都服务不了;宁愿只让少数人能用,也不要让所有人都不能用; 几种限流方案 限制并发的方案:全局计数器 限定同一时间只能有 10 个线程能访问接口,最初级的方案,用全局计...转载 2022-05-02 15:11:30 · 613 阅读 · 0 评论 -
21 秒杀系统 | 流量削峰技术 | 队列泄洪
队列泄洪原理 排队有时候比并发更高效,例如 Redis 单线程模型就是个正例;innodb 的 mutex key 就是个反例,所有的线程对一行数据更新,同时竞争一把行锁,没竞争到的线程多进入阻塞队列,完了等锁释放,再又一起竞争行锁就;单线程模型避免了线程切换的开销,反正遇到锁都会等待,还要有切换线程的消耗,不如就等待,把切换线程的消耗省掉;依靠排队去限制并发的流量;依靠排队和下游拥塞窗口的拥塞程度,调整队...转载 2022-04-09 14:10:02 · 342 阅读 · 1 评论 -
20 秒杀系统 | 流量削峰技术 | 秒杀大闸
秒杀大闸原理 依靠秒杀令牌的授权原理,定制化发牌逻辑,实现大闸功能;根据秒杀商品初始库存,颁发对应数量的令牌,控制大闸流量,比如初始库存 100 件,就发放 100 个令牌,实际实现的时候,颁发的令牌数量会比初始库存多一些,因为并不是所有的用户下单完成之后就会购买,多发一下,让更多的用户有竞争的机会;将用户的风控策略,前置到秒杀令牌的发放中(之前的令牌发放中已经完成了);将库存售罄判断前置到秒杀令牌的发放中...转载 2022-04-09 14:09:10 · 195 阅读 · 0 评论 -
19 秒杀系统 | 流量削峰技术 | 秒杀令牌
流量削峰三大技术 秒杀令牌秒杀大闸队列泄洪 引入削峰技术之前方案的缺点 秒杀下单接口会被脚本不停的刷新,所谓秒杀接口其实就是一个暴露在公网的 URL /order/create,如果用户知道自己的 token,要秒杀的商品的 id,很容易就能写个脚本不停的刷,这样会影响正常用户的下;即便在秒杀活动还没开始的时候,也存在被黄牛用户不停的刷的可能(有了秒杀令牌机制,在活动开始前,秒杀令牌是发不出去的,没...转载 2022-04-09 14:08:08 · 475 阅读 · 0 评论 -
18 秒杀系统 | 交易性能优化 | 库存售罄标识挡流量
库存售罄方案 库存售罄标识售罄后不操作后续流程售罄后通知各系统售罄回补上新 库存售罄方案实现 库存售罄标识 当扣减完库存后,库存为 0,则打上库存售罄标识; @Override@Transactionalpublic boolean decreaseStock(Integer itemId, Integer amount) { long result = redisTemplate.o...转载 2022-04-09 14:07:09 · 88 阅读 · 0 评论 -
17 秒杀系统 | 交易性能优化 | 库存操作流水 | 最终一致性 | RocketMQ 事务型消息反查接口的依据...
数据类型 主业务数据(Master Data) 比如 ItemModel,记录了商品的主数据;比如 item_stock 记录了商品库存的主数据; 操作型数据(Log Data) 比如库存扣减这样的操作发生了,需要把操作本身的过程记录下来,用于支持这种记录的数据,就是操作型数据;记录下操作型数据是为了追踪,比如库存流水的操作状态,可以根据这个状态做回滚,或者查询正在处理中的状态,使得很多异步的动...转载 2022-04-09 14:05:53 · 261 阅读 · 0 评论 -
16 秒杀系统 | 交易性能优化 | 库存缓存化(三)RocketMQ 事务型消息让 MySQL 同步 Redis 中的库存...
现存代码问题分析 decreaseStock 方法被 @Transactional 标注,并且调用 decreaseStock 的方法 createOrder 也被 @Transactional 标注,根据 Spring 的事务传播机制,默认 decreaseStock 会沿用 createOrder 的事务,也就是说和 createOrder 的事务同时成功或同时失败;原先 decreaseStock ...转载 2022-04-09 14:04:27 · 250 阅读 · 0 评论 -
15 秒杀系统 | 交易性能优化 | 库存行锁优化(二)异步消息扣减 MySQL 中的库存
异步消息扣减 MySQL 中的库存 RocketMQ 安装 下载二进制的包,解压;runserver.sh 和 runbroker.sh 两个文件虚拟机参数改小;启动 Name人Server:nohup sh bin/mqnamesrv &,启动 Broker:nohup sh bin/mqbroker -n localhost:9876 &;验证启动是否成功:export N...转载 2022-04-09 14:03:18 · 220 阅读 · 0 评论 -
14 秒杀系统 | 交易性能优化 | 库存行锁优化(一)扣减库存 Redis 化
SQL 分析 MySQL 加行锁的前提是:item_id 这一列上必须有索引;如果 item_id 这一列上没有索引,那么只能加表锁; <update id="decreaseStock"> update item_stock set stock = stock - #{amount} where item_id = #{itemId} and stock >= #{amount...转载 2022-04-09 14:02:16 · 261 阅读 · 0 评论 -
13 秒杀系统 | 交易性能优化 | 交易验证优化
交易流程图 交易流程.png 交易验证优化 用户风控策略优化;活动校验策略优化; 用户风控策略优化 用户风控策略 前提是获取用户信息;判断用户 Id 是最基础的风控策略;判断用户账号是否有异常:之前是否做过异地登录、最近是否做过修改密码等高风险操作; 优化 用户信息一开始都是持久化在 MySQL 中...转载 2022-04-09 13:59:51 · 77 阅读 · 0 评论 -
12 秒杀系统 | 交易性能优化 | 交易链路压测 & 瓶颈分析
交易流程图 交易流程.png Jmeter 压测交易接口 压测准备 做一笔交易操作,从 HTTP Request Header 抓出 Jmeter 发送压测请求时需要在消息体中添加的参数; 压测结果(1000,5,20) TPS:450+;Average:2000+;应用服务器 CPU 占用率:75%+;应...转载 2022-04-09 13:55:46 · 117 阅读 · 0 评论 -
11 秒杀系统 | 基于 phantomjs 全页面静态化技术的优化
思路 将 getitem.html 中 jQuery(document).ready(function(){... }) 方法中的内容,在服务端或爬虫端执行掉,执行完成之后,依赖于爬虫,生成一个 reload dom 完成的静态 html 文件;将生成出来的静态 html 文件部署到 CDN 上,完成全页面静态化的操作; 针对商品详情页的全页面静态化实践 编写 phantomjs 脚本 getite...转载 2022-04-05 14:16:28 · 137 阅读 · 0 评论 -
10 基于 phantomjs 的全页面静态化技术原理
定义 在服务端完成 html,css,甚至 js 的加载工作,渲染成纯 html 文件后直接以静态资源的方式部署到 CDN 上;不改动任何服务端代码,通过全页面静态化的手段,把已经渲染好的,布满数据的 html 页面,直接以 html 文件的形式部署到 CDN 上;全页面静态化的技术和网页爬虫非常的像,网页爬虫不知道引用的 js 文件或 css 文件,只知道最后爬出来的文件是一个可以在浏览器中渲染的文件; ...转载 2022-04-05 14:14:43 · 249 阅读 · 0 评论 -
09 静态资源前置到 CDN
CDN 概述 CDN 也是一种形式的缓存;CDN 在 Nginx 的前面,离用户更近;CDN 一般做静态资源的缓存; CDN 的配置步骤 & 运行原理 把需要加速的域名 ms.xxx.com 添加到 CDN 中,并指定 ms.xxx.com 的源站,添加到 CDN 中之后,CDN 会为这个加速域名生成一个 CNAME 域名;在腾讯云的 DNS 解析中,以 CNAME 的类型解析 ms.xxx...转载 2022-04-05 14:13:02 · 342 阅读 · 0 评论 -
08 秒杀系统 | 多级查询缓存 | OpenResty 直连 Redis
OpenResty 为什么要直连 Redis? OpenResty 到 Redis 的连接只读不写;当 OpenResty 在 Redis 中没有命中的情况下,请求打到应用服务器,应用服务器在 Redis 中应该也是没有命中的,然后请求会打到 MySQL,从 MySQL 中得到数据后,写入 Redis;OpenResty 直连 Redis 是解决 Nginx 的 Shared Dic 不能主动更新的问题,在...转载 2022-04-05 14:11:11 · 189 阅读 · 0 评论 -
07 秒杀系统 | 多级查询缓存 | 基于 Lua & Nginx 的 Shared Dic 做前置缓存
Shared Dic Nginx 的 Shared Dic 是对所有 Worker 进程可见的,共享内存字典,当共享内存空间用完了之后,采用 LRU 淘汰算法; 配置 Shared Dic 修改 nginx.conf,http 节点下添加: lua_shared_dict my_cache 128m; 创建脚本 itemshareddic.lua function get_from_c...转载 2022-04-05 14:09:48 · 251 阅读 · 0 评论 -
06 OpenResty 实战 | Hello World
OpenResty OpenResty 由 Nginx 核心加很多第三方模块组成,默认集成了 Lua 开发环境,使得开发人员可以使用 nginx_lua 开发 Nginx,使 Nginx 可以变成一个可以支持多功能的 Web Server;OpenResty 借助 Nginx 的事件驱动模型和非阻塞 IO(epoll),可以实现高性能的 Web 应用程序;OpenResty 提供了大量组件,如 MySQL、...转载 2022-04-05 14:07:35 · 190 阅读 · 0 评论 -
05 Nginx Lua 实战 | content_by_lua 插载点
在 nginx.conf 中配置 在 http 节点中配置; location /staticitem/get { default_type "text/html"; content_by_lua_file ../lua/staticitem.lua;} 创建 staticitem.lua 脚本 ngx.say("hello static item lua"); 重启 ngin...转载 2022-04-05 14:05:08 · 329 阅读 · 0 评论 -
04 Nginx Lua 实战 | init_by_lua 插载点
在 OpenResty 主目录下新建一个存放 Lua 脚本的目录 /home/lixinlei/application/openresty/lua,所有的 Lua 脚本都放在这个目录里,cd 到这个目录; 创建 Lua 脚本 init.lua init.lua 内容如下: ngx.log(ngx.ERR, "init lua success"); 使用 init.lua 脚本 修改 ...转载 2022-04-05 14:03:30 · 536 阅读 · 0 评论 -
03 Nginx Lua 原理
协程机制 基于用户态模拟出来的独立的运行空间;协程依附于线程的内存模型,切换开销小;协程遇到阻塞就归还执行权限,协程的代码以完全同步的方式模拟异步的调用,编程很容易;协程本质上是在线程中串行执行的,对任何共享变量的访问无需加锁; Nginx 协程 Nginx 的每一个 Worker 进程都是在 epoll 或 kqueue 这种事件模型之上,封装成协程;当一个 Socket 句柄接收到一个 HTTP...转载 2022-04-05 14:00:36 · 1006 阅读 · 0 评论