1.1 震惊!一个架构师竟然这样设计通知平台,解决了所有业务方的痛点!
在当今复杂的业务环境中,通知服务作为各个业务系统之间沟通的桥梁,承担着至关重要的作用。然而,随着业务规模的扩大和业务场景的多样化,传统的通知服务架构已经难以满足日益增长的需求。本文将深入剖析一个优秀架构师是如何通过巧妙的设计,解决通知平台面临的各种痛点。
通知平台的核心痛点
在构建通知平台之前,我们需要明确它所面临的核心痛点:
- 多业务方接入复杂性:不同业务方有着不同的接入需求和标准
- 多渠道支持:短信、邮件、微信、APP推送等多种通知渠道需要统一管理
- 高可用性要求:通知服务的稳定性直接影响用户体验和业务连续性
- 高并发处理:在促销活动等场景下,通知量可能瞬间激增
- 事务性通知需求:需要保证关键业务通知的可靠送达
通知平台整体架构设计
为了解决上述痛点,我们需要设计一个高内聚、低耦合的通知平台架构。下面是我们的架构设计图:
graph TB
A[业务方] --> B(接入层)
B --> C(路由分发层)
C --> D[短信渠道]
C --> E[邮件渠道]
C --> F[微信渠道]
C --> G[APP推送渠道]
C --> H[站内信渠道]
D --> I[(渠道管理)]
E --> I
F --> I
G --> I
H --> I
I --> J[监控告警]
K[管理后台] --> I
核心组件详解
- 接入层:提供统一的API接口,屏蔽底层实现细节
- 路由分发层:根据业务规则将通知消息分发到相应的渠道
- 渠道适配层:适配各种第三方通知服务提供商
- 监控告警层:实时监控系统状态,及时发现问题
通知平台核心功能设计
1. 统一接入接口设计
为了让不同业务方能够快速接入,我们需要设计一套简洁明了的统一接入接口:
go
// NotificationService 通知服务接口
type NotificationService interface {
// Send 发送通知
Send(ctx context.Context, req *SendRequest) (*SendResponse, error)
// BatchSend 批量发送通知
BatchSend(ctx context.Context, req *BatchSendRequest) (*BatchSendResponse, error)
// Query 查询通知状态
Query(ctx context.Context, req *QueryRequest) (*QueryResponse, error)
}
// SendRequest 发送请求
type SendRequest struct {
// 业务标识
BizID string `json:"biz_id"`
// 通知类型
Type NotificationType `json:"type"`
// 接收者信息
Receivers []Receiver `json:"receivers"`
// 通知内容
Content Content `json:"content"`
// 发送策略
Strategy SendStrategy `json:"strategy"`
// 回调地址
CallbackURL string `json:"callback_url"`
}
// Receiver 接收者信息
type Receiver struct {
// 接收者ID
ID string `json:"id"`
// 接收者类型
Type ReceiverType `json:"type"`
// 接收者联系方式
Contact string `json:"contact"`
}
// Content 通知内容
type Content struct {
// 标题
Title string `json:"title"`
// 正文
Body string `json:"body"`
// 附加数据
Extra map[string]interface{} `json:"extra"`
}
2. 多渠道适配器模式
为了支持多种通知渠道,我们采用适配器模式来实现渠道的统一管理:
go
// Channel 渠道接口
type Channel interface {
// Name 渠道名称
Name() string
// Send 发送消息
Send(ctx context.Context, msg *Message) error
// BatchSend 批量发送消息
BatchSend(ctx context.Context, msgs []*Message) error
// Query 查询消息状态
Query(ctx context.Context, msgID string) (*MessageStatus, error)
}
// Message 消息结构
type Message struct {
// 消息ID
ID string
// 接收者
To string
// 消息内容
Content string
// 模板ID
TemplateID string
// 模板参数
TemplateParams map[string]string
}
// SMSChannel 短信渠道实现
type SMSChannel struct {
// 短信服务商客户端
client SMSClient
// 渠道配置
config *SMSConfig
}
func (s *SMSChannel) Name() string {
return "sms"
}
func (s *SMSChannel) Send(ctx context.Context, msg *Message) error {
// 实现短信发送逻辑
req := &SMSRequest{
To: msg.To,
Content: msg.Content,
// ... 其他参数
}
resp, err := s.client.SendSMS(ctx, req)
if err != nil {
return err
}
// 处理响应
if !resp.Success {
return fmt.Errorf("send sms failed: %s", resp.Message)
}
return nil
}
// EmailChannel 邮件渠道实现
type EmailChannel struct {
// 邮件服务商客户端
client EmailClient
// 渠道配置
config *EmailConfig
}
func (e *EmailChannel) Name() string {
return "email"
}
func (e *EmailChannel) Send(ctx context.Context, msg *Message) error {
// 实现邮件发送逻辑
req := &EmailRequest{
To: []string{msg.To},
Subject: msg.Content,
// ... 其他参数
}
return e.client.SendEmail(ctx, req)
}
3. 消息路由分发机制
go
// Router 消息路由器
type Router struct {
// 渠道管理器
channelManager *ChannelManager
// 路由规则
rules []RoutingRule
}
// Route 路由消息
func (r *Router) Route(ctx context.Context, req *SendRequest) error {
// 根据接收者类型和业务规则选择合适的渠道
for _, receiver := range req.Receivers {
channel := r.selectChannel(receiver, req.Type)
if channel == nil {
return fmt.Errorf("no suitable channel found for receiver: %v", receiver)
}
// 构造消息
msg := &Message{
To: receiver.Contact,
Content: req.Content.Body,
// ... 其他字段
}
// 异步发送消息
go func() {
if err := channel.Send(ctx, msg); err != nil {
// 记录错误日志
log.Printf("send message failed: %v", err)
// 可以加入重试机制
}
}()
}
return nil
}
// selectChannel 根据规则选择渠道
func (r *Router) selectChannel(receiver Receiver, notifyType NotificationType) Channel {
// 根据接收者类型、通知类型和路由规则选择渠道
for _, rule := range r.rules {
if rule.Match(receiver, notifyType) {
return r.channelManager.GetChannel(rule.Channel)
}
}
// 返回默认渠道
return r.channelManager.GetDefaultChannel()
}
总结
通过上述架构设计和核心功能实现,我们构建了一个高可用、高扩展性的通知平台,有效解决了多业务方接入、多渠道支持、高并发处理等核心痛点。在后续章节中,我们将深入探讨各个组件的具体实现细节和优化方案。
这种设计的优势在于:
- 高内聚低耦合:各组件职责清晰,便于维护和扩展
- 易于扩展:新增渠道只需实现Channel接口
- 灵活路由:支持基于业务规则的动态路由
- 异步处理:提高系统响应速度和吞吐量
在下一节中,我们将详细介绍多渠道消息适配的具体实现方案。