开篇
最近看了一个技术分享的视频《百万级并发商品服务架构解密》, 演讲者来自 网易考拉的丁鸣亮, 感觉讲的还不错, 根据内容简单整理如下.
业务概念划分
1. 商品详情模块
- app 商品详情
- pc 商品详情
- wap 商品详情
针对不同平台数据需求定制不同的接口详情, 减少各大端的彼此互相依赖、影响
2. 商品通用模块
- sku
- 品牌
- 分类
- 当前售价
- 库存
3. 商品附属模块
- 活动标签
- 利益标签
数据概念划分
1. 商品基本数据
- property
- sku
- goods
商品基本数据可以通过商品服务异构到应用服务, 即使商品服务宕机也不影响基础的商品访问, 异构方式可以使用 MQ、binlog 等形式进行.
2. 商品拓展数据
- 品牌
- 分类
- 所在仓库
3. 商品动态数据
- 当前价格
- 库存
- 满减|折扣
商品动态数据可通过实时查询 商品服务 返回最新的数据.
4. 商品附属数据
- 标签
商品附属数据非核心功能, 关键时刻可选择降级数据.
以上我们通过数据的划分实现了 动静分离、核心数据与非核心数据区分, 当然商品基础数据异构到应用层做缓存的方式是否合理, 好处是响应的提升、容灾、减少网络的消耗, 但换来的是增加了数据的冗余, 牺牲了服务的边界划分. (当然也可以有选择性的对热点商品进行异构缓存).
三级缓存的预案
商品详情三级缓存:
- L1缓存: 主动刷新热点商品 (local cache) 失效 5 min
- L2缓存: 被动刷新被访问的商品 (local cache) 失效 1min
- L3缓存: 全量的商品 失效7天
借用 cpu 的三级缓存概念, L1对于商品预见性预热到 local cache, L2 对于真实用户热点数据刷到本地. L3 一般为 redis、memcache 缓存使用.
服务稳定性提升:
服务灰度上线
Consumer端:
- 服务调用的二次封装
捕获被调用方异常, 平滑处理错误, 防止异常蔓延
- 服务调用的超时时间
设置合理超时时间, 服务降级, 防止服务崩溃异常蔓延
- 服务关停演练
代码层做非核心服务兼容, 对开关进行测试, 禁止真正发生问题后开关失效.
Provider端:
- 接口设置流控(限流,防止某服务调用异常影响其它Consumer)
- 按客户端设置流控
- 动静分离
没有流控感觉就像在裸奔, 因为没有 流控、降级 导致服务完全不能用, 最后排查原来是因为某条 sql 没用到索引, 如果有根据负载情况流控, 也不会出现这么大的损失。
减少核心业务的入侵 进行解耦
分清主次
解决循环依赖
举例: 我服务慢因为的调用了你的服务, 你的服务慢因为调用他的服务, 他的服务慢因为其中有个数据调用了我的服务
结语
明确服务边界, 保持干净.