上面主要讲了一些商品系统的设计,接下来我们从大的方面来讲一下商品系统应该如何架构。
首先商品从业务上可以区分成,类目管理模块和商品模块。
商品模块又细分为写管理模块和读管理模块。写管理模块负责商品的写入、搜索,主要运营端的管理,读模块主要负责提供高性能强一致性的读服务。下面分别展开来讲这两个模块。
写管理模块架构我们在设计架构的时候,通常会涉及到应用架构,数据架构,技术架构等三个部分。这里我们再根据时间顺序,分为代码架构,数据架构,部署架构,运维架构。
代码架构
以DDD的思想触发,单位职责化代码
要点说明:
- 模型主数据化,包括模型的是否必须、默认值、校验规则等。
- 动态校验标准化,标记校验标准化,支持可扩展
- 提供动态的门店选品策略
- 商品状态管理分成两个部分,状态自动化,状态通知集中化。
- 商品消息独立设计,缓冲非缓存,ID通知、富消息通知、变化通知。分成三种类型可以有效减少反查。
- 商品管理日志
数据架构
基础主数据使用DB进行存储,必要时课提供存储分库分表的存储,以ProductId/SkuId做为分库键,设计表的时候记得加skuId.
搜索使用Solr或者ES进行存储,主要支持商品搜索功能、商品日志搜索功能。
商品快照使用NoSQL数据库进行存储,一般使用的是MongoDB.
使用离线日志的方式接入数据平台,提供统计分析报表。
部署架构
- 建议使用读写分离,灵活支持读写量的需求
- 数据集中化存储,部署、消息租户隔离
运维架构
- 服务监控: 主要是API、资源监控、网络监控。
- 动态日志: 主要通过动态的配置,可以对线上服务进行轻度的DEBUG。
- Agent排查: 如果动态日志不满足,那么就开放JMX或者使用Agent服务,来灵活对系统服务排查。
代码架构
- 结构返回Result, 定义错误码,方便下游识别进行处理
- 批量接口需要限定数量。
- 缓存设计是重中之重,需要设计多级缓存,包括本地缓存和被动缓存。本地缓存分为主动缓存和被动缓存,使用Guava/Caffeine即可,堆外缓存可选采用。如下图所示。
- 商品信息精细化,按需分配所需字段。
- 核心服务JVM资源隔离,这里所指的是线程成。
- 远程缓存读取采用Pipeline模式,可以有效的提高性能约4倍+。
- JVM读取建议采用单线程,可有效提高吞吐量。
- 一致性对比工具
**数据架构 **
略
部署架构
- 分组设计,核心分组、消息分组、日常分组、worker分组、其他
- 机房高可用
- 热备集群
- 远程缓存需要根据字段分成不同的集群,提升QPS上限,更好支持水平扩展。
运维架构
除了和写服务一样的需求,还要支持性能方面的trace,通常来说trace都是采样,所以对于服务TP50的提升会很有效,TP99服务提升手段不是很明显。
扩展阅读: TP99如何优化呢?
作者认为需要分成两个阶段: 基准提升和减少波动。
基准提升: 流程阶段监控,资源命令基准压测,缓存方式改进。此外还有一些比较hack的手段,比如优化编译的GraalVM
减少波动: 环境(容器规格和JVM内存及回收器)调整测试,减少穿透,减少GC。
至此,我们基本完成了商品系统从业务设计到架构的讨论。本系列的文章也只能作为比较粗粒度地介绍,如果读完能够对商品系统有一个整体的印象,那么我们就不虚此行。我们下次见。



