python攻城狮2019

百度云盘

 

在看本文章之前,需要了解Spring boot搭建和使用 ,本篇文章核心问题是如何解决高并发问题。

开发环境:redis缓存4.0.1,Rabbitmq消息队列,Erlang(这个跟MQ环境有关,先安装Erlang,再安装MQ),mysql5.7,JDK1.8(Spring boot要用1.8以上的版本)

开发框架:Spring boot 2.0.4 , mybatis,前端页面:thymeleaf展示信息

一:问题

首先我们要考虑的是为什么要解决高并发,高并发瓶颈出现在哪里,有了解过的朋友肯定知道是在数据库,因为在大量请求去操作数据库时会出现数据的错乱,超卖,系统崩溃,mysql死锁等现象。

二:思路

既然知道问题出现在哪之后,就要对症下药,减少对数据的访问。在这里提供一下解决思路:

1. 页面静态化:就是将整个页面存储到redis中,下次访问时去读取redis中的页面值

2. cdn:主要对整个网站的静态资源文件进行加速,如图片,css,js等(去阿里看教程)

3.数学验证码:用户在计算验证码结果时可以减少大量请求同时进入,减少redis, mysql,服务器的压力。

4:库存标识:这是一个巨大优化,通过标识来判断redis的库存是否足够,如不足就中断去读取redis库存。例:boolean over = map.get(goodsId);当我们map通过key读取到value值为true的时候,就返回错误提示给用户, if(over) { return Result.error(‘库存不足’); }.....这样不管以后有多个请求进入都只运行两行代码,以下的操作无法进入。

5.生成动态url:主要是防止恶意用户通过固定url进行提前秒杀商品(安全方面问题这个不可掉以轻心,你连安全措施都没做好以下的那些操作都是白搭的)

6. redis预减库存::在用户秒杀商品前去redis获取当前的库存数量,然后在秒杀时候直接减去redis存储的库存(大家放心这里Redis和MySQL数据是同步的,只要进入MQ队列操作完成下单,MySQL数据库会-1数量),从而避开去MySQL读取库存数据。

7. MQ消息队列:它是一个中间消息键,通过生产者发送消息给消费者,进行业务操作,而生产者无需知道执行结果,也就是用户点击秒杀之后等待处理结果,之后再去轮询查询处理结果(异步操作),这样就避开了不断请求去操作数据库。(这里的轮询查询也是直接从redis里面去查询,因为秒杀成功之后会将秒杀的结果放到redis中,轮询时候通过key去查询)

8. Nginx: 解决高并发的好方法,也就是我们多增加几个tomcat服务器。当用户访问的时候,请求可以提交到空闲的tomcat服务器上。

三:实现

1. 页面的静态化:很多人说怎么页面静态化,其实页面静态化就是将整个页面储到redis中,我们访问这个接口的时候就直接去获取redis的中页面,这样大大提高了访问页面的速度。如下图:

2. 预先获取秒杀商品信息,库存存储到redis中,怎么个预先法?在启动项目时在MiaoshaController调用InitializingBean接口,这个主要是在启动项目时去查询数据库中所有的秒杀商品的信息,库存等。大家别小看那一行标识代码,这可是一个巨大转折点的优化。为什么呢?接着看下去。如下图:

3. 数学公式验证码,这个也是减少大量请求的方法,因为你要去计算结果,想想几秒钟时间我可以减少多少访问请求,这个数学公司验证码自己去百度找下,同样把生成的验证码结果存储到redis中,判断时在去redis中获取结果对比验证码结果。

4.生成动态url,防止恶意用户提前秒杀商品! 我们应该先在访问秒杀业务时去生成一个动态的url,这样做可以防止恶意用户去通过固定url去提前秒杀商品。方法如下图:

html:

5.当我们生成动态Url之后,我们进行秒杀业务的操作,将我们的url传递到后台进行验证是否与之前所生存的一致,并且进行MQ消息队列处理请求 如下图:

我们执行完秒杀业务层之后,将结果0返回到js中,其实这时候mq已经异步进行操作去下订单操作了,js去轮询查询数据库中是否已经下订单成功,相当是说下订单操作和js去查询下订单信息是互不相关的,这也就说不管有没有秒杀是否成功都先返回一个0结果消息。当然这里还有个问题,就是我们如何区分秒杀的操作是在排队中呢还是库存已经秒杀完毕了呢?请接着继续看下去!

发布了21 篇原创文章 · 获赞 43 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/JggAkk/article/details/103747155