电商秒杀系统性能优化实战
电商秒杀系统性能优化实战
一、了解秒杀业务
1、秒杀场景
价格低、库存少、高并发、量少人多
技术特点:
短时高并发
读多写少
防止用户重复购买,也不能超卖
哪些属于秒杀业务:
电商平台抢购商品
12306抢购
会议室预定
演唱会门票
一线支援名额618
大学生抢课
2、秒杀的整体业务流程
①创建秒杀活动
首先有秒杀活动模块,创建秒杀活动模块时一定要看库存。如果库存够,创建秒杀活动,创建秒杀活动时进行商品的预热,将商品放到redis缓存中,因为redis的QPS是mysql的百倍。Mysql QBS一般是1000左右,redis是10W。
②用户开始抢购
对用户进行鉴权,包括:1)拦截同一用户对商品的多次抢购。活动id+用户id放到缓存里面维护。2)机器防刷。如果是第一次抢购,判断缓存中的商品是否被抢空。没有被抢空,进行扣减库存。
③下单
下单是异步下单,放到MQ,然后打到订单模块进行消费。先生成订单号,返给前端界面,告诉你抢购成功,订单处理中,请耐心等待,前台进行轮询,查询是否下单成功,增加用户体验。
④其他业务
1)通知用户下单成功
一种是用户端界面轮询,一种是发邮件
邮件发送订单消息可以异步发送,使用MQ。不是这种强相关的业务都可以通过异步处理。
618要实时知道销售情况,使用Websoket长链接,实时监控情况,在大屏上展示。后台主动向前端推。
2)用户超时支付
主要是补偿库存和允许该用户继续下单。
④支付成功后发货
二、秒杀的架构演变
1、单体架构
Manager 负责数据源选择,dao负责数据操作。
1)Tomcat
一个请求打到tomcat后,tomcat去请求数据库,连接数据库肯定会有数据库连接池,连接池调优,多个用户请求tomcat,涉及到线程池。Tomcat默认的线程池的数量是150,tomcat默认的最大连接数是1W。
如果占满还有等待数。
池化技术,可以资源复用、提高效率、可以降低创建和销毁的开销。
Tomcat调优,线程池参数
2)MySQL优化,加索引、联合索引,数据库表不能有外键,用业务保证,数据库不能写存储过程。索引的B+树。
3)引入缓存技术,引发数据一致性的问题,缓存失效的问题,如果缓存失效可能出现雪崩。
作为单体架构,性能应该压榨到及至。
Jvm调优:jvisualvm监控。
2、微服务架构
垂直拆分,根据业务垂直拆分。拆开后,可以对每一个模块进行集群化部署。
集群部署,集群部署如果用到定时器,如何保证只消费1次。常用的一种解决方式就是redis的分布式锁。
Mysql、redis也可以做集群化部署。Mysql用mycat进行分库分表。单机故障是不允许的。
三、秒杀项目代码架构
1、miaosha-parent(统一版本管理)
pom.xml
README.md
RELEASE.md 版本升级,版本迭代
2、miaosha-common (通用功能管理)
1)通用工具类
2)统一异常处理(自定义异常,错误码)
3)常量
4)分页、统一响应数据格式
5)鉴权
6)通用枚举
3、miaosha-manager (业务)
manager-api(发布 double)
manager-api-imply
manager-dao
manager-domain
manager-dto
manager-service
manager-manager(数据源切换)
manager-utils
manager-web
manager-rpc(调用其它模块的double)
pom.xml
RELEASE.md 版本升级,版本迭代
分支管理
四、搭建秒杀项目1.0版本
1、HandlerMethodArgumentResolver
HandlerMethodArgumentResolver是用来处理方法参数的解析器,包含以下2个方法:
supportsParameter(满足某种要求,返回true,方可进入resolveArgument做参数处理)
2、全局异常处理
@ControllerAdvice
使用该注解表示开启了全局异常的捕获。
在方法上使用@ExceptionHandler(value =Exception.class),注解后,捕获异常的类型即可对这些捕获的异常进行统一的处理。
五、Jmeter压测,找到系统瓶颈
1、测试redis性能
redis装在docker里面
①查看docker运行的容器
docker ps -a
②进入容器
docker exec -it 容器id /bin/bash
③压测命令
redis -benchmark -h 127.0.0.1 -p 6379 -c 100 -n 10000
2、测试项目
①添加线程组
②http请求
③ 监听器(聚合报告)
3、测试秒杀性能
①写测试类,生成user
类上加上注解 @SpringBootTest(class={ShopMiaoShaApplication.class})
如果需要注入其它方法,加上@RunWitn(SpringRunner.class)
方法直接用@Test
把session放到redis里面就是分布式session。
六、项目优化1.0版本升级
1、接口优化
1)库存预热
2)内存标记降低缓存访问
3)MQ异步下单,提升用户下单
2、页面优化
1)页面缓存
2)URL缓存
3)对象缓存
4)静态化
5)静态资源优化
6)Cnd优化
七、tomcat 优化、恶意流量防刷
八、课程总结、面试的注意事项