这是我参与「第五届青训营 」伴学笔记创作活动的第 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;
}
}