gulimall-秒杀服务

P310、商城业务-秒杀服务-后台添加秒杀商品

秒杀具有瞬间高并发的特点,针对这一特点,必须要做限流 + 异步 + 缓存(页面静态化)

  • 独立部署

限流方式:

  1. 前端限流,一些高并发的网站直接在前端页面开始限流,例如:小米的验证码设计

  2. nginx 限流,直接负载部分请求到错误的静态页面:令牌算法 漏斗算法

  3. 网关限流,限流的过滤器

  4. 代码中使用分布式锁-信号量

  5. rabbitmq 限流(能者多劳:chanel.basicQos(1)),保证发挥所有服务器的性能。

  6. 上架秒杀商品(价格和平常不一样)

  7. 后台管理系统的优惠营销-每日秒杀,可以录入每天的秒杀场次

  8. 通过点击后台管理页面点击查看路径,

  9. 添加网关路由 api/coupon/** 路由到coupon服务

  10. 增删改查场次信息,自动生成,可以直接用

  11. 关联商品:给场次新增一些秒杀哪些商品的信息,价格,件数

  12. 点关联,查询的是所有场次的商品信息,需改为所查场次的关联商品信息。通过传入的promotionSessionId,修改查询条件
    http://localhost:88/api/coupon/seckillskurelation/list?t=1634368262922&page=1&limit=10&key=&promotionSessionId=1

  13. 确认关联商品的增加、修改可以使用

秒杀场次表sms_seckill_session
场次商品关联表sms_seckill_sku_relation

P311、商城业务-秒杀服务-定时任务&Cron表达式

  1. 创建秒杀微服务(独立模块、独立部署)
    Springboot模块+SpringBootDevTools+Lombok+SpringWeb+SpringDataRedis+OpenFeign
  2. 添加依赖common并排除seata,common依赖mybatis,需排除数据源自动配置
    @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
  3. 配置application.properties,服务名,端口号,nacos.discover地址端口,redis地址,添加服务发现注解@EnableDiscoveryClient

定时任务(quartz流行框架,java原生timer类,每天对账,每月财务汇总,)
Cron表达式 秒分时日月周 年(spring不支持)

枚举:1,2,3
范围:3-8
任意:*

步长:7/6,第七秒启动,每隔6秒
防止日和周几冲突:一个精确(或*),另一个?

最后一个:L,***?*3L (1表示周日,2表示周一,3表示周二,3L表示最后一个周二)
工作日:W, (LW最后一个工作日)

第几个:# ***?*5#2:第2个周4

网上有cron表达式生成器

秒杀商品定时上架->定时任务查询需要上架的秒杀商品->封装最新的秒杀商品信息保存到redis中->设置秒杀商品分布式信号量作为库存扣减信息->结束
上架放到缓存,商品数据从缓存拿,库存也上架到缓存,扣库存从缓存扣

P312、商城业务-秒杀服务-SpringBoot整合定时任务与异步任务

解决:使用异步+定时任务完成定时任务不阻塞功能

类上面@EnableScheduling 开启定时任务
方法上面加@Scheduled(cron="") 开启一个定时任务
自动配置类TaskSchedulingAutoConfiguration
在这里插入图片描述
3、让定时任务异步执行
异步任务
类上面@EnableAsync 开启异步任务功能
方法 @Async 给希望异步执行的方法上标注,默认线程池,核心大小8
自动配置类TaskExecutionAutoConfiguration 属性绑定在TaskExecutionProperties
在这里插入图片描述

注意:2)经常不生效。有些版本不好使,有些版本好使。
在这里插入图片描述

P313、商城业务-秒杀服务-时间日期处理

定时上架类,定时配置类
上架最新3天(提前预告)
当天00:00:00-23:59:59
明天00:00:00-23:59:59
后天00:00:00-23:59:59
重复上架无需处理

远程调用优惠服务获取活动(秒杀服务没有数据库,在优惠服务的数据库里)
扫描三天的活动 sql条件between 2020-02-19 00:00:00 and 2020-02-21 23:59:59含头不含尾
LocalDate
LocalTime
LocalDateTime
时间最好格式化 start.format(DateTimeFormatter.ofPatter(”yyyy-MM-dd HH:mm:ss”))

在这里插入图片描述
在这里插入图片描述

P314、商城业务-秒杀服务-秒杀商品上架-1

优惠服务里,查询每一个活动关联的所有商品(判断活动 list!=null&list.size()>0)遍历
秒杀服务远程调用该接口
秒杀服务封装返回的数据信息(秒杀活动的信息,sku信息vo)

上架商品(缓存到redis,使用StringRedisTemplate(string,string) )
缓存活动信息
Key(活动开始结束时间)
Value(活动的所有商品信息)

缓存活动的关联商品信息

在这里插入图片描述

redis缓存2个信息
1、缓存活动信息key:seckill:sessions:start_endtime
value:[sessionId_skuIds]
2、活动里的商品信息:seckill:skus,Hash结构
缓存商品:
1)sku的基本信息
2)sku的秒杀信息
3)设置当前商品的秒杀时间信息
4)随机码
使用JSON字符串
新建Redis保存TO(秒杀商品详细信息,sku的详细信息,SkuInfoVo)
新建SkuInfoVo ,商品详细信息
在这里插入图片描述

P315、商城业务-秒杀服务-秒杀商品上架-2

  1. Sku的基本信息,调用远程商品服务
  2. 设置当前商品的秒杀时间信息
  3. 随机码
    seckill?skuId=1,秒杀接口暴露,商品id暴露,容易招致攻击,无限重试发这个请求,时间一到肯定抢到。
    seckill?skuId=1&key=随机码 秒杀开启那一刻暴露随机码

秒杀库存 - > redisson分布式锁:分布式信号量。根据商品随机码扣库存,而不是商品ID
使用库存作为分布式锁-信号量:限流
信号量id:seckill:stock+随机码
使用随机码减信号量。
在这里插入图片描述

P316、商城业务-秒杀服务-秒杀商品上架-3

P317、商城业务-秒杀服务-幂等性保证

上架只需要一台服务器上架就可以:分布式锁处理
在这里插入图片描述

上架时判断存不存在(判断条件使用 场次-商品id,注意UUID)

P318、商城业务-秒杀服务-查询秒杀商品

秒杀页面展示商品:返回当前页面时间需要展现的秒杀商品信息
1)确定当前时间属于哪个秒杀场次
2)获取这个秒杀场次需要的所有商品信息

秒杀开始页面需要随机码
秒杀预告页面不能随机码

页面展示商品信息
配置hosts,Linux(nginx),配置网关,秒杀请求路由至秒杀服务
修改前端页面

P319、商城业务-秒杀服务-秒杀页面渲染

商品详情页展示秒杀预告
1)页面展示完成后给秒杀服务发送Ajax请求查询是否参与秒杀
2)商品服务远程调用查询秒杀服务(采取这个)

找到所有需要参与秒杀的商品的key(绑定hash操作)
使用正则匹配
商城模块新建vo接收数据
前端页面展示(预告和正在秒杀显示不一样)
注意时间格式化

P320、商城业务-秒杀服务-秒杀系统设计

抢购功能。

不管是不是“立即抢购”按钮,都是加入购物车,价格是秒杀价格
关注重点不在业务,而在于高并发。
在这里插入图片描述
2的解决方法:1、连接加密,生成MD5或UUID
2、加随机码,只有活动开始才生成
3:还可以redis集群,分片的高可用
4:nginx存静态,可以复制多份
上线后,更好的条件,CDN网络:比如阿里云

在这里插入图片描述

恶意请求拦截,网关

前端限流:点一下后不能再点,点一下等1秒 等等。但知道点按钮发什么请求,限不住恶意脚本。
队列削峰:杀手锏

P321、商城业务-秒杀服务-登录检查

判断活动时间,修改按钮
抢购链接需要带随机码,场次和商品id
前端页面(url)编写
前端设置登录拦截,没登陆跳转登录页面
后端创建拦截器判断是否登录,拦截器创建后一定要配置到web中(创建WebConfig 实现WebMvcConfig,注入拦截器…)
使用SpringSession依赖(session使用redis保存),获取前端cookie
在这里插入图片描述
拦截器必须添加到这里才能生效。

P322、商城业务-秒杀服务-秒杀流程

第一套流程:加入购物车,跳到订单确认页,然后结算、支付(和以前业务整合)
在这里插入图片描述

优点:错峰,业务统一,数据模型、、、和普通商品只差价格、库存
缺点:增加购物车、订单等服务的压力

第二套流程:适用超高并发(独立业务)
点击立即抢购,请求发给秒杀系统,开始抢购,抢购先做一系列判断,比如登录,如果登录成功,再来校验秒杀请求合法性,校验包括当前秒杀商品有没有到秒杀时间,随机码和skuid的对应关系对不对,包括这个人是不是已经秒杀过商品等幂等性,通过以后,想要秒杀直接获取信号量,获取到就成功,获取不到就失败。(数据库库存已经锁定信号量的量了)成功以后,快速生成一个订单号,只生产一个订单号,把用户信息、订单号、商品直接发给MQ,只发了一个消息,没有动数据库,订单服务慢慢监听消息,创建订单,此时,立即给用户返回秒杀成功,正在准备订单,然后跳转到收获地址确认页,支付确认页。
在这里插入图片描述
优点:到创建订单为止没有访问数据库、没有远程调用,很快
缺点:订单服务炸了,却还是返回秒杀成功,没有服务消费订单,导致用户一致支付不成功。
该方法主要结合消息队列(通常是保证最终一致性,这里的作用更多是流量削峰)

判断是否买过(redis数据缓存至活动结束(过期时间),判断是否储存成功,成功没买过,失败买过)。

分布式信号量减库存(用tryAcquire方法,比如传100毫秒,没拿到返回null,不阻塞,也可以不设时间,就尝试一下)

P323、商城业务-秒杀服务-秒杀效果完成

在这里插入图片描述
RabbitMQ依赖,队列的编写
在这里插入图片描述
秒杀成功一次12ms,1个线程1s100并发
1个tomcat500线程,就是5W并发
百万并发20个单机集群就可以了。

P324、商城业务-秒杀服务-秒杀页面完成

在这里插入图片描述

数据库有一个锁定库存字段。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值