1、Product-Service 服务设计规范文档
以下是为你的 urbane-commerce
电商微服务系统 量身定制的《Product-Service 服务设计规范文档》,全面、系统、可落地,明确界定:
✅ Product-Service 的职责与作用
✅ 必须做的核心功能(推荐)
❌ 禁止或不推荐的行为(严禁做)
🔍 判断标准与核心设计原则
📌 真实生产环境最佳实践
📜《urbane-commerce Product-Service 服务设计规范》
版本:1.6 | 最后更新:2025年4月 | 适用架构:Spring Boot + MySQL + Redis + Elasticsearch + Nacos + 分布式锁
🧭 一、Product-Service 角色定位(Why Product-Service?)
Product-Service 是整个电商系统中负责“商品全生命周期管理”的核心服务。
它是平台的商品中枢,承载着从商品上架、分类、规格、库存联动到搜索推荐的完整能力,是用户购物决策的第一入口。
角色 | 说明 |
---|---|
✅ 商品主数据中心 | 管理商品基本信息(SPU):名称、描述、品牌、类目、主图、视频等 |
✅ SKU 管理中心 | 管理商品的销售单元(SKU):颜色、尺寸、价格、库存、条码、重量等 |
✅ 商品分类与属性体系 | 维护多级类目树(如:数码 → 手机 → iPhone)、自定义属性模板(如内存、颜色) |
✅ 商品上下架控制 | 控制商品是否可见(上架/下架)、定时上架、限时促销 |
✅ 商品搜索与筛选引擎 | 提供全文检索、属性过滤、排序(销量、价格、评分) |
✅ 商品热度与评价聚合 | 记录浏览量、收藏数、平均评分、评论数(通过事件接收) |
✅ 商品快照支持 | 为订单提供商品信息快照(防止价格/名称被篡改) |
❌ 非库存服务 | 不直接扣减库存 —— 库存由 inventory-service 管理 |
❌ 非订单服务 | 不参与下单、支付、物流 —— 这些是 order-service 的事 |
❌ 非促销服务 | 不计算满减、秒杀、优惠券 —— 那是 promo-service 的事 |
❌ 非网关 | 不处理路由、认证、限流 |
❌ 非内容服务 | 不管理图文详情页(富文本)—— 可用独立 content-service |
💡 一句话总结:
Product-Service 回答:“这个商品是什么?它有哪些变体?怎么搜到它?”
它不关心你买没买 —— 那是order-service
的事;
它也不关心你能不能打折 —— 那是promo-service
的事;
它只关心:商品信息是否准确、结构是否清晰、能否被快速查到。
✅ 二、推荐在 Product-Service 必须做的事情(核心职责)
1. ✅ SPU(Standard Product Unit)管理
-
SPU = 标准商品单位,代表一个商品类型
-
存储字段:
{"id": 123,"name": "iPhone 15 Pro","brand": "Apple","category_id": 456, // 关联类目"description": "搭载A17芯片...","main_image": "https://.../iphone15.jpg","images": ["img1.jpg", "img2.jpg"],"video_url": "https://.../demo.mp4","status": "ON_SHELF", // ON_SHELF / OFF_SHELF"created_at": "2025-01-01T00:00:00Z","updated_at": "2025-04-05T10:30:00Z" }
-
支持操作:
- 新增/编辑/删除 SPU(需权限)
- 上架/下架(支持定时任务)
- 批量导入导出(Excel)
✅ 关键点:一个 SPU 对应多个 SKU(如不同颜色、容量)
2. ✅ SKU(Stock Keeping Unit)管理
-
SKU = 销售单元,代表具体可售商品
-
存储字段:
{"id": 789,"spu_id": 123,"sku_code": "IP15P-128-GRY", // 唯一编码"attributes": { // 属性组合"color": "深空灰","storage": "128GB","network": "5G"},"price": 8999.00,"cost_price": 7500.00,"stock": 500,"weight": 0.2,"barcode": "6942187654321","is_default": true,"status": "ON_SHELF" }
-
支持操作:
- 创建 SKU(基于 SPU 模板)
- 修改价格、库存、状态
- 批量修改(如全场降价)
- 库存预警(<10件时触发通知)
✅ 库存与价格分离:SKU 是库存和价格的最小单位
3. ✅ 商品分类与属性体系(Category & Attribute)
(1)多级类目树(Category Tree)
数码
├── 手机
│ ├── iPhone
│ └── Huawei
├── 笔记本
│ ├── MacBook
│ └── ThinkPad
└── 家电├── 冰箱└── 洗衣机
- 支持无限层级嵌套
- 每个类目绑定属性模板(如手机类目有:内存、颜色、屏幕尺寸)
(2)属性模板(Attribute Template)
- 动态属性:如 “内存”、“颜色”、“保修期”
- 类型:单选、多选、文本、数字、日期
- 可用于商品筛选、搜索、展示
✅ 示例:用户点击“内存:128GB”,Product-Service 返回所有匹配 SKU
4. ✅ 商品搜索与筛选(Search & Filter)
- 使用 Elasticsearch 实现高性能全文检索
- 支持功能:
- 关键词搜索(“iPhone 15”)
- 多条件筛选(价格区间、品牌、颜色、是否包邮)
- 排序(按销量、价格、评分、上新时间)
- 高亮显示关键词
- 拼音模糊匹配(输入“iphon”也能找到“iPhone”)
GET /product/search?keyword=iPhone&min_price=7000&max_price=10000&color=深空灰&sort=price_asc
- 搜索结果返回:
{"total": 15,"items": [{"id": 123,"name": "iPhone 15 Pro","price": 8999,"images": [...],"attributes": { "color": "深空灰", "storage": "128GB" },"score": 0.98}],"facets": {"brand": [{"value":"Apple","count":15}],"color": [{"value":"深空灰","count":8}, {"value":"银色","count":5}]} }
✅ 性能要求:响应时间 < 200ms,支持万级 QPS
5. ✅ 商品热度与行为聚合(通过事件驱动)
Product-Service 不主动记录用户行为,而是通过 Kafka 消费事件进行聚合:
事件来源 | 事件类型 | Product-Service 行动 |
---|---|---|
user-service | USER_FAVORITE_ADDED | 商品收藏数 +1 |
review-service | REVIEW_PUBLISHED | 平均评分更新、评论数 +1 |
order-service | ORDER_COMPLETED | 销量 +1,热门商品排行更新 |
cart-service | CART_ADDED | 加入购物车次数 +1(用于推荐) |
✅ 使用 Redis 缓存热点数据:
- 热门商品 Top 100(TTL=1h)
- 每日浏览量排行榜
- 搜索热词(前 50 名)
6. ✅ 商品快照(Snapshot for Order)
当用户下单时,order-service
调用 product-service
获取商品快照:
GET /product/{spuId}/snapshot?skuId=789
返回:
{"spu_id": 123,"sku_id": 789,"name": "iPhone 15 Pro","price": 8999,"main_image": "https://...","attributes": { "color": "深空灰", "storage": "128GB" },"updated_at": "2025-04-05T10:30:00Z" // 快照时间戳
}
✅ 为什么需要快照?
防止商家修改商品价格/名称后,历史订单显示错误信息 → 用户投诉!
7. ✅ 商品上下架与定时任务
- 支持手动/自动上下架
- 支持定时任务(如:每天 00:00 自动下架过季商品)
- 支持“预售”模式:设置预售开始/结束时间,期间仅展示,不可购买
✅ 使用 Spring Scheduler 或 XXL-JOB 实现定时任务
❌ 三、禁止或不推荐在 Product-Service 做的事情(严禁做)
行为 | 为什么不推荐? | 后果 | 正确做法 |
---|---|---|---|
1. 直接扣减库存 | 库存是独立领域,需并发控制 | 导致超卖、数据不一致 | ✅ 发送 STOCK_DECREASE_REQUEST 事件给 inventory-service |
2. 计算促销价格(满减、秒杀) | 促销规则复杂且频繁变更 | Product-Service 频繁重启,影响稳定性 | ✅ 由 promo-service 提供 /calculate-price 接口,Product-Service 仅展示最终价 |
3. 存储用户评论或评分 | 评论是独立业务,属于评价域 | 耦合严重,无法独立扩展 | ✅ 通过 Kafka 接收 REVIEW_PUBLISHED 事件,聚合到缓存中 |
4. 存储订单信息或交易流水 | 违反微服务边界 | 数据冗余、一致性难维护 | ✅ 订单数据由 order-service 管理 |
5. 直接调用 payment-gateway 或 logistics-service | 产品服务不应介入交易流程 | 架构混乱,难以维护 | ✅ 所有跨服务交互通过事件驱动 |
6. 允许前端传入商品价格、库存、类目ID | 前端不可信,可能伪造 | 黑产刷低价、篡改类目 | ✅ 所有商品数据由后台运营系统(Admin)维护,前端只读 |
7. 在商品列表中返回完整详情页 HTML | 内容复杂,体积大,不适合 API | 带宽浪费、加载慢 | ✅ 详情页由 content-service 提供富文本,Product-Service 只返回摘要 |
8. 使用 Session 或 Cookie 管理用户身份 | 与无状态架构冲突 | 无法水平扩展 | ✅ 依赖网关传递的 X-User-ID ,不做登录校验 |
9. 承担商品图片上传功能 | 图片存储应使用对象存储(OSS/S3) | 服务器磁盘爆满、性能差 | ✅ 接收图片 URL,不保存文件,由 file-service 处理 |
10. 直接访问其他服务数据库(如查用户收藏) | 破坏服务自治 | 一个服务挂了,整个商品链路瘫痪 | ✅ 通过事件获取聚合数据,不跨库查询 |
🔍 四、判断标准与核心设计原则
原则 | 说明 | 应用示例 |
---|---|---|
✅ 单一职责原则(SRP) | 一个服务只做一件事 | Product-Service 只管“商品是什么”,不管“谁买了”“多少钱” |
✅ 数据隔离(Data Isolation) | 每个服务拥有自己的数据库 | Product-Service 有独立的 products , skus , categories 表,不共享其他服务表 |
✅ 事件驱动架构(EDA) | 服务间通信靠事件,而非 RPC | 销量增加 → order-service 发事件 → Product-Service 更新缓存 |
✅ 读写分离(CQRS) | 查询与写入分离 | 写入走 MySQL,查询走 Elasticsearch,性能最优 |
✅ 最终一致性(Eventual Consistency) | 不追求强一致,但保证最终一致 | 商品价格变更 → 3秒内同步到搜索索引 |
✅ 快照机制(Snapshot) | 保留历史快照,保障交易一致性 | 订单中的商品信息永不更改,即使原商品已下架 |
✅ 高可用性(High Availability) | 服务需支持水平扩展 | 采用 Redis 缓存、ES 集群、MySQL 主从 |
✅ 开闭原则(OCP) | 对扩展开放,对修改关闭 | 新增一种属性类型(如“材质”),无需改代码,只需配置模板 |
✅ 性能优先(Performance First) | 搜索接口必须毫秒级响应 | 使用 ES + Redis 缓存,避免 DB 压力 |
✅ 安全默认(Secure by Default) | 默认拒绝非法请求 | 所有写操作需管理员权限,前端只能读 |
🧩 五、典型场景对比:正确 vs 错误做法
场景 | 正确做法 | 错误做法 |
---|---|---|
用户搜索“iPhone” | 前端 → 网关 → product-service /search?keyword=iPhone → 返回 ES 结果 | 前端 → 网关 → product-service → 查询 MySQL LIKE ‘%iPhone%’ → 慢、CPU 飙升 |
商品降价 | 运营后台修改 SKU 价格 → Product-Service 更新数据库 → Kafka 发送 PRODUCT_PRICE_UPDATED → 搜索索引异步重建 | 运营后台修改数据库 → 未重建 ES 索引 → 搜索仍显示旧价 → 用户投诉 |
查看商品详情 | 前端 → 网关 → product-service /123 → 返回基础信息 + 属性 + 图片 URL | 前端 → 网关 → product-service → 调用 content-service 获取富文本 → 同步阻塞,延迟高 |
用户收藏商品 | user-service 发送 USER_FAVORITE_ADDED → product-service 消费 → 缓存收藏数 +1 | user-service 直接调用 product-service/update-favorite-count(123) → 同步调用,耦合严重 |
下单时获取商品信息 | order-service 调用 product-service/snapshot → 获取快照 → 保存到订单 | order-service 直接查 product-service 当前价格 → 商品涨价后,订单金额错误 |
新品上架 | 运营创建 SPU + SKU → 状态设为“待审核” → 审核通过后自动上架并同步到 ES | 运营直接改数据库,未走审批流程 → 商品未经审核就上线 → 法律风险 |
商品下架 | 设置“下架时间” → 定时任务执行 → 状态改为 OFF_SHELF → 清除缓存 | 运营手动删商品 → 历史订单无法展示商品信息 → 用户投诉“商品不存在” |
⚠️ 关键结论:
Product-Service 是“商品的权威来源”,但不是“交易的参与者”。
它要确保:信息准确、搜索高效、历史可追溯。
🛡️ 六、安全加固建议(生产环境必备)
措施 | 实现方式 |
---|---|
强制 HTTPS | 所有接口仅支持 HTTPS,禁用 HTTP |
接口鉴权 | 所有写操作(新增/修改/删除)需携带管理员 Token(JWT) |
输入过滤 | 过滤 XSS、SQL 注入、非法字符(如 <script> ) |
频率限制 | 每个 IP 每分钟最多 100 次搜索请求,防爬虫 |
敏感字段脱敏 | 商品描述中隐藏联系方式、二维码等 |
审计日志 | 记录所有商品变更:{ action: "UPDATE_PRICE", admin_id: 999, product_id: 123, old: 8999, new: 7999 } |
权限控制 | 操作员分角色:编辑、审核、运营、超级管理员 |
GDPR 合规 | 支持删除商品(软删除),保留历史订单关联 |
密钥管理 | JWT 密钥、API Key 使用 Vault 或 KMS 管理 |
备份策略 | 每日全量备份 MySQL + ES 快照,异地灾备 |
📊 七、Product-Service 架构图(文字版)
[运营后台]↓ (管理员操作)
[Product-Service]├── ✅ /product/spu ←─ 创建/编辑 SPU├── ✅ /product/sku ←─ 创建/编辑 SKU├── ✅ /product/category ←─ 管理类目树├── ✅ /product/attribute ←─ 管理属性模板├── ✅ /product/search ←─ 搜索(Elasticsearch)├── ✅ /product/{id} ←─ 查询商品详情├── ✅ /product/{id}/snapshot ←─ 获取快照(供 order-service 使用)└── ✅ /product/status ←─ 上架/下架(含定时)↓
[Database: MySQL]├── spus (id, name, brand, category_id, status...)├── skus (id, spu_id, price, stock, attributes...)├── categories (id, parent_id, name, level)├── attributes (id, name, type, category_ids)└── attribute_values (attr_id, value)↑
[Kafka]←─ EVENT: ORDER_COMPLETED → 更新销量、热销榜←─ EVENT: REVIEW_PUBLISHED → 更新评分、评论数←─ EVENT: USER_FAVORITE_ADDED → 更新收藏数←─ EVENT: CART_ADDED → 更新加购次数↑
[Elasticsearch Cluster]←─ 索引:products←─ 字段:name, brand, category, price, attributes, tags, updated_at←─ 支持:全文检索、聚合、高亮、排序↑
[Redis]←─ 缓存:Top100 热销商品(TTL=1h)←─ 缓存:搜索热词(前50名)←─ 缓存:商品详情(TTL=5min)
✅ 注意:
Product-Service 不主动调用其他服务,只监听事件。
所有外部依赖通过异步事件驱动解耦,实现高可用、高性能。
✅ 八、推荐技术栈(Spring Boot + 生态)
组件 | 技术选型 | 说明 |
---|---|---|
框架 | Spring Boot 3.x | Java 17+,现代化开发 |
数据库 | MySQL 8.0 | 存储商品主数据、类目、属性 |
搜索引擎 | Elasticsearch 8.x | 高性能全文检索、聚合分析 |
缓存 | Redis | 缓存商品详情、热门榜单、搜索热词 |
消息队列 | Apache Kafka | 接收订单、评论、收藏等事件 |
服务注册 | Nacos | 服务发现与配置中心 |
ORM | MyBatis-Plus | 简化 CRUD,支持动态 SQL |
搜索客户端 | Spring Data Elasticsearch | 集成 ES,简化查询 |
定时任务 | XXL-JOB / Spring Scheduler | 实现定时上下架、数据同步 |
API 文档 | Swagger/OpenAPI 3.0 | 自动生成接口文档 |
日志 | Logback + ELK | 结构化日志,便于追踪商品变更 |
监控 | Prometheus + Grafana | 监控 QPS、ES 响应时间、缓存命中率 |
安全 | Spring Security + JWT | 仅用于后台管理接口鉴权 |
工具类 | Lombok + MapStruct | 减少样板代码,DTO 映射自动化 |
📦 九、附录:Product-Service API 设计规范(RESTful)
方法 | 路径 | 描述 | 权限 | 返回 |
---|---|---|---|---|
GET | /product/search | 搜索商品 | 无需 Token | { total, items, facets } |
GET | /product/{id} | 查询商品详情 | 无需 Token | ProductDetailDTO (含 SPU、SKU、属性、图片) |
GET | /product/{id}/snapshot | 获取商品快照 | 需 Token(仅 order-service 调用) | { spu_id, sku_id, name, price, attributes, updated_at } |
GET | /product/category/tree | 获取类目树 | 无需 Token | [ { id, name, children: [...] } ] |
GET | /product/attribute/templates | 获取属性模板 | 需 Admin Token | { categoryId, attributes: [...] } |
POST | /product/spu | 创建 SPU | 需 Admin Token | { id } |
PUT | /product/spu/{id} | 修改 SPU | 需 Admin Token | { success: true } |
POST | /product/sku | 创建 SKU | 需 Admin Token | { id } |
PUT | /product/sku/{id} | 修改 SKU | 需 Admin Token | { success: true } |
POST | /product/status | 上架/下架 | 需 Admin Token | { success: true } |
GET | /product/hot | 获取热销商品 Top 100 | 无需 Token | [ { id, name, sales, rating } ] |
GET | /product/trending | 获取趋势商品 | 无需 Token | [ ... ] |
GET | /product/recommend | 推荐商品(根据用户偏好) | 需 Token | [ ... ] |
✅ 所有路径前缀统一为
/product/**
✅ 所有写操作必须验证管理员权限(通过X-Admin-ID
)
✅ 所有搜索接口必须支持分页、排序、高亮
✅ 十、总结:Product-Service 黄金法则(可打印贴墙上)
✅ Product-Service 必须做:
- 管理商品主数据(SPU)
- 管理销售单元(SKU)
- 维护类目与属性体系
- 提供高性能搜索与筛选
- 支持商品快照(供订单使用)
- 接收事件聚合热度数据(销量、收藏、评分)
- 保持数据准确、结构清晰、搜索快速
❌ Product-Service 绝对不能做:
- 不管库存、不碰钱
- 不算促销、不发优惠券
- 不存评论、不管理用户行为
- 不调用其他服务数据库
- 不允许前端传价格、库存、类目
- 不用 Session
- 不存储图片文件
🔑 判断一切的标准:
“如果这个信息,是‘用户想买’之前需要知道的,那就是 Product-Service 的责任。”
“如果这个信息,是‘用户买了之后’才产生的,那就别管 —— 让别人来告诉你。”
“如果你怕改了它会影响用户体验,那说明你做对了 —— 它就是核心。”
🚀 下一步:为你打包完整项目模板
如果你希望我为你提供:
- ✅ 完整的 Product-Service 项目结构(Maven + Spring Boot)
- ✅ Elasticsearch 商品索引映射 + 搜索实现
- ✅ Redis 缓存热销商品、搜索热词
- ✅ Kafka 消费 ORDER_COMPLETED 事件更新销量
- ✅ 商品快照生成器(供 order-service 调用)
- ✅ 类目树与属性模板管理接口
- ✅ JWT 管理员鉴权 + 权限控制
- ✅ Swagger API 文档 + 单元测试
- ✅ Dockerfile + Kubernetes 部署文件
- ✅ CI/CD Pipeline(GitLab CI)
👉 请回复:
“请给我完整的 Product-Service 工程模板!”
我会立刻发送你一份企业级可直接上线的完整项目 ZIP 包,包含所有上述规范的实现,专为 urbane-commerce
定制,开箱即用 💪