如何优化一个秒杀项目?(秒杀实现思路)
liuian 2025-05-05 17:01 6 浏览
问题1:使用jmeter性能压测,定位瓶颈代码
步骤流程:线程组--->Http请求--->查看结果树--->聚合报告
tips:host的文件--->优先调用映射,减少DNS的时间
默认内嵌Tomcat配置---->参数调优
server.tomcat.accept-count:等待队列长度,默认100
server.tomcat.max-connections:最大可被连接数,默认10000
server.tomcat.max-threads:最大工作线程数,默认200
server.tomcat.min-spare-threads:最小工作线程数,默认10
默认配置下,连接超过10000后出现拒绝连接情况
默认配置下,触发的请求超过200+100后拒绝处理
定制化内嵌Tomcat开发--->keepalive
keepAliveTimeOut:多少毫秒后不响应的断开keepalive
maxKeepAliveRequests:多少次请求后keepalive断开失效
使用
WebServerFactoryCustomizer定制化内嵌tomcat配置
MySql数据库QPS容量问题
◆主键查询:千万级别数据=1-10毫秒
◆唯一索引查询:千万级别数据=10-100毫秒
◆非唯一索引查询:千万级别数据=100-1000毫秒
◆无索引:百万条数据=1000毫秒+
问题2:分布式扩展
1.单机容量问题,水平扩展
- mysql数据库开放远端连接
- 服务端水平对称部署
- 验证访问
2.使用OpenResty
使用Nginx做为静态资源服务器+nginx反向代理负载均衡
Nginx的高性能原因:
- epoll多路复用
- master-worker模型
- 协程机制 依附于线程的内存模型,切换开销小 遇阻塞及归还执行权 代码同步无需加锁
3.分布式会话管理
传统的会话管理
基于cookie传输sessionid:java tomcat容器session实现
基于token传输类似sessionid:java代码session实现
使用redis实现分布式会话存储
基于cookie传输sessionid:java tomcat容器session实现迁移到redis
基于token传输类似sessionid:java代码session实现迁移到redis
问题3:查询优化技术
1.掌握多级缓存的定义
缓存设计
用快速存取设备
用内存将缓存推到离用户最近的地方
脏缓存清理
2.多级缓存
1.redis缓存:单机、哨兵、集群----(注意序列化问题)
2.热点内存本地缓存--Guava cache
- 可控制的大小和超时时间
- 可配置的lru策略
- 线程安全
3.nginx proxy cache缓存--实际效果还不如本地缓存 ,可以用shared dic (2000)
- 依靠文件系统存索引级的文件
- 依靠内存缓存文件地址
4.nginx lua缓存
- nginx lua挂载点---将简单的逻辑放到Nginx中处理,避免调用java代码 init-by_lua:系统启动时调用 init-worker-by_lua:worker进程启动时调用 setby_lua:nginx变量用复杂lua return rewrite-by_lua:重写url规则 access_by_lua:权限验证阶段 content-by_lua:内容输出节点
- OpenResty OpenResty由Nginx核心加很多第三方模块组成,默认集成了Lua开发环境,使得Nginx可以作为一个Web Server使用。 借助于Nginx的事件驱动模型和非阻塞IO,可以实现高性能的Web应用程序。 OpenResty提供了大量组件如Mysql,Redis,Memcached等等使在Nginx上开发Web应用更方便更简单。
shared dic:共享内存字典,所有worker进程可见,Iru淘汰 ---更新操作不强 (3500)
使用openresty对redis支持,可以连接到从机,只读不写。(3500)
问题4:静态资源的优化
1.静态请求CDN
1.DNS用CNAME解析到源站
2.回源缓存设置
cache control响应头
- private:客户端可以缓存
- public:客户端和代理服务器都可以缓存
- max-age=xxx:缓存的内容将在xxx秒后失效
- no-cache:强制向服务端再验证一次
- no-store:不缓存请求的任何返回内容
有效性验证
- ETag:资源唯一标识
- If-None-Match:客户端发送的匹配Etag标识符
- Last-modified:资源最后被修改的时间
- If-Modified-Since:客户端发送的匹配资源最后修改时间的标识符
三种刷新方式
- 回车刷新或a链接:看cache-control对应的max-age是否仍然有效,有效则直接from cache,若cache-control中为no-cache,则进入缓存协商逻辑
- F5刷新或command+ R刷新:去掉cache-control中的max-age或直接设置max-age为0,然后进入缓存协商逻辑
- ctrl+F5或commond+shift+R刷新:去掉cache-control和协商头,强制刷新
CDN自定义缓存策略
- 可自定义目录过期时间
- 可自定义后缀名过期时间
- 可自定义对应权重
- 可通过界面或api强制cdn对应目录刷新(非保成功)
2.静态资源部署策略
css,js,img等元素使用带版本号部署,例如a.js?v=1.0不便利且维护困难
css,js,img等元素使用带摘要部署,例如a.js?v=45edw存在先部署html还是先部署资源的覆盖问题(先后问题)
css.js,img等元素使用摘要做文件名部署,例如45edw.js,新老版本并存且可回滚,资源部署完后再部署html(==好==)
对应静态资源保持生命周期内不会变,max-age可设置的很长,无视失效更新周期
html文件设置no-cache或较短max age,以便于更新
html文件仍然设置较长的max age,依靠动态的获取版本号请求发送到后端,异步下载最新的版本号的html后展示渲染在前端
动态请求也可以静态化成json资源推送到cdn上 依靠异步请求获取后端节点对应资源状态做紧急下架处理
可通过跑批紧急推送cdn内容以使其下架等操作
3.全页面静态化
定义:在服务端完成html,css,甚至js的load渲染成纯html文件后直接以静态资源的方式部署到cdn上
phantomjs应用---类似于爬虫的原理
修改需要全页面静态化的实现,采用initView和hasInit方式防止多次初始化
编写对应轮讯生成内容方式
将全静态化页面生成后推送到cdn
问题5:交易优化技术之缓存库存
扣减库存缓存化
(1)活动发布同步库存进缓存
(2)下单交易减缓存库存
异步同步数据库------异步消息队列rocketmq
分布式事务
方案:
(1)引入库存操作流水
(2)引入事务性消息机制
问题6:流量削峰技术
秒杀令牌的原理和使用方式
- 秒杀接口需要依靠令牌才能进入
- 秒杀的令牌由秒杀活动模块负责生成
- 秒杀活动模块对秒杀令牌生成全权处理,逻辑收口
- 秒杀下单前需要先获得秒杀令牌
秒杀大闸的原理和使用方式
- 依靠秒杀令牌的授权原理定制化发牌逻辑,做到大闸功能
- 根据秒杀商品初始库存颁发对应数量令牌,控制大闸流量
- 用户风控策略前置到秒杀令牌发放中
- 库存售馨判断前置到秒杀令牌发放中
队列泄洪的原理和使用方式
- 排队有些时候比并发更高效
- 依靠排队去限制并发流量
- 依靠排队和下游拥塞窗口程度调整队列释放流量大小
本地OR分布式?
- 本地:将队列维护在本地内存中--负载不均衡
- 分布式:将队列设置到外部redis内
可以使用外部的分布式,如果出现了性能问题,可以使用降级策略,切换到本地。
问题7:防刷限流
为什么要进行限流?
- 流量远比你想的要多
- 系统活着比挂了要好
- 宁愿只让少数人能用,也不要让所有人不能用
限流方案
- 限并发
- 令牌桶算法(互联网公司常用)
- 漏桶算法
限流力度
- 接口维度
- 总维度---比接口的低20%左右
限流范围
- 集群限流:依赖redis或其他的中间件技术做统一计数器,往往会产生性能瓶颈
- 单机限流:负载均衡的前提下单机平均限流效果更好
传统防刷
- 限制一个会话(session_id,token)同一秒钟/分钟接口调用多少次:多会话接入绕开无效
- 限制一个ip同一秒钟/分钟接口调用多少次:数量不好控制,容易误伤
黄牛为什么难防
- 模拟器作弊:模拟硬件设备,可修改设备信息
- 设备牧场作弊:工作室里一批移动设备
- 人工作弊:靠佣金吸引兼职人员刷单
防刷策略
1.验证码
2.排队,限流,令牌均只能控制总流量,无法控制黄牛流量
3.不同端进行隔离,使用代码混淆,HTTPs等技术
4.设备指纹
◆采集终端设备各项参数,启动应用时生成唯一设备指纹
◆根据对应设备指纹的参数猜测出模拟器等可疑设备概率
5.凭证系统
◆根据设备指纹下发凭证
◆关键业务链路上带上凭证并由业务系统到凭证服务器上验证
◆凭证服务器根据对应凭证所等价的设备指纹参数并根据实时行为风控系统判定对应凭证的可疑度分数
◆若分数低于某个数值则由业务系统返回固定错误码,拉起前端验证码验身,验身成功后加入凭证服务器对应分数
问题8:单点登录
问题9:Mysql的性能优化
1.mysql应用性能优化拓展
通用性能优化---缓存+异步+批处理
写---批量写
- Sql编译N次和1次的时间与空间复杂度
- 网络消耗的时间复杂度
- 磁盘寻址的复杂度
读---索引
- 主键查询千万条记录1-10ms
- 唯一索引千万条记录10-100ms
- 非唯一索引千万条记录100-1000ms
- 无索引百万条记录1000ms+
mysql单机配置性能优化拓展
max_connection=1000
innodb _file_per_table=1
innodb_buffer_pool_size=1G
innodb_log_ file_size=256M
innodb_log_buffer_size=16M
innodb_flush_log_at_trx_commit=2(1---事务提交就刷盘)
2.mysql分布式配置性能优化拓展
mysql主从
- 开启bin_log
- 设置主从同步账号,配置主从同步
3.一致性原理
- 强一致性
- 弱一致性
- 最终一致性
CAP理论
- C:一致性
- A可用性
- P:分片性
base理论
- ◆Basic available:基本可用
- ◆S.:软状态
- ◆E:最终一致性
作者:gsyzh
链接:
https://juejin.im/post/5ed5adbd6fb9a047d3710da4
相关推荐
- Docker 47 个常见故障的原因和解决方法
-
【作者】曹如熙,具有超过十年的互联网运维及五年以上团队管理经验,多年容器云的运维,尤其在Docker和kubernetes领域非常精通。Docker是一种相对使用较简单的容器,我们可以通过以下几种方式...
- 电脑30个快问快答,解决常见电脑问题
-
1.强行关机/停电对电脑有影响吗?答:可能损坏硬盘(机械硬盘风险高)、未保存数据丢失,偶尔一次影响小,但频繁操作会缩短硬件寿命。2.C盘满影响速度吗?答:会!系统运行需C盘空间缓存临时数据,空间不...
- 使用Tcpdump包抓取分析数据包的详细用法
-
TcpDump可以将网络中传送的数据包的“头”完全截获下来提供分析。它支持针对网络层、协议、主机、网络或端口的过滤,并提供and、or、not等逻辑语句来帮助你去掉无用的信息。tcpdump就是一种...
- 电脑启动不了(BootDevice Not Found Hard Disk-3F0)解决方案
-
HP品牌机,开机启动不了,黑屏,开机取下主板电池恢复BIOS后,开机显示找不到启动盘。一、按F2键进入BIOS,出现硬盘内存检测界面的话,直接退出。就会出现这个界面,光标键向下,选择BIOSSetu...
- 电脑开机黑屏别慌!快码住!起底维修老师傅不能说的秘密
-
按下开机键却只收获黑屏大礼包?那些神秘的英文提示、刺耳的蜂鸣声,其实是电脑在给你发送求救信号!从按下电源到进入桌面的12秒里,你的电脑经历了史诗级的硬件自检与系统加载,今天我们就破译这段“摩斯电码”。...
- 电脑启动故障为何总要先看BIOS?新手必读的关键知识解析
-
最近在帮朋友们解答电脑无法正常开机的问题时,发现大家经常收到一句高频建议:“先检查BIOS”。对不少普通用户而言,BIOS依然是个神秘的存在。那么,BIOS到底是什么?电脑出现哪些故障会与它相关呢?本...
- Windows 11 KB5053598更新:安全补丁还是系统噩梦?
-
2025年3月11日,微软发布了Windows1124H2的强制性更新KB5053598,作为“周二补丁日”(PatchTuesday)的一部分。然而,这款本应提升系统安全性的更新却引发了广泛的...
- 飞牛OS入门安装遇到问题,如何解决?
-
之前小编尝试了用旧电脑装飞牛OS安装之前特意查了一些硬件要求飞牛OS目前支持主流的x86架构硬件主机需能连网线飞牛OS暂时不支持只有无线网卡的安装貌似很多小伙伴在一开始安装就卡住了那今天咱们汇总分...
- 几种常见的电脑开机黑屏显示白色英文字母解决方法
-
当电脑开机出现黑屏并显示白色英文字母时,通常表示系统启动过程中遇到了错误。以下是几种常见原因及对应的解决方法,按照排查顺序整理:一、检查外接设备与硬件连接可能原因:外接U盘、移动硬盘等未拔出,或内部硬...
- 电脑启动出现问题,为什么都要先检查BIOS?
-
【ZOL中关村在线原创技巧应用】最近在回答问题的时候,总会发现很多朋友都在问“电脑无法正常开机怎么办?”这样类似的问题,而许多DIY大佬的回复总会出现一条高频建议“先检查BIOS”。但对于许多普通用户...
- 教你怎么用JavaScript检测当前浏览器是无头浏览器
-
什么是无头浏览器(headlessbrowser)?无头浏览器是指可以在图形界面情况下运行的浏览器。我可以通过编程来控制无头浏览器自动执行各种任务,比如做测试,给网页截屏等。为什么叫“无头”浏览器?...
- 12个高效的Python爬虫框架,你用过几个?
-
实现爬虫技术的编程环境有很多种,Java、Python、C++等都可以用来爬虫。但很多人选择Python来写爬虫,为什么呢?因为Python确实很适合做爬虫,丰富的第三方库十分强大,简单几行代码便可实...
- 运维的报表之路,用 node.js 轻松发送 grafana 报表
-
在运维过程中,无论是监控还是报表,都会有一些通过邮件发送图表的需求,由于开源的zabbix,grafana和kibana等并不完全具有“想发送哪儿就发送哪儿”的图片生成功能,在grafana...
- C#基于浏览器内核的高级爬虫(c#爬取网页内容)
-
基于C#.NET+PhantomJS+Sellenium的高级网络爬虫程序。可执行Javascript代码、触发各类事件、操纵页面Dom结构、甚至可以移除不喜欢的CSS样式。很多网站都用Ajax动态加...
- 如何优化一个秒杀项目?(秒杀实现思路)
-
问题1:使用jmeter性能压测,定位瓶颈代码步骤流程:线程组--->Http请求--->查看结果树--->聚合报告tips:host的文件--->优先调用映射,减少DNS的时...
- 一周热门
-
-
Python实现人事自动打卡,再也不会被批评
-
Psutil + Flask + Pyecharts + Bootstrap 开发动态可视化系统监控
-
一个解决支持HTML/CSS/JS网页转PDF(高质量)的终极解决方案
-
【验证码逆向专栏】vaptcha 手势验证码逆向分析
-
再见Swagger UI 国人开源了一款超好用的 API 文档生成框架,真香
-
网页转成pdf文件的经验分享 网页转成pdf文件的经验分享怎么弄
-
C++ std::vector 简介
-
python使用fitz模块提取pdf中的图片
-
《人人译客》如何规划你的移动电商网站(2)
-
Jupyterhub安装教程 jupyter怎么安装包
-
- 最近发表
- 标签列表
-
- python判断字典是否为空 (50)
- crontab每周一执行 (48)
- aes和des区别 (43)
- bash脚本和shell脚本的区别 (35)
- canvas库 (33)
- dataframe筛选满足条件的行 (35)
- gitlab日志 (33)
- lua xpcall (36)
- blob转json (33)
- python判断是否在列表中 (34)
- python html转pdf (36)
- 安装指定版本npm (37)
- idea搜索jar包内容 (33)
- css鼠标悬停出现隐藏的文字 (34)
- linux nacos启动命令 (33)
- gitlab 日志 (36)
- adb pull (37)
- table.render (33)
- uniapp textarea (33)
- python判断元素在不在列表里 (34)
- python 字典删除元素 (34)
- react-admin (33)
- vscode切换git分支 (35)
- vscode美化代码 (33)
- python bytes转16进制 (35)