Java秒杀系统常见问题

1. 如何解决超卖问题
a. 在sql加上判断防止数据变为负数
b. 数据库加唯一索引防止用户反复购买(限购)
c. redis预减库存减少数据库访问;内存标记减少redis访问;请求先进入队列缓冲,异步下单
2. 全局异常处理拦截
a. 定义全局的异常拦截器RespBean
b. 定义全局异常类型RespBeanNum
c. 返回与业务相关的异常,其他的异常用GlobleException
3. 对象级缓存redis
a. redis永久缓存对象减少压力
b. redis预减库存减少对数据库的访问
c. 内存标记方法减少redis访问(如果redis库存已空则不访问)
4. 异步下单处理队列RabbitMQ
a. 请求先入队缓冲,异步下单,增强用户体验
b. 请求出队,生成订单,减少库存
c. 客户轮询查询是否秒杀成功
5. 解决分布式session(用户信息存到session->存到redis)
a. 生成随机的uuid作为cookie返回并写入redis内存
b. 拦截器每次拦截方法,来重新根据cookie获取对象
c. 下一个页面拿到key重新获取对象
d. UserArgumentResolver 重写supportsParameter方法判断是否为User类型,是则返回true,执行resolveArgument获取User对象
Note: 在一个用户访问接口的时候我们把访问次数写到缓存中,在加上一个有效期。通过拦截器. 做一个注解 @AccessLimit 然后封装这个注解,可以有效的设置每次访问多少次,有效时间是否需要登录
6. 秒杀安全性设计
a. 对秒杀接口进行隐藏,防止网络明文传输中被直接获取到秒杀接口,进行一次转接口获取
b. 数学公式等验证码,防止直接识别
c. 接口防刷限流(通用 写注解对操作进行限制,拦截器方式)
7. 通用缓存key的封装采用什么设计模式(模板模式)
优点:
a. 具体细节步骤定义在子类中,子类定义详细处理算法是不会改变算法整体结构
b. 代码复用的基本技术, 在数据库设计中尤为重要,存在一种反向的控制结构,通过一个父类调用其子类对父类进行扩展增加新的行为,符合“开闭原则”
缺点:
每个不同的实现都需要定义一个子类,会导致类的个数增加,系统更加庞大
8. redis的库存如何与数据库的库存保持一致
reids中的数量不是库存,是减少数据库访问次数的一种限制手段,通过预减redis的数量阻挡多余的请求透传到DB,因此并不需要保持一致。
9. redis预减成功但是数据库扣除库存失败怎么办
不用在意,对用户而言秒杀不成功属于正常现象,而且这种情况本身属于小概率事件;对于商家而言这活动本身就是为了人气流量的,卖不完还可以省一部分钱,活动目的同样能达到。
10. 为什么要单独维护一个秒杀结束的标志
a. 所有的秒杀相关的接口都要加上活动是否结束的标志,结束则返回,包括轮寻的接口防止一直轮寻
b. 管理后台也可以手动的更改这个标志,可以随时停止防止无法结束
11. rabbitmq如何做到消息不重复不丢失即使服务器重启
a. exchange和queue持久化
b. 开启 confirm(发布确认)模式。因为即使我们在生产者中设置了队列持久化、消息持久化,但依然存在消息被传送到队列上,还没来得及存储在磁盘上,队列就宕机了,这种情况下消息也是会丢失的。所以在之前两步的基础上还是进行第三步:发布确认。三步操作加一起才能保证消息 从生产者到RabbitMQ服务器这个过程是不丢失的。
c. 关闭 RabbitMQ 的自动 ack,采用手动ack(消息应答机制)。
12. 为什么threadlocal 存储user对象,原理
a. 并发编程中重要的问题就是数据共享,当你在一个线程中改变任意属性时,所有的线程都会因此受到影响,同时会看到第一个线程修改后的值。但有时希望确保每个线程只工作在他自己的线程实例拷贝上而不影响其他线程数据。
b. 局部线程通常使用在这样的情况下,当你有一些对象并不满足线程安全,但是你想避免在使用synchronized关键字块时产生的同步访问,那么,让每个线程拥有它自己的对象实例
c. 局部变量是同步或局部线程的一个好的替代,它总是能够保证线程安全。唯一可能限制你这样做的是你的应用设计约束所以设计threadlocal存储user不会对对象产生影响,每次进来一个请求都会产生自身的线程变量来存储
13. maven隔离
在开发中把各个环境隔离起来,一般分为本地(local)、开发(dev)、测试(test)、线上(prod)
14. redis分布式锁实现方法
利用Lua脚本实现(包含SETNX + EXPIRE两条指令)
15. 服务降级–服务熔断(过载保护)
所有秒杀相关接口比如:秒杀,获取秒杀地址,获取秒杀结果,获取秒杀验证码都需要加上秒杀是否开始结束的判断
16. RPC事务补偿
当集中式进行服务化RPC演进成分布式的时候,事务则成为了进行分布式的痛点
17. sql写法注意事项
秒杀中数据量亿万级导致有时缓存也扛不住不可避免的穿透到DB中,所以sql语句应该注意:
a. 避免全表扫描(可能造成慢查询使得连接池满)
b. 合理的使用索引 索引并不是越多越好,使用不当会造成性能开销
c. 尽量避免大事务操作,提高系统并发能力
d. 尽量避免向客户端返回大量数据,如果返回则要考虑是否需求合理

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值