5.5商城服务拆分设计

分类: 微服务架构理论与实践

商城服务拆分设计

本节将根据商城业务需求,设计微服务拆分方案。本节将学习如何将单体商城应用拆分为多个微服务。

本节将学习:用户服务(User Service)、商品服务(Product Service)、订单服务(Order Service)、支付服务(Payment Service)、库存服务(Inventory Service),以及网关服务(Gateway Service)。

完整的服务拆分方案

拆分原则

微服务拆分原则:

  1. 单一职责:每个服务只负责一个业务领域
  2. 数据独立:每个服务拥有独立的数据库
  3. 服务自治:服务可以独立开发、部署、扩展
  4. 接口清晰:服务间通过明确的 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用户注册UserRegisterDTOUserVO
POST/api/users/login用户登录LoginDTOLoginResponse
GET/api/users/{id}查询用户信息-UserVO
PUT/api/users/{id}更新用户信息UserUpdateDTOUserVO
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, keywordPageResult
GET/api/products/{id}商品详情-ProductVO
POST/api/products创建商品ProductCreateDTOProductVO
PUT/api/products/{id}更新商品ProductUpdateDTOProductVO
DELETE/api/products/{id}删除商品-Boolean
GET/api/products/categories分类树-List
GET/api/products/search商品搜索Query: keyword, filtersPageResult

订单服务(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创建订单OrderCreateDTOOrderVO
GET/api/orders/{id}查询订单详情-OrderVO
GET/api/orders查询订单列表(分页)Query: userId, status, page, sizePageResult
PUT/api/orders/{id}/status更新订单状态OrderStatusUpdateDTOBoolean
POST/api/orders/{id}/cancel取消订单CancelOrderDTOBoolean
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创建支付订单PaymentCreateDTOPaymentVO
GET/api/payments/{id}查询支付订单-PaymentVO
GET/api/payments/order/{orderId}根据订单ID查询-PaymentVO
POST/api/payments/{id}/pay发起支付-PaymentResponse
POST/api/payments/callback支付回调CallbackDTOBoolean
POST/api/payments/{id}/refund申请退款RefundDTOBoolean

库存服务(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扣减库存InventoryDeductDTOBoolean
POST/api/inventory/release释放库存InventoryReleaseDTOBoolean
POST/api/inventory/adjust调整库存InventoryAdjustDTOBoolean
GET/api/inventory/low-stock低库存商品列表Query: thresholdList
GET/api/inventory/{productId}/records库存变更记录Query: page, sizePageResult

网关服务(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 设计规范:

  1. URL 设计

    • 使用名词,不使用动词
    • 使用复数形式:/api/users 而不是 /api/user
    • 使用层级结构:/api/users/{userId}/orders
  2. HTTP 方法

    • GET:查询操作
    • POST:创建操作
    • PUT:更新操作(完整更新)
    • PATCH:部分更新
    • DELETE:删除操作
  3. 响应格式

    { "code": 200, "message": "success", "data": {}, "timestamp": "2024-01-01T00:00:00" }
  4. 错误响应

    { "code": 400, "message": "Bad Request", "error": "Validation failed", "timestamp": "2024-01-01T00:00:00" }

服务间调用接口

订单服务调用其他服务的接口:

  1. 调用用户服务

    • GET /api/users/{userId} - 查询用户信息
    • GET /api/users/{userId}/exists - 验证用户是否存在
  2. 调用商品服务

    • GET /api/products/{productId} - 查询商品信息
    • POST /api/products/batch - 批量查询商品
  3. 调用库存服务

    • POST /api/inventory/deduct - 扣减库存
    • POST /api/inventory/release - 释放库存
    • GET /api/inventory/{productId} - 查询库存
  4. 调用支付服务

    • POST /api/payments - 创建支付订单
    • GET /api/payments/{paymentId} - 查询支付状态

数据一致性方案设计

分布式事务场景

需要分布式事务的场景:

  1. 订单创建流程

    • 订单服务:创建订单
    • 库存服务:扣减库存
    • 支付服务:创建支付订单
    • 需要保证:要么全部成功,要么全部回滚
  2. 订单支付流程

    • 支付服务:处理支付
    • 订单服务:更新订单状态
    • 库存服务:确认库存扣减(如果支付成功)
    • 需要保证:支付和订单状态一致

一致性方案

数据一致性方案:

  1. 强一致性(分布式事务)

    • 使用 Seata AT 模式
    • 适用于:订单创建、支付处理
    • 优点:数据强一致
    • 缺点:性能开销大
  2. 最终一致性(消息队列)

    • 使用 RocketMQ 事务消息
    • 适用于:订单状态同步、库存扣减确认
    • 优点:性能好、解耦
    • 缺点:有延迟
  3. 补偿机制(Saga 模式)

    • 使用 Seata Saga 模式
    • 适用于:复杂业务流程
    • 优点:灵活、可扩展
    • 缺点:实现复杂

数据一致性设计图

服务关系图

服务拆分总结

拆分后的服务列表

服务名称端口数据库主要职责
user-service8081user_db用户管理、认证授权
product-service8082product_db商品管理、分类、搜索
order-service8083order_db订单管理、订单协调
payment-service8084payment_db支付处理、支付记录
inventory-service8085inventory_db库存管理、库存操作
gateway-service8080-统一入口、路由转发

服务依赖关系

拆分原则总结

服务拆分遵循的原则:

  1. 业务边界清晰:每个服务负责一个业务领域
  2. 数据独立:每个服务拥有独立的数据库
  3. 接口明确:服务间通过 RESTful API 通信
  4. 服务自治:服务可以独立开发、部署、扩展
  5. 故障隔离:一个服务故障不影响其他服务

官方资源

本节小结

在本节中,我们设计了完整的微服务拆分方案:

第一个是服务拆分方案。 将单体商城应用拆分为6个微服务,每个服务职责清晰、边界明确。

第二个是数据库拆分设计。 为每个服务设计了独立的数据库和表结构,保证数据隔离。

第三个是API接口设计。 为每个服务设计了RESTful API接口,明确了服务间的通信方式。

第四个是数据一致性方案。 设计了分布式事务和最终一致性方案,保证数据一致性。

第五个是服务依赖关系。 明确了服务间的调用关系,为后续实现打下基础。

这就是商城服务拆分设计。合理的服务拆分是微服务架构的基础,为后续的服务实现和组件集成提供了清晰的架构指导。

在下一节,我们将进行服务拆分实战,实际创建这些服务项目。