以一个典型的用户咨询场景为例,当用户打开 App 或者网页时,会通过连接层建立长连接,之后在咨询入口发起咨询时,会携带着消息线索初始化消息链路,建立一条可复用、可检索的消息线;发送消息时,通过消息服务将消息存储到 DB 中,同时会根据消息线检索当前咨询是否被分配到客服,调用分配服务的目的是为当前咨询完善客服信息;最后将客服信息更新到链路关系中。
在这期间,公司其它业务线对 IM 服务的使用需求也越来越多,使用频次和量级也开始加大。初期阶段的 IM 服务当连接量大时,只能通过修改代码实现水平扩容;新业务接入时,还需要在业务服务器上配置 Openresty 环境及 Lua 协程代码,业务接入非常不便,IM 服务的通用性也很差。
考虑到以上问题,我们对 IM 服务进行了全面重构,目标是将 IM 服务抽取成独立的模块,不依赖其它业务,对外提供统一的集成和调用方式。考虑到 IM 服务对并发处理高和损耗低的要求,选择了 Go 语言来开发此模块(关于Go语言的详细实践总结,请详读《从游击队到正规军(三):基于Go的马蜂窝旅游网分布式IM系统技术实践》一文)。