site logo

Marico's space

打造 Laravel NATS:现代化、生产就绪的 Laravel NATS 集成方案

编程技术 2026-08-03 11:28:15 8

最近折腾微服务消息队列,在 Laravel 项目里集成 NATS(一个轻量级消息系统),踩了几个坑,终于把这块打通。这篇把问题和解决方案说清楚,顺便介绍下我做的 Laravel NATS 包。

做分布式系统,最大的挑战之一就是让服务之间可靠通信,又不搞出强耦合。Laravel 本身对队列、事件、广播、任务的处理已经相当完善,但涉及到 NATS 这个消息中间件,生态就比较匮乏了。

这就是我写 Laravel NATS 的初衷。

这个包不是简单封装一个现成的 PHP 客户端,而是想做真正的 Laravel 优先开发体验,同时把 NATS 的全部能力暴露给现代事件驱动架构。

这篇文章会聊到:

  • 为什么做这个包
  • 为什么考虑用 NATS
  • Laravel NATS 的实现原理
  • 生产级特性
  • 代码示例
  • 实际业务场景
  • 和其他方案的差异

什么是 NATS?

NATS 是一款专为云原生应用设计的高性能轻量级消息系统。

跟传统队列不一样,NATS 的核心关注点是:

  • 极低延迟
  • 高吞吐
  • 简洁的发布/订阅消息模型
  • 请求/响应 API
  • JetStream 持久化
  • 水平扩展能力

传统方式下,应用之间直接互相调用:

订单服务 │ ▼
通知服务

改成 NATS 之后,应用只管发布事件:

订单服务 │ ▼ NATS 服务器 │ │ ▼ ▼
短信 数据分析

每个服务都独立了,耦合彻底消失。

为什么 Laravel 需要更好的 NATS 包

现有的包大多数直接暴露底层 PHP 客户端。

这意味着开发者还是得理解:

  • 客户端生命周期
  • 连接管理
  • 序列化
  • 订阅机制
  • 队列消费者
  • JetStream API

但 Laravel 开发者期待的不一样。

我们习惯了这样的 API:

Cache::put(); Queue::push(); Event::dispatch();

Laravel NATS 的目标就是让 NATS 用起来跟这些一样自然。

安装 Laravel NATS

安装过程很直接。

composer require zaeem2396/laravel-nats php artisan vendor:publish --tag=nats-config

然后配置环境变量:

NATS_HOST=127.0.0.1
NATS_PORT=4222
NATS_USER=
NATS_PASS=
NATS_TOKEN=

完事。

发布消息

发布事件应该很简单。

Laravel NATS 提供了现代化的 NatsV2 Facade。

use LaravelNats\Laravel\Facades\NatsV2; NatsV2::publish( 'orders.created', [ 'order_id' => 123 ], [ 'X-Request-Id' => 'req-1' ]
);

注意,没有连接管理。

没有手动编码。

没有模板代码。

直接发就完了。

订阅事件

订阅也一样简洁。

NatsV2::subscribe('orders.created', function ($message) { logger($message->payload()); });

这样 Laravel 应用就能几乎实时响应事件了。

为什么用 NatsV2?

这个包支持两条路线:

  • 遗留 API
  • 现代化的 NatsV2

新项目应该始终使用 NatsV2,因为它基于更新版的 basis-company/nats 客户端,同时保持了 Laravel 友好风格。

这样做的好处:

  • 更清晰的 API
  • 更好的可维护性
  • 长期兼容性更有保障
  • 迁移路径更平滑

生产级特性

这个项目最大的目标不只是"让 NATS 能跑起来"。

目标是真正能在生产环境用。

主要特性包括:

配置校验

消息系统配置错了很难调试。

Laravel NATS 会在建立连接之前先校验配置,把问题拦在门外。

TLS 生产保护

生产环境跑不加密的消息传输是严重的安全隐患。

Laravel NATS 包含可选的 TLS 强制选项,防止不小心部署成不安全的方式。

可选 ACL 支持

多服务架构通常需要精细的访问控制。

这个包提供了可选的 ACL 集成来保护服务间通信。

幂等性支持

分布式系统里消息重试不可避免。

没有幂等性的话:

支付已创建 ↓ 支付已创建 ↓ 支付已创建

可能不小心创建三笔支付。

Laravel NATS 内置可选的幂等性支持,重复投递不会变成重复的业务操作。

可观测性

我最兴奋的一个特性是可观测性。

消息系统能追踪请求在服务间的流转,调试会轻松很多。

Laravel NATS 支持:

  • 链路追踪
  • 请求头
  • W3C Trace Context
  • 可选的可观测性集成

分布式调试变得简单很多。

队列驱动支持

这个包还包含了专用的队列驱动。

不是把 NATS 当成另一个传输层就完事了,而是让 Laravel 应用能把它融入队列生态。

开发者可以继续用熟悉的 Laravel 队列写法,底层跑的是 NATS。

Header 支持

1.6 版本引入了 Header 辅助方法。

例子:

NatsV2::publish( 'orders.created', $payload, [ 'X-Request-Id' => $requestId, 'traceparent' => $traceparent ]
);

Header 让这些信息可以随消息传递:

  • 链路追踪 ID
  • 多租户 ID
  • 认证元数据
  • 关联 ID

不需要改动消息体本身。

Docker 支持

上手 NATS 不应该要折腾半天。

仓库里自带 Docker 支持。

docker compose up -d

Laravel 应用立刻就能跟本地 NATS 服务器通信了。

这对以下场景特别有用:

  • 本地开发
  • CI 流水线
  • 集成测试

文档优先

一个经常被忽视的决策是文档。

很多开源项目代码写得漂亮,但文档一塌糊涂。

Laravel NATS 刻意采用索引优先的文档结构。

开发者可以快速定位:

  • 安装
  • JetStream
  • 迁移
  • 队列
  • 故障排查
  • 示例

这让上手体验好很多。

为什么用 NATS 而不是 Redis?

Redis 队列很好用。

但 NATS 解决的是不同的问题。

Redis NATS
队列为核心 事件驱动
主要处理任务 服务间通信
路由能力有限 主题式路由
适合任务处理 适合微服务

如果你的场景是:

  • SaaS 平台
  • 分布式系统
  • 事件驱动应用
  • 多个 Laravel 服务协同

NATS 是非常好的选择。

实际案例

拿电商平台举例。

用户下单之后:

订单服务 ↓ orders.created

多个服务立刻收到事件:

库存服务 短信服务 数据分析服务 发票服务 风控服务

这些服务之间完全不知道彼此存在。

它们只管订阅事件。

这种架构扩展起来容易太多。

Laravel NATS 的亮点

主要有几个方面。

Laravel 优先体验

没有直接暴露原始 PHP 客户端,包的设计拥抱了 Laravel 惯例。

  • Facade
  • 配置系统
  • 服务提供者
  • 队列
  • 环境配置

用起来都很熟悉。

现代 API

NatsV2 提供了比之前方案更干净的抽象。

开发者可以专注业务,而不是纠结传输层的细节。

生产就绪

这些特性通常是开发者自己写:

  • 配置校验
  • TLS 安全措施
  • 幂等性
  • 重连辅助
  • 可观测性
  • W3C 链路追踪

Laravel NATS 开箱就有。

遗留兼容

迁移生产系统很难。

Laravel NATS 没有强行破坏性更新,遗留 API 保持可用,同时鼓励迁移到新实现。

这让采纳门槛低很多。

文档

好的文档本身就是功能。

这个包包含:

  • 示例
  • 迁移指南
  • 故障排查
  • 路线图
  • 更新日志
  • Docker 搭建说明

上手比很多消息库都轻松。

为什么做这个项目

这个项目不是为了简单包装一个现成的 PHP 库。

目标是改善 Laravel 生态,让 NATS 成为框架的自然组成部分。

Laravel 开发者值得同样的优雅体验,不管用的是队列、Redis、事件还是 NATS。

开源应该降低复杂度,而不是暴露复杂度。

这就是 Laravel NATS 的理念。

路线图

这个包会继续演进。

我感兴趣的扩展方向包括:

  • 更深入的 Laravel 集成
  • 增强 JetStream 支持
  • 更丰富的可观测性
  • 更好的测试工具
  • 开发者工具
  • 更多生产特性

目标很简单:

让 Laravel NATS 成为每个使用 NATS 的 Laravel 应用的首选消息包。

最后

构建分布式系统不应该牺牲 Laravel 的开发体验。

Laravel NATS 把这些结合在一起:

  • Laravel 优先的 API
  • 现代 NATS 特性
  • 生产级安全保护
  • 更完善的文档
  • 轻松上手
  • 优秀的开发者体验

无论你在做微服务平台、事件驱动 SaaS、实时后端,还是只是想试试 NATS,Laravel NATS 都致力于扫清障碍,让你专注写代码而不是搭基础设施。