项目和1013

这里写目录标题

  • 项目
    • 采用Nginx做反向代理、以及搭建Tomcat服务器集群,实现负载均衡和动静分离
      • 4.3
      • 4.7
      • 相关的八股
    • 动静分离
      • 4.12
      • 5-4 Redis集中式缓存商品详情页
      • 5-7 开启本地缓存
      • 5-11 开启本地缓存
    • 采用RabbitMQ实现异步消息扣减数据库内库存
      • 7-4 同步进缓存,下单减库存
      • 7-5 利用roketmq,异步扣减数据库
      • 8-2 事务性消息应用 transcationMQProducer
    • 8-3 库存流水状态
    • 8.6库存数据最终一致性保证
    • 采用Redis实现流量削峰和限流
      • 9-1秒杀令牌
  • 面试
    • 1.问了怎么保证幂等?
    • 2.数据库扣减库存怎么实现一致性
    • 3. 多级缓存的是怎么做的?为什么还要再多加一层本地缓存呢?对性能提升大吗?QPS 提升多少?
    • 4.超卖问题

项目

采用Nginx做反向代理、以及搭建Tomcat服务器集群,实现负载均衡和动静分离

4.3

项目和1013_第1张图片
项目和1013_第2张图片
ajax前端访问miaoshaserver的域名,niginx通过动态的反向代理请求,访问不同的服务器
H5(STATIC)若访问miaoshaserver/resources的域名,nginx会直接从本地磁盘中获得静态资源

4.7

4-7:
项目和1013_第3张图片1. 通过upstream server添加对应的服务器,weight表示权重
项目和1013_第4张图片

相关的八股

反向代理:客户端将请求发送到反向代理服务器,由反向代理服务器去选择目标服务器,获取数据后再返回给客户端。对外暴露的是反向代理服务器地址,隐藏了真实服务器 IP 地址。反向代理“代理”的是目标服务器

动静分离

将静态资源部署在Nginx上,当一个请求来的时候,如果是静态资源的请求,就直接到nginx配置的静态资源目录下面获取资源,如果是动态资源的请求,nginx利用反向代理的原理,把请求转发给后台应用去处理,从而实现动静分离。

4.12

4-12项目和1013_第5张图片项目和1013_第6张图片

redis:集中式缓存中间件

项目和1013_第7张图片先存入redis,返回给前端
项目和1013_第8张图片
前端获取token再发送给后端
项目和1013_第9张图片后端的获取对应的token,根据token从redis里获取对应的用户

第五章:本地热点缓存(JVM的缓存–堆栈信息)

5-4 Redis集中式缓存商品详情页

5-4:Redis集中式缓存商品详情页
利用redis在controller层的时候,之间从redis中获取,减少对数据库的依赖
项目和1013_第10张图片

5-7 开启本地缓存

5-7:开启本地缓存接口:cacheService
项目和1013_第11张图片
本地缓存用的就是tomcat的堆内缓存
利用Guava cache 实现
项目和1013_第12张图片先去本地缓存(不存在)–再取redist(不存在)-- 最后再去数据库,最后记得反向SET到对应的库中

项目和1013_第13张图片

5-11 开启本地缓存

5-11:nginx 本地缓存 – 语言:nginx lua
项目和1013_第14张图片

1.在nginx openresty-- redis

项目和1013_第15张图片openresty对redis脚本的编写,(连接上面的redis slave)
项目和1013_第16张图片
==分级理解:==前端访问,先从redis slave读数据,没有 ,就去本地缓存读数据,再没有,就去redis中读数据,再没有才回去数据库中读数据。

采用RabbitMQ实现异步消息扣减数据库内库存

7-4 同步进缓存,下单减库存

7-4
项目和1013_第17张图片

1.将库存放入缓存中(这里是在cintroller方法调用下面serverce,使得库存进入缓存)
项目和1013_第18张图片

2.减去对应的Redis库存

项目和1013_第19张图片课程中通过redis的原子性,先减库存判断剩余数量是否大于0来防止超卖。本项目中只要控制住redis 就不会超卖 redis挂了就不可交易 因此不会超卖

会出现数据库记录不一致的问题

7-5 利用roketmq,异步扣减数据库

7-5
项目和1013_第20张图片
项目和1013_第21张图片

  • 分别构建MqProducer和MqConsumer类
    项目和1013_第22张图片
  • ItemserveImpl,redis扣减库存成功,result>0,就会调用上面的方法
    项目和1013_第23张图片如果Mq失败,redis需要回滚
  • Consumer收到消息调用数据进行库存扣减
    项目和1013_第24张图片
    因为redis和数据库扣减 与 订单入库写在一个事务当中,如果redis和数据库都扣减成功了,但是订单入库出现了问题(买家取消支付),redis和数据库没有对应的回滚措施,就会出现少买的情况

8-2 事务性消息应用 transcationMQProducer

事务型:保证数据库数据提交了,对应的消息必定会发送成功的。数据库事务回滚,消息必定不会发送成功
项目和1013_第25张图片
1.上述首先往消息队列中投递消息,消息被维护在broker 中间件上面 2. 再去执行executelocalTransaction方法
在prepare的状态下会去执行executeLocalTransaction方法
项目和1013_第26张图片

  • 在oredercontroller层调用mqproducer.transcation扣减库存的操作
    如果上述订单入库执行了很久, mqproducer还有一个 c h e c k L o c a l T r a n s a c t i o n checkLocalTransaction checkLocalTransaction方法,去判断上面的方法是否入库成功,判断要返回三种情况的哪一种

如何判断,查看是否生成对应的订单流水
项目和1013_第27张图片

8-3 库存流水状态

引入库存流水,
项目和1013_第28张图片
订单入库成功之后,
项目和1013_第29张图片
后面需要重写一下executelocalTransaction和check方法

8.6库存数据最终一致性保证

少卖不可超卖

项目和1013_第30张图片
触发15分钟以上,需要释放掉,将数据回滚回去
项目和1013_第31张图片

  • 加入库存售罄表示(redis)

项目和1013_第32张图片

  • 在生成库存流水之前,先判断redis中是否存在售罄表示
  • 项目和1013_第33张图片

采用Redis实现流量削峰和限流

9-1秒杀令牌

项目和1013_第34张图片
在业务层生成token,并且设置时间为五分钟
项目和1013_第35张图片
在ordercontroller判断前端送来的token是否与redis中一致
项目和1013_第36张图片
问题*

项目和1013_第37张图片
令牌数量
项目和1013_第38张图片

生成token前先判断count的数量
项目和1013_第39张图片
项目和1013_第40张图片

  • 秒杀令牌:通过promoID,userID,ITEMiD生成一个token,放入redis中
  • 根据商品的库存设置对应令牌的数量(先计算大闸count的数量在获取对应的token)
  • 队列泄洪:依靠排队和下游拥塞窗口调整队列释放流量大小(设置一个线程池大小xx,以及拥塞窗口为xx的等待队列)
    项目和1013_第41张图片
    异步操作:调整队列释放流量的大小,在队列的消费端,一次性取多个,交给下游的多线程处理,取得大小就是一个拥塞窗口,

项目和1013_第42张图片

项目和1013_第43张图片

面试

1.问了怎么保证幂等?

2.数据库扣减库存怎么实现一致性

3. 多级缓存的是怎么做的?为什么还要再多加一层本地缓存呢?对性能提升大吗?QPS 提升多少?

参考1:
参考2:

4.超卖问题

库存售罄的时候,是通过Redis来读出库存数量,如果大于0,那就将库存扣减掉,然后当为0时,就在redis中打入售罄标识

在ordercontroller中,先判断redis中是否存在售罄表示

通过redis的原子性,先减库存判断剩余数量是否大于0来防止超卖。
因为同一个redis,两个不同的服务,同时执行incre和decre,同一个redis,两个不同的服务,同时执行incre和decre,

你可能感兴趣的:(java)