Laravel通知不卡队列需正确配置驱动和队列:填准服务商凭证,建好队列表或配对Redis,确保模型实现Notifiable,routeNotificationForSms返回有效手机号,微信用对应环境配置与订阅消息类,双通道需手动控制降级逻辑。

通知驱动怎么配才不卡在 queue 里
Laravel 的通知默认走同步发送,但一加短信或微信就容易卡住响应,必须切到队列。问题不在通知本身,而在驱动配置和队列启动状态。
-
config/services.php里得填对服务商凭证,比如aliyun_sms或wechat的app_id、secret,漏一个字段,Notification::send()表面成功,实际日志里报Invalid credentials - 用
database队列时,别忘了跑php artisan queue:table+migrate;用redis就得确认REDIS_HOST没写成localhost(Docker 环境常见) - 发通知前务必检查模型是否实现了
MustVerifyEmail或绑了Notifiabletrait,否则routeNotificationForSms()根本不会被调用
routeNotificationForSms() 返回空字符串就收不到短信
这个方法是 Laravel 找手机号的唯一入口,它不抛异常,只静默跳过 —— 所以返回空、null、0 或未定义属性都会导致短信丢弃。
- 典型错误:用户表字段叫
mobile,但方法里写return $this->phone;,结果返回null - 微信模板消息需要
open_id,但有些项目把 openid 存在关联表里,这时不能直接$this->wechat_openid,得加一层判断:return $this->wechatUser?->open_id ?? ''; - 如果用阿里云短信,
toSms()方法里传的template必须和控制台审核通过的模板 code 完全一致,大小写、下划线都不能错
本地开发时微信通知总提示 invalid credential
不是 token 过期,而是环境没区分测试号和正式号。微信开放平台对测试号的 access_token 和 jsapi_ticket 有效期只有 2 小时,且不能复用正式环境的缓存。
- 在
config/wechat.php里按环境拆配置:'default' => env('WECHAT_ENV', 'dev'),然后dev下用测试号的app_id和secret - 别用
php artisan config:cache缓存带环境变量的配置,否则env('WECHAT_ENV')会固化成 production - 测试号没有「模板消息」权限,只能用「订阅消息」,对应的通知类得继承
Illuminate\Notifications\Messages\WeChatMessage,而不是旧版WeChatTemplateMessage
短信+微信双通道怎么避免重复发送
一个通知触发多个渠道,但业务上往往只需要其中一个送达即可,比如用户设置了“优先微信,失败再发短信”。Laravel 默认并行发,没法自动降级。
- 别在
via()里硬写['sms', 'wechat'],改用条件逻辑:return $this->prefersWechat() ? ['wechat'] : ['sms']; - 如果真要兜底,得手动控制:先
try/catch发微信,捕获WeChatException后再发短信,而不是靠通知系统自动分发 - 注意:短信网关可能返回 200 但实际没发出去(比如余额不足),这类错误不会抛出异常,得解析响应体里的
Code字段,is_success为 false 时才算失败
多通道的核心不是堆配置,是明确每条通知的送达策略——微信快但依赖用户授权,短信稳但有频控。选哪个、怎么 fallback、失败后要不要重试,这些逻辑得写进通知类里,而不是指望框架自动处理。











