13 - 运行与部署指南
本章提供完整的本地运行指南,包括基础设施搭建、服务启动和端到端验证。
前置条件
| 软件 | 版本要求 | 用途 |
|---|---|---|
| Go | ≥ 1.21 | 编译和运行服务 |
| Docker + Docker Compose | 最新版 | 启动 Kafka 和 MySQL |
| curl | 任意版本 | 调用 API 验证 |
Docker Compose 启动基础设施
bash
cd 05-projects/watermill/ecommerce/deploy
docker-compose up -d该命令启动 Kafka(含 Zookeeper)和 MySQL 服务。验证状态:
bash
docker-compose ps
# 预期:kafka、zookeeper、mysql 均为 Up 状态
# 验证 MySQL
docker exec -it watermill-mysql mysql -uroot -pwatermill -e "SHOW DATABASES;"服务启动(按序)
每个服务在独立的终端窗口启动。启动顺序无严格要求(事件驱动天然解耦),但建议按依赖关系启动:
终端 1 — 订单服务(端口 8081):
bash
cd 05-projects/watermill/ecommerce
go run cmd/order-service/main.go --config=configs/order-service.yaml终端 2 — 库存服务(端口 8082):
bash
go run cmd/inventory-service/main.go --config=configs/inventory-service.yaml终端 3 — 支付服务(端口 8083):
bash
go run cmd/payment-service/main.go --config=configs/payment-service.yaml终端 4 — 通知服务(端口 8084):
bash
go run cmd/notification-service/main.go --config=configs/notification-service.yaml每个服务启动时会自动执行 AutoMigrate() 创建数据库表,并连接 Kafka。服务启动日志中应看到 "服务启动" 信息。
curl 端到端验证
创建订单(触发完整 Saga 流程):
bash
curl -X POST http://localhost:8081/orders \
-H 'Content-Type: application/json' \
-d '{
"order_id": "ORD-001",
"user_id": "U001",
"items": [{"product_id": "PROD-001", "quantity": 1, "price": 99.99}],
"total": 99.99
}'预期响应:{"order_id":"ORD-001","status":"pending"}
验证数据库状态:
bash
docker exec -it watermill-mysql mysql -uroot -pwatermill -e \
"SELECT order_id, status FROM watermill_orders.orders;"90% 概率订单状态为 confirmed,10% 概率为 cancelled(支付服务随机 10% 失败)。
日志追踪事件流
在各终端观察事件流转日志。完整成功流程的日志顺序如下:
# 订单服务
订单创建成功 {order_id: ORD-001}
已发布 OrderCreated 事件
# 库存服务
收到 OrderCreated 事件 {order_id: ORD-001}
库存预留成功 {order_id: ORD-001}
# 支付服务
库存已预留,发起支付 {order_id: ORD-001}
支付成功 {order_id: ORD-001, payment_id: xxx}
# 订单服务
收到支付完成事件 {order_id: ORD-001}
# 通知服务
通知: 用户 U001 的订单 ORD-001 已创建
通知: 订单 ORD-001 支付成功常见问题排查
| 问题 | 原因 | 解决方案 |
|---|---|---|
| Kafka 连接失败 | Docker Kafka 未启动 | docker-compose up -d 等待 10s 后重试 |
| MySQL 连接拒绝 | MySQL 未就绪 | 检查端口 3306,等待健康检查通过 |
| 消费不到消息 | Consumer group offset 已提交 | 每次测试使用不同 order_id,或重置 Kafka offset |
| 库存不足 | 数据库中无对应产品库存 | 手动插入测试数据到 inventory 表 |
| 端口冲突 | 端口已被占用 | 修改各服务 config YAML 中的 http_port |
多订单并发测试
bash
# 并发发送 10 个订单
for i in $(seq 1 10); do
curl -s -X POST http://localhost:8081/orders \
-H 'Content-Type: application/json' \
-d "{\"order_id\":\"ORD-$(printf %03d $i)\",\"user_id\":\"U001\",\"items\":[{\"product_id\":\"PROD-001\",\"quantity\":1,\"price\":99.99}],\"total\":99.99}" &
done
wait观察各服务的并发处理日志,验证乐观锁冲突重试等机制。