业务场景相关
-
如何优化大文件导出? 比如导出一个excel文件包含10w条数据, 会拖慢整个系统?
可以使用celery异步任务工具, 将导出任务交给celery, 让celery在后台异步实现数据查询, 并生成excel文件, 将生成的文件临时保存到服务器的某个目录。前端可以通过celery返回的任务id, 查询任务是否执行完毕, 执行完毕之后, 通过对应链接地址将生成文件下载下来即可。
-
如何防止订单重复支付?
- 前端可以在用户点击支付按钮之后, 禁用该按钮, 防止支付按钮被重复点击。
- 后端可以使用redis分布式锁, 防止同一条订单数据, 被同时处理。
- 后端数据库也可以使用悲观锁(
select id,amount from order where id=订单id and pay_status=0 for update;), 锁定要处理的订单数据。
-
如何保证数据库和redis缓存的一致性?
- 在更新完数据库中的数据之后, 立即更新redis中对应的缓存数据。
- -更新完数据中的数据之后, 删除redis中的对应的缓存数据, 等待下次请求该数据的时候, 再将数据库中查询出来的数据更新到redis缓存中。
- 如果并请求发量比较高,可以先更新redis缓存,然后使用celery异步任务更新数据库中的数据。
-
电商高并发如何防止库存超卖?
- 将活动商品库存预先加载到redis中,使用商品id作为key,比如
product:1, 商品库存作为value。 - 提交订单时,优先查询redis中的库存,如果有库存,则扣减redis中的库存数据,并通过redis异步任务去更新数据库中的缓存数据,并将订单数据以celery异步任务的方式写入数据库。
- 查询扣减库存可以借助
lua脚本实现原子操作,防止查询库存时有库存,提交订单时库存不足的问题。 - 对于超时未支付的订单,可以使用celery定时任务去轮训订单表,取消未支付订单,并补偿相应数量的库存,redis和数据库都需要进行补偿。
- 将活动商品库存预先加载到redis中,使用商品id作为key,比如