分布式项目——电商秒杀
概述
主要是实现电商网站的秒杀业务,去思考在高并发场景下如何是开发我们的项目。此项目我们用到的技术是SpringBoot+Redis+RabbitMQ+Mysql+Tomcat,压测就用jmeter。
开发过程:
1.项目框架的搭建
1.1Spring Boot环境搭建
1.2集成Thymeleaf,Result结果的封装:Result类封装返回结果、状态码
1.3集成Mybatis+Druid
1.4集成Jedis+通用缓存key封装:用缓存key进行统一封装,防止代码混乱导致key被覆盖
2.实现登录功能
2.1数据库设计:用户表
2.2明文密码两次MD5处理:一次在客户端到服务端,一次在服务端到数据库
2.3JSR303参数检验+全局异常处理器:统一处理系统异常
2.4分布式session:建立token,这是在分布式开发中很重要的一个知识点
3.实现秒杀功能
3.1数据库设计:商品表、订单表、秒杀商品表、秒杀订单表(秒杀商品表和秒杀订单表单独成一张表,通过id关联商品表,避免对商品表的频繁改动字段而导致程序的改动,从而让商品表相对稳定)
3.2商品列表页
3.3商品详情页
3.4订单详情页
4.JMeter压测:这里我们先对普通的电商下单方式进行压测,后面再来比较我们优化后的接口的QPS
4.1自定义变量模拟多用户
4.2Redis压测
5.页面优化技术
5.1页面缓存+URL缓存+对象缓存:我们这里对商品列表页加页面缓存
5.2页面静态化,前后端分离(利用浏览器缓存,这里用Ajax):我们这里对商品详情页加客户端缓存
5.3静态资源优化
5.4解决卖超问题:sql加库存数量判断,简单的说我们可以在对应的减库存sql语句后面加stock_count>0,来防止秒杀商品表里的库存字段减到小于0;其次我们加唯一索引,防止同一个用户重复秒杀到商品。
6.秒杀接口优化
6.1Redis预减库存减少数据库的访问:将库存缓存到redis,做预减操作
6.2内存标记减少Redis访问:本地创建一个hashmap用来标记,当预减到小于0时,改变hashmap中value值得状态,通过状态判断下次用不用访问redis,这样可以减小redis的负载
6.3请求先入队缓冲,异步下单:这里我们使用RabbitMQ,如果并发为10万级以上的话,可以考虑用kafka或者RocketMQ
6.4Nginx水平扩展:这也是一个优化点,但是在这里我只部署了一台Tomcat,没有做主从,所以优化不大,就暂时不做这个点
6.5压测:可以很直观的感受到qps的提升,当然我进行压测是在虚拟机上,而且虚拟机上安装软件较多,也没有做主从,导致效果没有那么明显,只提升了一倍不到,如果你想要看到效果,你可以做主从、然后保证你的linux性能,效果就会更明显。
这里提供一个思路:减少数据库的访问
(1)系统初始化,把商品库存数量加载到redis中;
(2)收到请求,redis预减库存,库存不足,直接返回,否则进入(3);
(3)请求入队,立即返回排队中;
(4)请求出队,生成订单,减少库存;
(5)客户端轮询,是否秒杀成功。
7.安全优化
7.1秒杀接口地址隐藏
7.2添加数学公式验证码
7.3接口限流防刷
最后附上github地址,里面注释给的很详细,大家可以down下来看看。
项目的github地址:https://github.com/Happy-Ape/flashSale