Golang怎么用Go实现通知系统_Golang如何实现站内信邮件短信多渠道消息推送服务【实战】

1次阅读

应定义函数式 Notifier 接口,接收 context 和已渲染 Message,Channel 用常量;SMTP 需用中转服务或合理超时配置;短信须基于 MessageID 幂等;站内信未读数存 Redis,列表用游标分页。

Golang 怎么用 Go 实现通知系统_Golang 如何实现站内信邮件短信多渠道消息推送服务【实战】

怎么设计统一的消息通道接口

Go 里没有内置的“通知服务”抽象,硬写一堆 SendEmail()SendSMS() 函数会导致调用方耦合严重,改一个渠道就要动业务逻辑。必须先定义清晰的接口,让渠道实现可插拔。

推荐用函数式接口,不强制依赖 struct 或 interface{}:

type Notifier interface {Notify(ctx context.Context, msg *Message) error }

其中 Message 至少包含 IDUserIDTitleContentChannel(如 "email""sms""inapp"),避免后续加字段时所有实现全量修改。

  • 别把模板渲染逻辑塞进 Notify() —— 渲染应前置,传入已渲染好的纯文本 /HTML
  • Channel 字段建议用常量定义(const ChannelEmail = "email"),别用字符串字面量散落各处
  • 接口方法必须接收 context.Context,否则超时控制、取消传播全失效

邮件发送为什么总卡住或报错 dial tcp: i/o timeout

这不是 Go 代码问题,而是 SMTP 配置和网络策略导致的高频失败点。本地开发用 smtp.gmail.com:587 很容易失败,因为 Gmail 默认禁用“不够安全的应用”。

立即学习 go 语言免费学习笔记(深入)”;

  • 生产环境别直连公有邮箱 SMTP,用 Mailgun / SendGrid / Amazon SES 等中转服务,它们提供稳定 API + 可观测性
  • 若必须自建 SMTP,确保 net.DialTimeout 设置合理(建议 ≤10s),并启用 STARTTLS(不是 SSL/TLS)
  • Go 标准库 net/smtp 不支持 OAuth2,Gmail/Outlook 账号需生成专用 App Password 替代账户密码
  • 错误日志里看到 dial tcp: i/o timeout,优先检查防火墙、VPC 安全组是否放行目标端口,而不是重试逻辑

短信网关怎么避免重复投递和乱序

第三方短信服务(如阿里云、腾讯云)本身不保证投递顺序,且 HTTP 请求可能因网络重试造成重复。Go 层必须做幂等控制,不能指望下游。

  • 每个消息生成唯一 MessageID(用 uuid.NewString()),并透传给短信服务商的 ExtDataSignature 字段
  • 在数据库加唯一索引:(channel, ext_id),插入前先 INSERT …… ON CONFLICT DO NOTHING(PostgreSQL)或 INSERT IGNORE(MySQL)
  • 别用时间戳或用户 ID 做幂等键——同一用户发两条相似内容会冲突
  • 异步发送时,用 time.AfterFunc 或简单轮询查状态,别依赖短信回调——回调可能延迟数分钟甚至丢失

站内信怎么做到低延迟又不压垮数据库

站内信本质是高读低写场景,但“未读数实时更新”和“列表分页拉取”极易成为瓶颈。直接 SELECT * FROM notifications WHERE user_id = ? AND read = false 在百万级数据下必然慢。

  • 把未读数存在 Redis 的 HSET user:<id> unread_count 12</id>,每次新消息 +1,标记已读 -1;DB 只存原始记录,不承担计数压力
  • 消息列表用“游标分页”而非 OFFSET:按 created_at DESC, id DESC 排序,请求带 cursor=2024-03-19T10:00:00Z_12345,SQL 改为 WHERE created_at
  • 冷数据归档:6 个月前的已读消息迁出主表,避免 WHERE user_id = ? 全表扫描
  • 别在事务里发通知——通知失败不该回滚业务操作(比如下单成功但站内信没发出去,订单仍应成立)

多渠道推送真正难的不是发,是状态收敛、失败重试策略、以及用户关闭某渠道后的历史消息屏蔽逻辑。这些细节不提前约定清楚,上线后查漏补缺的成本远高于初期多花两小时建模。

星耀云
版权声明:本站原创文章,由 星耀云 2026-03-18发表,共计1683字。
转载说明:转载本网站任何内容,请按照转载方式正确书写本站原文地址。本站提供的一切软件、教程和内容信息仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。
text=ZqhQzanResources