秒杀活动:
模拟场景:
商城做一个秒杀活动,秒杀的商品数量为10,秒到即得。
方案:
1、应用层做首次过滤
因为考虑到处理的失败,我们要给缓存开的总数比10稍大是最好的,那我们就给队列开的总数是50。秒杀开始后,我们的队列只接收前面50个请求,当数量满50后,在请求就返回已秒杀完。如果一瞬间的并发大于50,我们就随机取50个放入队列。
缓存的处理是在内存上处理的,效率非常高,但是在这个层面处理过之后要二次请求,可能会有稍许延迟。
2、数据层做二次过滤
- 从50个中随机或者排序的方式,二次“并发”按队列执行下单,这时候可以考虑使用文件锁。入库时也可考虑使用乐观锁、自定义锁、限制条件等。
经过首次处理后的数据量已经非常小了,直接操作数据库的话压力会小很多,二次过滤也能尽可能的保证数据不超出。 - 分库存,比如总共有50000个秒杀名额,可以分50份,放在redis上的50个不同的key,那么每份上1000个库存,用户进入秒杀流程后随机到其中一个库存来修改,这样有50个库存数来竞争,缩短请求的排队时间。
读写分离的数据一致性问题:
- 适当放弃一致性:在一些实时性要求不高的场合,我们适当放弃一致性要求。
- 可以通过程序控制,将强一致性要求的功能(比如存钱、取钱)的读写操作均指向主数据库,或者将写操作采用“双写”的方式实现;而弱一致性(最终一致性)要求的功能(比如更新微博(写)、金融查询账户(读))实现读写分离。
一、http连接池优点:
1、降低延迟:如果不采用连接池,每次连接发起Http请求的时候都会重新建立TCP连接(经历3次握手),用完就会关闭连接(4次挥手),如果采用连接池则减少了这部分时间损耗,别小看这几次握手,本人经过测试发现,基本上3倍的时间延迟
2、支持更大的并发:如果不采用连接池,来一个请求,就创建一个连接,导致资源瓶颈,无法建立新的连接。所以采用连接池,连接的复用,可以提高并发访问量。
SpringBoot,数据库MyBatis.
用户浏览商品列表,点击秒杀,如果秒杀成功,就会下单,显示在订单详情页中。
系统压测:并发情况下
缓存优化:先写数据库还是日志文件?缓存一致性问题
消息队列:12306,排队中,大并发出现在数据库中,
接口安全:
一、项目框架搭建
集成Thymeleaf, Result结果封装
集成Mybatis
集成Redis
二、登录功能
明文密码两次MD5处理
JSR303参数检验+全局异常处理器
分布式Session
三、实现秒杀功能
数据库设计
商品列表页
商品详情页
订单详情页
秒杀功能实现:
- 前端页面点击“秒杀”,传入后端一个goodsId,然后后台通过id找到相应秒杀活动的一条记录,然后判断库存是否>0。
- 判断是否已经秒杀到了,从OrderService中查找,通过userId和goodsId查找,看能否找到。
- 减库存,写入秒杀订单:一个事务中,这两 个操作必须同时成功或失败。MiaoShaService,
订单详情页:
四、JMeter压测
添加线程组:模拟多并发。
自定义变量模拟多用户:
redis压测:
查看服务器起来了没: ps -ef | grep redis
redis 的QPS很高啊
spring boot打war包:
性能参数:
1 并发量:即系统同时处理事务的能力,通常我们用QPS(query per second)来表示,也有地方用RPS(request per second),TPS(吞吐量,准确来说应该是吞吐率)来表示.
但其实我们拿到的qps/tps/rps等大多都是1s内的处理能力,并不等同于同一时刻处理的请求。jmeter中定时器里有元器件可以进行控制,等待请求n个时,一同向服务器发请求。
2 响应时间:客户端发出请求,到接收到返回的时间。比如我访问baidu.com,按下enter之后等了1s打开了百度首页,那响应时间就是1s。这个过程的时间包括=网络传输时间+服务处理请求时间;尤其对于一个非web的请求,如果我本身的网络环境不好,就会导致传输时间过长,所以也有人仅用服务处理请求时间来表示响应时间。我认为两者均可,只要在报告里写清楚测试环境和字段含义即可。
并发时,QTS,TPS(一秒钟的订单量)
3. cpu:计算机的逻辑处理能力。CPU利用率反映的是CPU被使用的情况,当CPU长期处于被使用而没有得到足够的时间休息间歇,那么对于CPU硬件来说是一种超负荷的运作,需要调整使用频度。
4 网络I/O: 磁盘通常是计算机最慢的子系统,也是最容易出现性能瓶颈的地方,因为磁盘离 CPU 距离最远而且 CPU 访问磁盘要涉及到机械操作
对商品列表压测: 10个线程访问商品列表,添加监听器,图形结果,
添加线程数,
添加HTTP默认值,服务器名称localhost
五、页面优化技术
并发:减少对数据库的访问,可以提高访问速度
- 页面缓存+URL缓存+对象缓存
页面缓存:浏览器在对资源的第一次请求之后,会把资源的一部分存储在计算机的临时文件空间,当再次请求的时候,按照特定的策略加载缓存中的资源,从而减少http请求的次数与传输的数据量,提高了浏览效率。缓存时间短
(1)访问页面,先从缓存找,如果找到:直接返回,如果是空:手动渲染
缓存时间短,商品列表,缓存前一两页。自动失效。
(2)热点对象缓存。秒杀用户缓存, 取缓存,通过id获取对象,设置过期时间:永久有效。
(3)商品页面缓存。 - 页面静态化,前后端分离:
- 静态资源优化,
- CDN优化
热点数据缓存:对象缓存
根据Token获取用户,HttpServletResponse
更新数据库,更新缓存,(假如)
页面静态化:前后端分离,利用浏览器缓存
数据库唯一索引:防止用于插入多条记录
六、接口优化
Redis预减库存减少对数据库的访问
内存标记减少Redis访问
RabbitMQ队列缓存,异步下单,增强用户体验
访问Nainx水平扩展
压测
秒杀接口优化思路: mycat 减少对数据库的访问
(1)系统初始化,把商品库存数量加载到Redis
(2) 收到请求,Redis预减库存,库存不足,直接返回,否则进入3
(3)请求入队,立即返回排队中。
(4)请求出队,生成订单,减少库存
(5)客户端轮询,是否秒杀成功。
超卖问题:
(1)数据库加唯一索引:防止用户重复该买
(2)SQL加库存数量判断,防止库存编程负数
七、安全优化
秒杀接口地址隐藏
数学公式验证码(输入验证码延长访问时间)
接口防刷(限制用户刷新次数)