You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

微服务架构中如何处理Laravel Notification功能?

Laravel微服务架构下通知服务的实现方案

在微服务架构中,Notification服务不需要访问User服务的完整模型,只需要获取发送通知必需的用户数据即可。下面是具体的实现思路和示例:

核心思路

微服务间通过API传递最小化的用户通知数据(如邮箱、推送Token、手机号等),Notification服务内部创建一个极简的"通知收件人"类,而非重复定义完整的User模型,以此适配Laravel的Notifiable特性。

具体实现示例

1. Notification服务中创建极简的收件人类

这个类仅保留通知渠道所需的字段,并实现Notifiable trait要求的路由方法:

// app/Models/NotificationRecipient.php
namespace App\Models;

use Illuminate\Notifications\Notifiable;

class NotificationRecipient
{
    use Notifiable;

    public int $id;
    public string $email;
    public ?string $fcm_token;

    public function __construct(array $userData)
    {
        $this->id = $userData['id'];
        $this->email = $userData['email'];
        $this->fcm_token = $userData['fcm_token'] ?? null;
    }

    // 定义邮件通知的接收地址
    public function routeNotificationForMail($notification): string
    {
        return $this->email;
    }

    // 定义FCM推送的Token
    public function routeNotificationForFcm($notification): ?string
    {
        return $this->fcm_token;
    }

    // 如需支持短信,可添加对应路由方法
    // public function routeNotificationForSms($notification): string
    // {
    //     return $this->phone;
    // }
}

2. 创建常规的Laravel通知类

和单体架构中的写法一致,定义多渠道的通知内容:

// app/Notifications/OrderShipped.php
namespace App\Notifications;

use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Messages\FcmMessage;

class OrderShipped extends Notification implements ShouldQueue
{
    use Queueable;

    private array $orderDetails;

    public function __construct(array $orderDetails)
    {
        $this->orderDetails = $orderDetails;
    }

    public function via($notifiable): array
    {
        // 根据收件人数据动态选择渠道(比如无FCM Token则只发邮件)
        $channels = ['mail'];
        if ($notifiable->fcm_token) {
            $channels[] = 'fcm';
        }
        return $channels;
    }

    public function toMail($notifiable): MailMessage
    {
        return (new MailMessage)
            ->subject('您的订单已发货')
            ->line('订单号: ' . $this->orderDetails['order_id'])
            ->line('预计3个工作日内送达')
            ->action('查看物流', url("/track/{$this->orderDetails['tracking_no']}"));
    }

    public function toFcm($notifiable): FcmMessage
    {
        return (new FcmMessage)
            ->content([
                'title' => '订单发货通知',
                'body' => "您的订单#{$this->orderDetails['order_id']}已发出,点击查看物流",
            ])
            ->data([
                'order_id' => $this->orderDetails['order_id'],
                'tracking_no' => $this->orderDetails['tracking_no'],
            ]);
    }
}

3. Notification服务提供API接口接收通知请求

暴露接口让其他服务(如User服务)触发通知:

// routes/api.php
use Illuminate\Http\Request;
use App\Models\NotificationRecipient;
use App\Notifications\OrderShipped;

Route::post('/notifications/order-shipped', function (Request $request) {
    // 验证请求参数
    $validated = $request->validate([
        'user' => 'required|array',
        'user.id' => 'required|integer',
        'user.email' => 'required|email',
        'user.fcm_token' => 'nullable|string',
        'order_details' => 'required|array',
        'order_details.order_id' => 'required|string',
        'order_details.tracking_no' => 'required|string',
    ]);

    // 创建收件人实例并发送通知
    $recipient = new NotificationRecipient($validated['user']);
    $recipient->notify(new OrderShipped($validated['order_details']));

    return response()->json(['status' => 'notification_sent']);
});

4. User服务调用Notification服务的接口

在User服务中,当需要触发通知时,调用上述API并传递必要的用户和业务数据:

// User服务中触发通知的代码示例
use Illuminate\Support\Facades\Http;
use App\Models\User;

$user = User::find(1);
$orderDetails = [
    'order_id' => 'ORD-20240501001',
    'tracking_no' => 'TRK-789456',
];

// 调用Notification服务的API
Http::post('http://notification-service/api/notifications/order-shipped', [
    'user' => [
        'id' => $user->id,
        'email' => $user->email,
        'fcm_token' => $user->fcm_token,
    ],
    'order_details' => $orderDetails,
]);

额外建议

  • 可以使用DTO类(如UserNotificationData)来规范服务间传递的用户数据,避免参数混乱
  • 启用Laravel队列处理通知发送,避免阻塞主服务的请求响应
  • 若需保证数据一致性,可考虑在User服务的用户信息变更时,主动同步通知所需字段到Notification服务的缓存或数据库中

内容的提问来源于stack exchange,提问作者Hanie Asemi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 04:20:28