1. IM系统中好友管理子服务的核心价值
即时通讯(IM)系统中的好友管理模块,就像现实生活中的通讯录升级版。它不仅需要处理基础的增删改查,还要应对复杂的社交关系链、状态同步、权限控制等场景。在主流IM架构中,这个模块通常会独立为微服务,我们团队在最近的项目中就重构了这样一个子系统。
不同于简单的联系人列表,现代IM的好友管理需要处理这些典型场景:
- 双向好友关系的建立与解除(类似微信)
- 单向关注机制(类似微博)
- 黑名单与静默限制
- 好友分组与标签系统
- 在线状态订阅与通知
- 资料变更的实时同步
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 技术架构设计要点
2.1 服务边界划分
好友服务需要明确与这些模块的交互:
code复制用户服务 → 获取基础资料
消息服务 → 关系变更通知
推送服务 → 状态更新推送
我们采用Protobuf定义接口契约,关键API包括:
protobuf复制service FriendService {
rpc ApplyFriend (FriendApplyRequest) returns (FriendApplyResponse);
rpc DeleteFriend (FriendDeleteRequest) returns (FriendDeleteResponse);
rpc GetFriendList (FriendListRequest) returns (stream FriendProfile);
}
2.2 存储方案选型
关系型数据库(MySQL)存储核心关系:
sql复制CREATE TABLE user_relationships (
id BIGINT PRIMARY KEY,
user_id BIGINT,
friend_id BIGINT,
relation_type TINYINT, -- 1:好友 2:关注 3:黑名单
group_id INT,
remark VARCHAR(64),
created_at TIMESTAMP
) ENGINE=InnoDB;
Redis缓存热点数据:
- 用户好友列表缓存(ZSET结构)
- 在线状态订阅列表(PUB/SUB)
- 申请审批队列(Stream)
3. 核心业务流程实现
3.1 好友申请审批流程
典型时序:
- 客户端提交申请(含验证信息)
- 服务端写入申请记录
- 通过WS通知对方
- 审批通过后:
- 双向建立关系记录
- 生成系统消息
- 更新双方缓存
关键代码片段(Go实现):
go复制func (s *Service) HandleApply(ctx context.Context, req *pb.ApplyRequest) error {
// 防重复申请检查
if exists, _ := s.dao.CheckApplyExists(req.From, req.To); exists {
return errors.New("apply already exists")
}
// 写入申请记录
apply := &model.FriendApply{
From: req.From,
To: req.To,
Message: req.Message,
Status: model.ApplyStatusPending,
}
if err := s.dao.CreateApply(apply); err != nil {
return err
}
// 实时通知
return s.notifier.NotifyFriendApply(ctx, req.To, req.From)
}
3.2 状态同步机制
采用分级推送策略:
- 在线用户:WebSocket直推
- 离线用户:APNs/厂商通道
- 跨设备同步:通过SyncSeq机制
4. 性能优化实践
4.1 缓存策略
采用多级缓存架构:
- 本地缓存(Caffeine):TTL 30秒
- Redis集群:TTL 5分钟
- 异步预热:关系变更后主动刷新
缓存键设计示例:
code复制user:123:friends → 完整好友列表
user:123:friend:456 → 单条关系详情
4.2 批量接口设计
针对移动端优化的批量查询接口:
json复制POST /v1/friends/batch
{
"user_ids": [123,456,789],
"fields": ["nickname","avatar","online_status"]
}
5. 踩坑记录与解决方案
5.1 分布式事务问题
在关系建立时遇到:
- MySQL记录成功
- Redis缓存更新失败
- 导致数据不一致
最终方案:
- 引入本地消息表
- 定时任务补偿
- 客户端重试机制
5.2 海量关系列表加载
当用户好友数超过5000时:
- 首次加载超时
- 内存占用过高
优化手段:
- 分片加载(每次500条)
- 增量同步(通过version控制)
- 客户端本地持久化
6. 监控与治理
关键监控指标:
- 关系变更QPS
- 审批平均耗时
- 缓存命中率
- 消息投递成功率
我们采用的监控方案:
code复制Prometheus → 基础指标收集
Grafana → 可视化看板
ELK → 业务日志分析
在实施灰度发布时,通过Feature Flag控制新老逻辑切换:
go复制if features.Enabled("new_friend_logic") {
return newApplyFlow(ctx, req)
} else {
return legacyApplyFlow(ctx, req)
}
这个子系统经过三个迭代周期的优化,目前支持:
- 日均1000万+关系变更
- 99.99%的请求响应<50ms
- 支持3000+TPS的峰值流量
实际开发中发现,好友管理这类基础服务,稳定性往往比功能丰富度更重要。我们在v2版本砍掉了几个花哨的社交功能,转而强化了核心链路的事务一致性保障,这个决策让系统可用性提升了两个数量级。
