// TODO 增加请求许可校验(自定义注解+拦截器),校验请求此接口的所有用户是否是已登录用户,如果没有登录,提示请登录
// TODO 增加接口参数的校验,判断用户是否是系统正常用户,不能是状态异常用户,判断商品的数据是否正确(切记:涉及系统内数据不要信任请求参数,要信任系统的缓存的数据库)
// TODO 为了提高抢购入口的并发处理能力,要减少数据库交互,可以设计为根据商品编号,从redis缓存中查询商品,如果商品信息存在,则参与抢购,如果不存在,还是需要到数据库查询商品,如果数据库中存在,将商品信息存入redis缓存,如果数据库不存在,则直接提示抢购失败。
// TODO 此种场景,正常情况,没有问题,可能存在的问题,某个商品,是首次参与抢购,缓存中没有数据,但是数据库有,虽然上面的处理方式,可以解决,但是在高并发场景下,同一时刻会有大批量的请求来秒杀此商品,此时同时去缓存中获取商品数据,没有获取到,又同时去数据库查询,就会导致数据库扛不住压力,可能直接数据库挂掉。
// TODO 解决方式:缓存商品数据一般都是在后台添加抢购商品时,直接对商品进行预热处理,即:事先把参与抢购的商品直接同步到redis缓存中,这样当抢购开始,直接从redis缓存就可以获取到商品,而不会出现缓存击穿问题。
// TODO 虽然商品数据预热方式,可以解决此类问题,但是可能还会存在例外(比如:缓存中的商品由于后台失误操作,导致设置的过期时间不对,缓存时间提前过期,或者缓存数据误删除),此种情况还是需要当缓存不存在商品数据,从数据库查询,放入缓存的逻辑。
// TODO 解决方式:可以进行加锁,限制在高并发的情况下访问数据库,如果同一时刻,缓存中没有获取到商品数据库,就进入查询数据库操作,但是在进入查询前,增加分布式锁,只有获取到锁的请求,才可以查询数据库并加入到缓存中(加完就释放锁),获取不到锁的请求,直接返回失败(损失当前请求,后续请求进行弥补,只要一个操作成功,缓存中的数据就存在,后续的请求自然可以获取到数据)
// TODO 极端情况:redis无法使用,必须要增加redis的高可用,确保redis永远是有效的,考虑的模式就是集群模式下的哨兵机制。或者把大批量的请求直接放到消息队列,进行缓冲处理。