手把手教你做系统设计之秒杀系统 | 青训营笔记

109 阅读2分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 9 天

介绍

  • 标准流程(4S模型): 场景分析(Scenario)-> 存储设计(Storage)-> 服务设计(Service)-> 可扩展性(Scale)
  • 发现瓶颈:火焰图分析、链路分析、全链路压测
  • 验证系统的可用性和稳定性:链路梳理(核心链路、流量漏斗、强弱依赖)、可观测性(链路追踪、核心监控、业务报警)、全链路测试(压力、负载、容量)、稳定性控制(系统限流、业务兜底、熔断降级)、容灾演练(混沌工程、应急手册、容灾预案)

电商秒杀业务介绍

  • 电商:人(消费者)、货(供给侧)、场(交易环境)
  • 商品:具有交易价值和属性的信息载体
    • SPU:standard product unit 标准产品单元
    • SKU:stock keeping unit 库存保持单元
  • 特点:瞬时流量高、读多写少,实时性要求高
  • 挑战:资源成本、反欺诈、防止超卖、流量监控、高性能、扩展性、鲁棒性(系统的稳定性)

秒杀系统设计

场景

  • 功能:秒杀活动发布、秒杀商品详情、秒杀下单
  • 并发:万人参与秒杀、QPS 1w+、TPS 1k+

存储

  • 三级存储:MySQL -> Redis -> Localcache

服务

  • 子服务:用户服务、风控服务、活动服务、订单服务
  • 基础组件:ID生成器、缓存组件、MQ组件、限流组件

扩展

  • 流量隔离、CDN、缓存优化、流量管控
  • 数据库扩展、服务水平扩展、MQ扩展、Redis扩展、服务垂直扩展

实践

  • 整体流程:用户抢购 --下单--> 秒杀系统 --销峰--> MQ --消费MQ--> 订单服务 --支付--> 支付系统
  • 秒杀系统:
    • User 服务:登录校验
    • 风控服务:风控校验
    • Redis:活动校验
    • Redis:预扣库存
  • 订单服务:
    • 订单超时检查
    • MySQL:扣减库存,取消&下单失败库存回补
  • 实践采用Java语言,其中本地缓存的实现方式如下。
@Slf4j
@Service
public class LocalCacheService {

    @Resource
    private RedisService redisService;

//    private LoadingCache<String, HPromoProductModel> GuavaCache;

    private LoadingCache<String, HPromoProductModel> caffeineCache;

    @PostConstruct
    public void init() {
        caffeineCache = Caffeine.newBuilder()
                .initialCapacity(10)
                .maximumSize(100)
                .expireAfterWrite(5,TimeUnit.SECONDS)
                .build(new CacheLoader<>() {
                    @Override
                    public @Nullable HPromoProductModel load(String key) {
                        return (HPromoProductModel) redisService.getVal(key);
                    }
                });
    }

    public HPromoProductModel getVal(String key) {

        HPromoProductModel model = null;
        try {
            model = this.caffeineCache.get(key);
        } catch (Exception e) {
            return null;
        }
        log.info("get HPromoProductModel from local cache, key = {}, res is null {}", key, model == null);
        return model;
    }
}