1.背景
公司在做一个社交项目,音视频技术是使用的第三方技术,直播间开播,进出房间,以及推送相关功能需要自己完成开发,因而需要自己搭建长连接服务器。于是在技术选型上,为了保证服务高并发性能,以及长连接性能,在本身就是微服务架构上,采用了SpringBoot + Netty实现了长连接服务搭建,关于SpringBoot和Netty框架相关,本文不是重点,本文重点在于Netty集群搭建实现消息转发功能。
2.技术选项&实现
2.1 关于Netty长连接
Netty是一个非常优秀的NIO异步事件驱动框架,在JDK NIO的基础上,封装并拓展包装,使得NIO的API简单易用,很多框架底层也应用了(比如Dubbo),官网入口:Netty,Netty是可以做为一个长连接服务的,使用ws协议,可以构建一个高性能的长连接服务器,据说单机就能支持1万左右的连接。
熟悉Netty或NIO的都了解,其底层数据传输时通过一个网络连接Channel,对于单机Netty来说,Channel都连接在同一台服务器上,Channel之间的通信可以直接根据绑定的用户信息进行获取并转发。但是对于Netty集群来说,每个客户端的连接可能在不同的服务器上,这样在Channel互相通信时,需要判断是否在当前节点,并实现消息的转发。
2.2 技术选项
实现消息转发,有多种技术框架可以实现,比如ZK,MQ,Redis等,由于当前项目已经搭建了自己的MQ和Redis服务,因此考虑成本,目前只在MQ和Redis中选择。
如上文,Netty集群搭建后,Channel收到消息后,需要判断目标用户的Channel是否在本节点,如果不在,就需要做消息转发,转发到目标节点上,并将消息写到Channel中。因而MQ的广播机制和Redis的发布订阅就可以实现功能。
对比如下:
MQ:专门做消息队列的,可靠性高,但重量级,异步,不能保证实时。
Redis:较轻量级,低延迟,高并发,低可靠性。
两者在项目均在使用,考虑到直播消息更加保证时效性,故而选择Redis发布订阅功能,相对而言集成较为简单。
2.3 实现架构图
①服务启动时,向Redis注册自己的节点信息,并指定监听频道。
②客户端连接Netty Server成功后,并在Redis缓存中绑定用户加入的节点,以便后续信息转发,将信息转发到指定的频道。
③在Channel转发时,判断如果当前用户在本节点,就直接转发,如果不在,从Redis获取到注册的节点信息,并将消息发布到指定的频道节点。
3.代码实现
绑定当前节点,服务启动并监听指定的频道,指定Listener。
订阅节点生成器 本机 ip + 服务端口
监听器实现,监听的频道收到消息,处理并发送到对应Channel
消息转发Sender
4.总结
①通过应用Redis发布订阅,Netty Server多个集群,追加多节点时,新增节点会自动注册监听对于的频道,消息转发时也会自动投递到新注册的节点频道上,可扩展性强。
②当前Redis 5中有很多新增的高级特性,笔者也在慢慢学习中,可应用到项目业务场景中也比较多。
任它岁月流逝,前方也定会海阔天空!