拆分 Laravel 微服务应按限界上下文而非目录结构,聚焦解决数据库打满、Excel阻塞、代码冲突等真实瓶颈;需独立数据库、事件驱动、最终一致性及网络容错设计。

高并发下拆分 Laravel 微服务,不是为了“上微服务”而拆,而是为了解决真实瓶颈:数据库连接打满、Excel 导入卡死主服务、小功能不敢上线、几十人改同一块代码天天冲突。拆对了,能横向扩容下单服务而不动报表;拆错了,只是把单体换了个壳,还多了一堆网络超时和事务不一致。
按限界上下文拆,别按 Controller/Model 目录硬切
很多人一上来就建 user-service、order-service,然后把 UserController 和 OrderModel 拷过去——这没用。关键看业务语义是否自洽:
- “下单”必须包含库存扣减 + 优惠券核销 + 订单写入,三者要原子一致 → 它们必须在同一个服务里
- “物流轨迹推送”失败可重试、延迟容忍高 → 单独拆成
logistics-service,通过OrderPlaced事件触发 - 若
admin_users表被多个模块直连,说明认证没边界 → 必须抽象出auth-service,其他服务只调/api/v1/users/{id}
用事件风暴梳理出核心领域事件(如 PaymentConfirmed、InventoryReserved),再反推哪些聚合根必须共存,比看目录结构靠谱得多。
Excel、报表、文件处理必须剥离为独立服务
Laravel-Excel 在主服务里跑大文件导入,一次 OOM 就让整个 API 网关不可用。这不是配置调优能解决的,是职责错位:
- 新建独立 Laravel 项目
excel-service,只装maatwebsite/excel和redis队列驱动,不引入任何业务模型 - 主服务发任务只传
file_url、template_id、callback_url,绝不传二进制流 -
excel-service内部用QueuedWriter+Filesystem::disk('s3')直接落盘,避免Storage::get()加载大文件到内存 - 导出结果通过
callback_url回调或写入共享 Redis key,主服务轮询或监听事件获取状态
数据库和服务必须同步拆,不能“服务分家、DB 同居”
服务拆了但还共用一个 MySQL 实例?那慢查询、锁表、连接池打满,所有服务一起卡死:
- 每个微服务对应独立数据库实例或 schema,连接走
config/database.php中的connections分离项,禁用复用default - 跨服务查数据(比如订单页显示用户昵称)禁用实时 JOIN,改用最终一致性:监听
UserUpdated事件,在订单库本地缓存user_nickname字段 - laravel-admin 的
admin_users若被多个管理模块共享,必须抽成auth-service,主应用删掉所有DB::table('admin_users')调用
别低估网络和队列带来的隐性延迟
原来内存里一个 matchOrder() 函数 8ms 完成,改成 HTTP 调用后可能飙到 300ms —— 这不是 bug,是通信开销。你得接受它,并针对性设计:
- 高频低延迟操作(如会话校验、权限判断)尽量留在网关层或用 Redis Lua 脚本聚合
- 非核心路径(如日志归档、通知发送)全部走消息队列,用 Horizon 管理
redis队列消费 - 服务间调用必须设超时(
guzzle_timeout≤ 2s)、熔断(spatie/laravel-circuit-breaker)、降级(返回兜底数据或空响应) - API 网关统一做请求限流(
throttle:60,1)、鉴权透传(X-User-IDheader)、链路追踪(X-Request-ID)
最常被忽略的是:拆分后事务边界变窄了,原来一个 DB 事务搞定的事,现在得靠 Saga 模式或本地消息表保障最终一致性。这点不提前想清楚,上线后数据对不上,比性能问题更难排查。


















