5.5、商城服务拆分设计
商城服务拆分设计
本节将根据商城业务需求,设计微服务拆分方案。本节将学习如何将单体商城应用拆分为多个微服务。
本节将学习:用户服务(User Service)、商品服务(Product Service)、订单服务(Order Service)、支付服务(Payment Service)、库存服务(Inventory Service),以及网关服务(Gateway Service)。
完整的服务拆分方案
拆分原则
微服务拆分原则:
- 单一职责:每个服务只负责一个业务领域
- 数据独立:每个服务拥有独立的数据库
- 服务自治:服务可以独立开发、部署、扩展
- 接口清晰:服务间通过明确的 API 接口通信
服务拆分架构图
用户服务(User Service)
服务职责
用户服务职责:
- 用户注册:用户名、邮箱、手机号注册
- 用户登录:用户名/邮箱/手机号登录,密码验证
- 用户信息管理:查询、更新用户信息
- 用户权限管理:角色管理、权限验证
- 用户状态管理:激活、禁用、注销
服务边界
用户服务边界:
-
包含:
- 用户数据管理(用户表、角色表、权限表)
- 用户认证授权(登录验证、Token 生成)
- 用户个人信息管理
-
不包含:
- 订单相关业务逻辑
- 商品相关业务逻辑
- 支付相关业务逻辑
数据库设计
用户服务数据库(user_db):
-- 用户表 CREATE TABLE `user` ( `id` BIGINT PRIMARY KEY AUTO_INCREMENT, `username` VARCHAR(50) UNIQUE NOT NULL COMMENT '用户名', `email` VARCHAR(100) UNIQUE NOT NULL COMMENT '邮箱', `phone` VARCHAR(20) UNIQUE COMMENT '手机号', `password` VARCHAR(255) NOT NULL COMMENT '密码(加密)', `nickname` VARCHAR(50) COMMENT '昵称', `avatar` VARCHAR(255) COMMENT '头像URL', `status` TINYINT DEFAULT 1 COMMENT '状态:1-正常,0-禁用', `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP, `update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, INDEX `idx_username` (`username`), INDEX `idx_email` (`email`), INDEX `idx_phone` (`phone`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表'; -- 角色表 CREATE TABLE `role` ( `id` BIGINT PRIMARY KEY AUTO_INCREMENT, `role_name` VARCHAR(50) UNIQUE NOT NULL COMMENT '角色名称', `role_code` VARCHAR(50) UNIQUE NOT NULL COMMENT '角色代码', `description` VARCHAR(255) COMMENT '角色描述', `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='角色表'; -- 用户角色关联表 CREATE TABLE `user_role` ( `id` BIGINT PRIMARY KEY AUTO_INCREMENT, `user_id` BIGINT NOT NULL, `role_id` BIGINT NOT NULL, `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP, UNIQUE KEY `uk_user_role` (`user_id`, `role_id`), FOREIGN KEY (`user_id`) REFERENCES `user`(`id`), FOREIGN KEY (`role_id`) REFERENCES `role`(`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户角色关联表';
API 接口设计
用户服务 RESTful API:
| 方法 | 路径 | 说明 | 请求体 | 响应 |
|---|---|---|---|---|
| POST | /api/users/register | 用户注册 | UserRegisterDTO | UserVO |
| POST | /api/users/login | 用户登录 | LoginDTO | LoginResponse |
| GET | /api/users/{id} | 查询用户信息 | - | UserVO |
| PUT | /api/users/{id} | 更新用户信息 | UserUpdateDTO | UserVO |
| GET | /api/users/username/{username} | 根据用户名查询 | - | UserVO |
| GET | /api/users/email/{email} | 根据邮箱查询 | - | UserVO |
商品服务(Product Service)
服务职责
商品服务职责:
- 商品管理:商品 CRUD 操作
- 商品分类:分类管理、分类树结构
- 商品搜索:关键词搜索、条件筛选
- 商品展示:商品列表、商品详情
- 商品评价:评价管理(可选,也可独立为评价服务)
服务边界
商品服务边界:
-
包含:
- 商品数据管理(商品表、分类表、商品属性表)
- 商品信息查询和展示
-
商品分类管理
-
不包含:
- 库存管理(由库存服务负责)
- 订单管理(由订单服务负责)
- 价格计算(可能涉及促销,可独立为价格服务)
数据库设计
商品服务数据库(product_db):
-- 商品分类表 CREATE TABLE `category` ( `id` BIGINT PRIMARY KEY AUTO_INCREMENT, `parent_id` BIGINT DEFAULT 0 COMMENT '父分类ID,0表示顶级分类', `category_name` VARCHAR(100) NOT NULL COMMENT '分类名称', `category_code` VARCHAR(50) UNIQUE NOT NULL COMMENT '分类代码', `level` TINYINT DEFAULT 1 COMMENT '分类层级', `sort_order` INT DEFAULT 0 COMMENT '排序', `status` TINYINT DEFAULT 1 COMMENT '状态:1-启用,0-禁用', `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP, `update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, INDEX `idx_parent_id` (`parent_id`), INDEX `idx_category_code` (`category_code`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='商品分类表'; -- 商品表 CREATE TABLE `product` ( `id` BIGINT PRIMARY KEY AUTO_INCREMENT, `product_name` VARCHAR(200) NOT NULL COMMENT '商品名称', `product_code` VARCHAR(50) UNIQUE NOT NULL COMMENT '商品编码', `category_id` BIGINT NOT NULL COMMENT '分类ID', `description` TEXT COMMENT '商品描述', `price` DECIMAL(10,2) NOT NULL COMMENT '商品价格', `image_url` VARCHAR(500) COMMENT '商品主图', `images` TEXT COMMENT '商品图片列表(JSON)', `status` TINYINT DEFAULT 1 COMMENT '状态:1-上架,0-下架', `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP, `update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, INDEX `idx_category_id` (`category_id`), INDEX `idx_product_code` (`product_code`), INDEX `idx_status` (`status`), FULLTEXT INDEX `ft_product_name` (`product_name`, `description`), FOREIGN KEY (`category_id`) REFERENCES `category`(`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='商品表'; -- 商品属性表 CREATE TABLE `product_attribute` ( `id` BIGINT PRIMARY KEY AUTO_INCREMENT, `product_id` BIGINT NOT NULL, `attribute_name` VARCHAR(100) NOT NULL COMMENT '属性名称', `attribute_value` VARCHAR(255) NOT NULL COMMENT '属性值', `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP, INDEX `idx_product_id` (`product_id`), FOREIGN KEY (`product_id`) REFERENCES `product`(`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='商品属性表';
API 接口设计
商品服务 RESTful API:
| 方法 | 路径 | 说明 | 请求体 | 响应 |
|---|---|---|---|---|
| GET | /api/products | 商品列表(分页) | Query: page, size, categoryId, keyword | PageResult |
| GET | /api/products/{id} | 商品详情 | - | ProductVO |
| POST | /api/products | 创建商品 | ProductCreateDTO | ProductVO |
| PUT | /api/products/{id} | 更新商品 | ProductUpdateDTO | ProductVO |
| DELETE | /api/products/{id} | 删除商品 | - | Boolean |
| GET | /api/products/categories | 分类树 | - | List |
| GET | /api/products/search | 商品搜索 | Query: keyword, filters | PageResult |
订单服务(Order Service)
服务职责
订单服务职责:
- 订单创建:创建订单、验证订单信息
- 订单管理:订单查询、订单更新
- 订单状态管理:订单状态流转(待支付、已支付、已发货、已完成、已取消)
- 订单协调:协调用户服务、商品服务、库存服务、支付服务完成订单流程
服务边界
订单服务边界:
-
包含:
- 订单数据管理(订单表、订单项表)
- 订单业务逻辑(订单创建、状态管理)
- 订单查询和统计
-
不包含:
- 用户数据管理(通过调用用户服务获取)
- 商品数据管理(通过调用商品服务获取)
- 库存管理(通过调用库存服务)
- 支付处理(通过调用支付服务)
数据库设计
订单服务数据库(order_db):
-- 订单表 CREATE TABLE `order` ( `id` BIGINT PRIMARY KEY AUTO_INCREMENT, `order_no` VARCHAR(50) UNIQUE NOT NULL COMMENT '订单号', `user_id` BIGINT NOT NULL COMMENT '用户ID(来自用户服务)', `total_amount` DECIMAL(10,2) NOT NULL COMMENT '订单总金额', `pay_amount` DECIMAL(10,2) NOT NULL COMMENT '实付金额', `status` TINYINT DEFAULT 0 COMMENT '订单状态:0-待支付,1-已支付,2-已发货,3-已完成,4-已取消', `payment_status` TINYINT DEFAULT 0 COMMENT '支付状态:0-未支付,1-已支付,2-已退款', `payment_time` DATETIME COMMENT '支付时间', `delivery_time` DATETIME COMMENT '发货时间', `complete_time` DATETIME COMMENT '完成时间', `cancel_time` DATETIME COMMENT '取消时间', `cancel_reason` VARCHAR(255) COMMENT '取消原因', `remark` VARCHAR(500) COMMENT '订单备注', `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP, `update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, INDEX `idx_order_no` (`order_no`), INDEX `idx_user_id` (`user_id`), INDEX `idx_status` (`status`), INDEX `idx_create_time` (`create_time`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='订单表'; -- 订单项表 CREATE TABLE `order_item` ( `id` BIGINT PRIMARY KEY AUTO_INCREMENT, `order_id` BIGINT NOT NULL COMMENT '订单ID', `product_id` BIGINT NOT NULL COMMENT '商品ID(来自商品服务)', `product_name` VARCHAR(200) NOT NULL COMMENT '商品名称(冗余)', `product_image` VARCHAR(500) COMMENT '商品图片(冗余)', `product_price` DECIMAL(10,2) NOT NULL COMMENT '商品单价(冗余)', `quantity` INT NOT NULL COMMENT '购买数量', `subtotal` DECIMAL(10,2) NOT NULL COMMENT '小计金额', `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP, INDEX `idx_order_id` (`order_id`), INDEX `idx_product_id` (`product_id`), FOREIGN KEY (`order_id`) REFERENCES `order`(`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='订单项表';
API 接口设计
订单服务 RESTful API:
| 方法 | 路径 | 说明 | 请求体 | 响应 |
|---|---|---|---|---|
| POST | /api/orders | 创建订单 | OrderCreateDTO | OrderVO |
| GET | /api/orders/{id} | 查询订单详情 | - | OrderVO |
| GET | /api/orders | 查询订单列表(分页) | Query: userId, status, page, size | PageResult |
| PUT | /api/orders/{id}/status | 更新订单状态 | OrderStatusUpdateDTO | Boolean |
| POST | /api/orders/{id}/cancel | 取消订单 | CancelOrderDTO | Boolean |
| GET | /api/orders/{orderNo} | 根据订单号查询 | - | OrderVO |
支付服务(Payment Service)
服务职责
支付服务职责:
- 支付处理:创建支付订单、调用支付渠道
- 支付回调:处理支付成功/失败回调
- 支付状态管理:支付状态查询、状态同步
- 支付记录:支付流水记录、对账
服务边界
支付服务边界:
-
包含:
- 支付数据管理(支付订单表、支付流水表)
- 支付流程处理(支付、退款)
- 支付渠道对接(支付宝、微信等)
-
不包含:
- 订单业务逻辑(只负责支付,不涉及订单状态)
- 用户数据管理(通过订单服务获取用户信息)
数据库设计
支付服务数据库(payment_db):
-- 支付订单表 CREATE TABLE `payment_order` ( `id` BIGINT PRIMARY KEY AUTO_INCREMENT, `payment_no` VARCHAR(50) UNIQUE NOT NULL COMMENT '支付单号', `order_id` BIGINT NOT NULL COMMENT '订单ID(来自订单服务)', `order_no` VARCHAR(50) NOT NULL COMMENT '订单号(冗余)', `user_id` BIGINT NOT NULL COMMENT '用户ID(冗余)', `amount` DECIMAL(10,2) NOT NULL COMMENT '支付金额', `payment_method` VARCHAR(20) NOT NULL COMMENT '支付方式:ALIPAY-支付宝,WECHAT-微信', `status` TINYINT DEFAULT 0 COMMENT '支付状态:0-待支付,1-已支付,2-支付失败,3-已退款', `third_party_no` VARCHAR(100) COMMENT '第三方支付单号', `pay_time` DATETIME COMMENT '支付时间', `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP, `update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, INDEX `idx_payment_no` (`payment_no`), INDEX `idx_order_id` (`order_id`), INDEX `idx_status` (`status`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='支付订单表'; -- 支付流水表 CREATE TABLE `payment_record` ( `id` BIGINT PRIMARY KEY AUTO_INCREMENT, `payment_order_id` BIGINT NOT NULL, `transaction_type` VARCHAR(20) NOT NULL COMMENT '交易类型:PAY-支付,REFUND-退款', `amount` DECIMAL(10,2) NOT NULL COMMENT '交易金额', `status` TINYINT NOT NULL COMMENT '状态:1-成功,0-失败', `third_party_no` VARCHAR(100) COMMENT '第三方交易号', `remark` VARCHAR(255) COMMENT '备注', `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP, INDEX `idx_payment_order_id` (`payment_order_id`), FOREIGN KEY (`payment_order_id`) REFERENCES `payment_order`(`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='支付流水表';
API 接口设计
支付服务 RESTful API:
| 方法 | 路径 | 说明 | 请求体 | 响应 |
|---|---|---|---|---|
| POST | /api/payments | 创建支付订单 | PaymentCreateDTO | PaymentVO |
| GET | /api/payments/{id} | 查询支付订单 | - | PaymentVO |
| GET | /api/payments/order/{orderId} | 根据订单ID查询 | - | PaymentVO |
| POST | /api/payments/{id}/pay | 发起支付 | - | PaymentResponse |
| POST | /api/payments/callback | 支付回调 | CallbackDTO | Boolean |
| POST | /api/payments/{id}/refund | 申请退款 | RefundDTO | Boolean |
库存服务(Inventory Service)
服务职责
库存服务职责:
- 库存管理:库存初始化、库存调整
- 库存扣减:订单扣减库存、释放库存
- 库存查询:商品库存查询、库存历史
- 库存预警:低库存预警、缺货通知
服务边界
库存服务边界:
-
包含:
- 库存数据管理(库存表、库存变更记录表)
- 库存操作(扣减、释放、调整)
- 库存查询和统计
-
不包含:
- 商品信息管理(通过商品ID关联,不存储商品详情)
- 订单业务逻辑(只负责库存操作)
数据库设计
库存服务数据库(inventory_db):
-- 库存表 CREATE TABLE `inventory` ( `id` BIGINT PRIMARY KEY AUTO_INCREMENT, `product_id` BIGINT UNIQUE NOT NULL COMMENT '商品ID(来自商品服务)', `total_stock` INT NOT NULL DEFAULT 0 COMMENT '总库存', `available_stock` INT NOT NULL DEFAULT 0 COMMENT '可用库存', `locked_stock` INT NOT NULL DEFAULT 0 COMMENT '锁定库存(已下单未支付)', `sold_stock` INT NOT NULL DEFAULT 0 COMMENT '已售库存', `low_stock_threshold` INT DEFAULT 10 COMMENT '低库存阈值', `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP, `update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, INDEX `idx_product_id` (`product_id`), INDEX `idx_available_stock` (`available_stock`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='库存表'; -- 库存变更记录表 CREATE TABLE `inventory_record` ( `id` BIGINT PRIMARY KEY AUTO_INCREMENT, `product_id` BIGINT NOT NULL, `change_type` VARCHAR(20) NOT NULL COMMENT '变更类型:DEDUCT-扣减,RELEASE-释放,ADJUST-调整', `change_quantity` INT NOT NULL COMMENT '变更数量(正数为增加,负数为减少)', `before_stock` INT NOT NULL COMMENT '变更前库存', `after_stock` INT NOT NULL COMMENT '变更后库存', `order_id` BIGINT COMMENT '关联订单ID', `order_no` VARCHAR(50) COMMENT '订单号', `remark` VARCHAR(255) COMMENT '备注', `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP, INDEX `idx_product_id` (`product_id`), INDEX `idx_order_id` (`order_id`), INDEX `idx_create_time` (`create_time`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='库存变更记录表';
API 接口设计
库存服务 RESTful API:
| 方法 | 路径 | 说明 | 请求体 | 响应 |
|---|---|---|---|---|
| GET | /api/inventory/{productId} | 查询商品库存 | - | InventoryVO |
| POST | /api/inventory/deduct | 扣减库存 | InventoryDeductDTO | Boolean |
| POST | /api/inventory/release | 释放库存 | InventoryReleaseDTO | Boolean |
| POST | /api/inventory/adjust | 调整库存 | InventoryAdjustDTO | Boolean |
| GET | /api/inventory/low-stock | 低库存商品列表 | Query: threshold | List |
| GET | /api/inventory/{productId}/records | 库存变更记录 | Query: page, size | PageResult |
网关服务(Gateway Service)
服务职责
网关服务职责:
- 统一入口:所有外部请求通过网关进入
- 路由转发:根据路径转发到对应服务
- 负载均衡:在多个服务实例间负载均衡
- 限流熔断:接口限流、服务熔断
- 认证授权:统一认证、Token 验证
- 请求日志:记录请求日志、监控
服务边界
网关服务边界:
-
包含:
- 请求路由和转发
- 统一认证和授权
- 限流和熔断
- 请求日志和监控
-
不包含:
- 业务逻辑(所有业务逻辑在各自服务中)
- 数据存储(不存储业务数据)
路由配置设计
网关路由配置:
| 路由路径 | 目标服务 | 说明 |
|---|---|---|
/api/users/** | user-service | 用户服务路由 |
/api/products/** | product-service | 商品服务路由 |
/api/orders/** | order-service | 订单服务路由 |
/api/payments/** | payment-service | 支付服务路由 |
/api/inventory/** | inventory-service | 库存服务路由 |
服务间通信接口设计
RESTful API 规范
统一的 API 设计规范:
-
URL 设计:
- 使用名词,不使用动词
- 使用复数形式:
/api/users而不是/api/user - 使用层级结构:
/api/users/{userId}/orders
-
HTTP 方法:
- GET:查询操作
- POST:创建操作
- PUT:更新操作(完整更新)
- PATCH:部分更新
- DELETE:删除操作
-
响应格式:
{ "code": 200, "message": "success", "data": {}, "timestamp": "2024-01-01T00:00:00" } -
错误响应:
{ "code": 400, "message": "Bad Request", "error": "Validation failed", "timestamp": "2024-01-01T00:00:00" }
服务间调用接口
订单服务调用其他服务的接口:
-
调用用户服务:
GET /api/users/{userId}- 查询用户信息GET /api/users/{userId}/exists- 验证用户是否存在
-
调用商品服务:
GET /api/products/{productId}- 查询商品信息POST /api/products/batch- 批量查询商品
-
调用库存服务:
POST /api/inventory/deduct- 扣减库存POST /api/inventory/release- 释放库存GET /api/inventory/{productId}- 查询库存
-
调用支付服务:
POST /api/payments- 创建支付订单GET /api/payments/{paymentId}- 查询支付状态
数据一致性方案设计
分布式事务场景
需要分布式事务的场景:
-
订单创建流程:
- 订单服务:创建订单
- 库存服务:扣减库存
- 支付服务:创建支付订单
- 需要保证:要么全部成功,要么全部回滚
-
订单支付流程:
- 支付服务:处理支付
- 订单服务:更新订单状态
- 库存服务:确认库存扣减(如果支付成功)
- 需要保证:支付和订单状态一致
一致性方案
数据一致性方案:
-
强一致性(分布式事务):
- 使用 Seata AT 模式
- 适用于:订单创建、支付处理
- 优点:数据强一致
- 缺点:性能开销大
-
最终一致性(消息队列):
- 使用 RocketMQ 事务消息
- 适用于:订单状态同步、库存扣减确认
- 优点:性能好、解耦
- 缺点:有延迟
-
补偿机制(Saga 模式):
- 使用 Seata Saga 模式
- 适用于:复杂业务流程
- 优点:灵活、可扩展
- 缺点:实现复杂
数据一致性设计图
服务关系图
服务拆分总结
拆分后的服务列表
| 服务名称 | 端口 | 数据库 | 主要职责 |
|---|---|---|---|
| user-service | 8081 | user_db | 用户管理、认证授权 |
| product-service | 8082 | product_db | 商品管理、分类、搜索 |
| order-service | 8083 | order_db | 订单管理、订单协调 |
| payment-service | 8084 | payment_db | 支付处理、支付记录 |
| inventory-service | 8085 | inventory_db | 库存管理、库存操作 |
| gateway-service | 8080 | - | 统一入口、路由转发 |
服务依赖关系
拆分原则总结
服务拆分遵循的原则:
- 业务边界清晰:每个服务负责一个业务领域
- 数据独立:每个服务拥有独立的数据库
- 接口明确:服务间通过 RESTful API 通信
- 服务自治:服务可以独立开发、部署、扩展
- 故障隔离:一个服务故障不影响其他服务
官方资源
- 微服务拆分设计:https://microservices.io/patterns/decomposition/
- 领域驱动设计:https://martinfowler.com/bliki/DomainDrivenDesign.html
- RESTful API 设计:https://restfulapi.net/
本节小结
在本节中,我们设计了完整的微服务拆分方案:
第一个是服务拆分方案。 将单体商城应用拆分为6个微服务,每个服务职责清晰、边界明确。
第二个是数据库拆分设计。 为每个服务设计了独立的数据库和表结构,保证数据隔离。
第三个是API接口设计。 为每个服务设计了RESTful API接口,明确了服务间的通信方式。
第四个是数据一致性方案。 设计了分布式事务和最终一致性方案,保证数据一致性。
第五个是服务依赖关系。 明确了服务间的调用关系,为后续实现打下基础。
这就是商城服务拆分设计。合理的服务拆分是微服务架构的基础,为后续的服务实现和组件集成提供了清晰的架构指导。
在下一节,我们将进行服务拆分实战,实际创建这些服务项目。