【基于 Swoole+Hyperf 的微服务实战】第九周·周四:实现订单服务并通过网关聚合下单接口
【基于 SwooleHyperf 的微服务实战】第九周·周四实现订单服务并通过网关聚合下单接口今天我们进入第九周周四核心目标是实现订单服务并通过网关聚合下单接口完成从客户端到订单、库存、商品服务的全链路贯通。昨天我们已经有了商品和库存服务今天将创建订单服务并让网关作为统一入口整合 JWT 鉴权和限流为明天的 Saga 分布式事务奠定基础。今日目标创建order-service项目配置数据库、RPC 客户端、Consul 注册。实现订单服务的CreateOrderRPC 接口内部通过 RPC 调用库存服务冻结库存调用商品服务获取商品信息调用用户服务校验用户。在网关中创建聚合下单接口POST /orders通过 RPC 客户端调用订单服务并在此应用JWT 鉴权和限流50 QPS。测试全链路注册用户 → 登录获取 Token → 通过网关下单 → 订单生成、库存冻结、商品信息正确。验证限流效果使用压测工具确认超过 50 QPS 后返回 429。一、创建订单服务并配置环境约 45 分钟1. 创建项目docker-composeexecswoolebashcd/var/www/servicescomposercreate-project hyperf/hyperf-skeleton ordercdordercomposerrequire hyperf/database hyperf/redis hyperf/json-rpc hyperf/service-governance-consul hyperf/guzzle设置端口9505避免与现有服务冲突数据库为order_db。2. 配置数据库和 RPC 客户端.env设置数据库连接指向mysql容器库order_db。config/autoload/databases.php按环境变量配置。config/autoload/server.php添加 JSON-RPC 服务端监听9505servers[[namejsonrpc,typeServer::SERVER_HTTP,host0.0.0.0,port9505,callbacks[Event::ON_REQUEST[\Hyperf\JsonRpc\HttpServer::class,onRequest],],],],config/autoload/services.php配置 Consul 注册和消费者。消费者需添加三个依赖服务的发现consumers[[nameUserService,registry[protocolconsul,addresshttp://consul:8500],],[nameProductService,registry[protocolconsul,addresshttp://consul:8500],],[nameInventoryService,registry[protocolconsul,addresshttp://consul:8500],],],3. 数据库表结构在order_db中创建orders表通过 SQL 文件或迁移CREATETABLEorders(idBIGINTUNSIGNEDAUTO_INCREMENTPRIMARYKEY,order_idVARCHAR(64)NOTNULLUNIQUE,user_idINTNOTNULL,product_idINTNOTNULL,amountDECIMAL(10,2)NOTNULL,statusENUM(pending,frozen,paid,cancelled)NOTNULLDEFAULTpending,created_atTIMESTAMPDEFAULTCURRENT_TIMESTAMP,updated_atTIMESTAMPDEFAULTCURRENT_TIMESTAMPONUPDATECURRENT_TIMESTAMP);二、知识核心订单服务职责与同步调用流程约 1 小时订单服务的CreateOrder需要做几件事校验用户存在调用用户服务getUserById。校验商品存在且价格正确调用商品服务getProductById。调用库存服务freeze冻结库存。创建订单记录状态设为frozen。为什么不用 Saga今天先用同步调用实现基本流程保证核心链路可用。明天我们会引入 Saga 协调器将这些同步调用拆分为异步命令并增加补偿逻辑从而解决分布式事务问题。今天重点体验服务间协作和网关聚合。订单服务的接口定义我们将订单服务作为一个 RPC 服务暴露CreateOrder方法返回订单信息。也可以暴露GetOrder等。三、实战编写订单服务与网关聚合约 2.5 小时步骤 1定义订单服务契约在订单服务中创建app/JsonRpc/OrderServiceInterface.php?phpnamespaceApp\JsonRpc;useHyperf\RpcServer\Annotation\RpcService;#[RpcService(name:OrderService,protocol:jsonrpc-http,server:jsonrpc)]interfaceOrderServiceInterface{publicfunctioncreateOrder(int$userId,int$productId,float$amount):array;publicfunctiongetOrder(string$orderId):array;}步骤 2实现订单服务创建app/JsonRpc/OrderService.php?phpnamespaceApp\JsonRpc;useApp\Model\Order;useHyperf\Di\Annotation\Inject;useHyperf\RpcClient\Annotation\RpcClient;useApp\JsonRpc\UserServiceInterface;useApp\JsonRpc\ProductServiceInterface;useApp\JsonRpc\InventoryServiceInterface;useHyperf\Utils\Str;#[RpcService(name:OrderService,protocol:jsonrpc-http,server:jsonrpc)]classOrderServiceimplementsOrderServiceInterface{#[RpcClient(name:UserService)]privateUserServiceInterface$userService;#[RpcClient(name:ProductService)]privateProductServiceInterface$productService;#[RpcClient(name:InventoryService)]privateInventoryServiceInterface$inventoryService;publicfunctioncreateOrder(int$userId,int$productId,float$amount):array{// 1. 校验用户$user$this-userService-getUserById($userId);if(empty($user)){thrownew\InvalidArgumentException(用户不存在);}// 2. 校验商品$product$this-productService-getProductById($productId);if(empty($product)){thrownew\InvalidArgumentException(商品不存在);}// 金额可简单校验if($amount0){thrownew\InvalidArgumentException(金额错误);}// 3. 冻结库存数量暂定为1实际应参数化$frozen$this-inventoryService-freeze($productId,1);if(!$frozen){thrownew\RuntimeException(库存不足);}// 4. 创建订单$orderId(string)Str::uuid();Order::create([order_id$orderId,user_id$userId,product_id$productId,amount$amount,statusfrozen,]);return[order_id$orderId,user_id$userId,product_id$productId,amount$amount,statusfrozen,];}publicfunctiongetOrder(string$orderId):array{$orderOrder::where(order_id,$orderId)-first();return$order?$order-toArray():[];}}步骤 3创建模型和依赖绑定app/Model/Order.php继承Hyperf\DbConnection\Model\Model$table orders。config/autoload/dependencies.php绑定接口到实现。步骤 4启动订单服务并验证 RPC启动订单服务直接通过curl测试 RPC 接口curl-XPOST http://localhost:9505-HContent-Type: application/json\-d{jsonrpc:2.0,method:order/createOrder,params:[1,1,99.00],id:1}前提是用户 ID1 存在商品 ID1 存在且库存够应返回订单信息并检查库存服务的冻结量是否增加。步骤 5在网关中创建聚合下单接口网关需要暴露一个 RESTful 下单接口POST /orders内部调用订单服务的 RPC同时网关负责鉴权和限流。5.1 网关中增加订单服务消费者网关的config/autoload/services.php添加消费者[nameOrderService,registry[protocolconsul,addresshttp://consul:8500],],5.2 创建网关侧的订单聚合服务新建app/Service/OrderService.php或叫 OrderClientWrapper?phpnamespaceApp\Service;useHyperf\RpcClient\Annotation\RpcClient;useApp\JsonRpc\OrderServiceInterface;classOrderServiceWrapper{#[RpcClient(name:OrderService)]privateOrderServiceInterface$orderService;publicfunctioncreateOrder(int$userId,int$productId,float$amount):array{return$this-orderService-createOrder($userId,$productId,$amount);}}5.3 创建网关控制器新建app/Controller/OrderController.php?phpnamespaceApp\Controller;useApp\Service\OrderServiceWrapper;useHyperf\HttpServer\Annotation\Controller;useHyperf\HttpServer\Annotation\RequestMapping;useHyperf\Di\Annotation\Inject;#[Controller(prefix:/orders)]classOrderControllerextendsAbstractController{#[Inject]privateOrderServiceWrapper$orderService;#[RequestMapping(path:,methods:post)]publicfunctioncreate(){$userId$this-request-getAttribute(user_id);// 由 JWT 中间件注入if(!$userId){return$this-response-json([code401,message未登录])-withStatus(401);}$productId(int)$this-request-input(product_id);$amount(float)$this-request-input(amount);try{$order$this-orderService-createOrder($userId,$productId,$amount);return[code200,data$order];}catch(\Throwable$e){return$this-response-json([code400,message$e-getMessage()])-withStatus(400);}}}5.4 将/orders加入网关自身路由白名单避免被转发中间件代理。步骤 6配置限流中间件下单接口 50 QPS在网关的RateLimitMiddleware中为/orders路径设置独立限流。修改resolveLimiter方法privatefunctionresolveLimiter(string$uri):?string{if(str_starts_with($uri,/orders)){returnapi_order;}// ... 其他}并在rate_limit.php中添加api_order配置api_order[capacity50,rate50,],这样下单接口每秒最多允许 50 个请求令牌桶容量和速率都设 50可实现严格限流。步骤 7JWT 鉴权已在全局中间件中实现确保HybridAuthMiddleware或之前的JwtAuthMiddleware处于活跃状态且/orders不在白名单中因此只有携带有效 JWT 的请求才能到达控制器。四、全链路测试与压测验证约 1 小时1. 准备测试数据通过用户服务注册用户若之前未注册可 RPC 调用注册确保商品 ID1 存在库存stocks表有足够库存2. 流程测试# 登录获取 TokenTOKEN$(curl-s-XPOST http://localhost:9500/auth/login-HContent-Type: application/json-d{username:alice,password:123456}|jq-r.data.token)# 下单curl-XPOST http://localhost:9500/orders\-HAuthorization: Bearer$TOKEN\-HContent-Type: application/json\-d{product_id:1,amount:99.00}应返回订单信息状态frozen。3. 验证库存冻结curlhttp://localhost:9504-XPOST-HContent-Type: application/json\-d{jsonrpc:2.0,method:inventory/getStock,params:[1],id:1}frozen应为 1available减少。4. 限流测试使用ab或wrk以超过 50 QPS 的并发请求下单接口wrk-t4-c100-d10s--latency-HAuthorization: Bearer$TOKEN-spost_order.lua http://localhost:9500/orders需要写一个简单的 Lua 构造 POST body。观察部分请求返回 429并且后端订单服务压力可控。5. 未登录拦截测试不带 Token 请求下单接口应返回 401。五、今日作业与学习产出提交代码将order-service项目、网关聚合代码、限流配置提交到 Git。增强订单服务添加GetOrder接口供查询。记录订单操作日志事件监听写入日志或数据库。学习笔记绘制下单全链路时序图客户端 - 网关JWT限流- 订单服务 RPC - 用户/商品/库存服务 RPC - 数据库。思考同步调用库存冻结的潜在问题超时、失败为明天的 Saga 改造做铺垫。挑战任务为订单服务添加熔断器当库存服务连续失败时自动降级返回“系统繁忙”。使用 Redis 缓存商品信息减少订单服务对商品服务的 RPC 调用。今天你已经将电商系统的核心交易链路打通客户端可以安全、受控地下单库存得到实时冻结。明天我们将引入 Saga 分布式事务和延迟队列实现支付超时自动取消和补偿恢复让整个系统具备最终一致性能力。

相关新闻

Hyperf Translation 国际化组件实战指南:语言文件、占位符与复数规则的完整实现

Hyperf Translation 国际化组件实战指南:语言文件、占位符与复数规则的完整实现

后端微服务 【免费下载链接】hyperf 🚀 A coroutine framework that focuses on hyperspeed and flexibility. Building microservice or middleware with ease. 项目地址: https://gitcode.com/gh_mirrors/hy/hyperf 点击查看 免费下载 Hyperf 的翻译&…

2026/11/11 15:23:22 阅读更多 →
ORA-01623 无法删除redo

ORA-01623 无法删除redo

这个是线程2的redo,当前环境是单机,关闭线程2即可删除关闭集群模式(重启生效) ALTER SYSTEM SET cluster_databaseFALSE SCOPESPFILE;关闭线程2(如果可以直接关闭) ALTER DATABASE DISABLE THREAD 2;

2026/11/9 23:31:34 阅读更多 →
DeepSeek V4 MegaMoE与DeepGEMM:大模型推理底层优化拆解

DeepSeek V4 MegaMoE与DeepGEMM:大模型推理底层优化拆解

做算法的人学 Infra,最怕的就是被一堆源码和术语劝退。但如果你真的想把一个大模型跑明白,绕不开 GPU 底层发生了什么。今天这篇是“算法同学学 Infra 系列”的第三篇,专门讲 DeepSeek V4 里最核心的 MegaMoE 架构,以及把它跑起来…

2026/11/11 0:34:56 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/11/12 5:00:00 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/11/12 5:13:20 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/11/12 5:13:20 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/11/11 17:16:37 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/11/11 17:16:37 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/11/12 5:13:20 阅读更多 →

日新闻

周新闻

月新闻