1.开发酷鲨秒杀业务
1.1创建流控和降级的处理类
秒杀业务肯定是一个高并发的处理,并发数超过程序设计的限制时,就需要对请求的数量进行限流
Sentinel是阿里提供的SpringCloud组件,主要用于外界访问当前服务器的控制器方法的限流操作
之前的课程中,我们已经比较详细的学习的Sentinel使用的方式
下面我们要先编写Sentinel限流和服务降级时,运行的自定义异常处理类
我们酷鲨前台项目seckill-webapi模块
先来编写限流异常处理类
创建一个exception包,包中新建SeckillBlockHandler代码如下
// 秒杀业务的限流处理类
@Slf4j
public class SeckillBlockHandler {
// 声明限流的方法,返回值必须和控制器一致
// 参数要保护控制器方法的参数,还要添加一个BlockException的异常类型参数
// 这个方法定义成静态的,可以直接被使用类名调用到
public static JsonResult seckillBlock(String randCode,
SeckillOrderAddDTO seckillOrderAddDTO,
BlockException e){
log.error("一个请求被限流了");
return JsonResult.failed(ResponseCode.INTERNAL_SERVER_ERROR,
"对不起,服务器忙,请稍候再试");
}
}
再创建降级类SeckillFallBack
// 秒杀业务的降级处理类
@Slf4j
public class SeckillFallBack {
// 返回值和控制器方法一致
// 参数也是包含控制器的所有方法,可以不写其它参数,也可以添加一个Throwable类型的参数
// Throwable类型的参数就是触发降级的异常对象
public static JsonResult seckillFallback(String randCode,
SeckillOrderAddDTO seckillOrderAddDTO,
Throwable throwable){
log.error("一个请求被降级了");
return JsonResult.failed(ResponseCode.INTERNAL_SERVER_ERROR,
throwable.getMessage());
}
}
1.2开发执行秒杀的业务逻辑层
我们之前完成了秒杀的预热,预热中完成了秒杀商品sku库存数,spu随机码(布隆过滤器)保存在redis中的操作
也完成了查询秒杀商品列表,和显示秒杀商品详情的方法
下面要开始进行秒杀商品生成订单的操作
如果用户选择商品规格(sku)提交订单,那么就要按照提交秒杀订单的业务流程处理
秒杀提交订单和普通订单的区别
1.要判断当前用户是否为重复购买
2.从Redis中判断是否有库存
3.秒杀订单转换成普通订单,需要使用dubbo在order模块完成
4.用消息队列(RabbitMQ)的方式将秒杀成功信息保存在success表中
创建一个SeckillServiceImpl业务逻辑层实现类,完成上面的业务
@Service
@Slf4j
public class SeckillServiceImpl implements ISeckillService {
// 需要dubbo调用mall_order的生成普通订单的方法
@DubboReference
private IOmsOrderService dubboOrderService;
// 要用Redis减少库存,库存数是字符串类型的数字
@Autowired
private StringRedisTemplate stringRedisTemplate;
// 秒杀成功后需要将秒杀成功信息保存到数据库,但是使用消息队列
@Autowired
private RabbitTemplate rabbitTemplate;
/*
1.要判断当前用户是否为重复购买
2.从Redis中判断是否有库存
3.秒杀订单转换成普通订单,需要使用dubbo在order模块完成
4.用消息队列(RabbitMQ)的方式将秒杀成功信息保存在success表中
*/
@Override
public SeckillCommitVO commitSeckill(SeckillOrderAddDTO seckillOrderAddDTO) {
// 第一阶段:利用redis检查重复购买和是否有库存
// 从方法参数的订单项中获得skuId
Long skuId=seckillOrderAddDTO.getSeckillOrderItemAddDTO().getSkuId();
Long userId=getUserId();
// 有了userId和skuId相当于知道了谁买了什么
// 秒杀业务规定,一个用户只能购买一个skuId的商品一次
// 所以我们可以根据userId和skuId判断当前用户是否已经购买过
// 先获得该用户对该商品购买的key
// mall:seckill:reseckill:[skuId]:[userId]
String reseckillCheckKey=
SeckillCacheUtils.getReseckillCheckKey(skuId,userId);
// 使用上面生成的Key利用Redis的功能调用increment()方法
// increment是增长的意思,方法效果如下
// 1.如果当前的key不存在,redis会创建这个key,并保存他的值为1
// 2.如果当前的key存在,redis会给当前值加1,例如现在值是1,运行方法后会变为2
// 3.方法会将新增之后的值返回
Long seckillTimes=
stringRedisTemplate.boundValueOps(reseckillCheckKey).increment();
// seckillTimes实际就是当前用户第几次购买这个商品了
if(seckillTimes>1){
// 购买次数超过1,证明已经购买过,终止业务,抛出异常
throw new CoolShark