- 石家庄变频柜
-
跟着源码学IM(十):基于Netty搭建高性能IM集群(含技术思路+源码
时间:2022-01-20 19:51 作者:admin 来源:未知 查看:内容摘要:原标题:跟着源码学IM(十):基于Netty,搭建高性能IM集群(含技术思路+源码) 相信很多朋友对微信、QQ等聊天软件的实现原理都非常感兴趣,笔者同样对这些软件有着深厚的兴趣。而且笔者在公司也是做IM的,公司的IM每天承载着上亿条消息的发送! 正好有这样的...原标题:跟着源码学IM(十):基于Netty,搭建高性能IM集群(含技术思路+源码)
相信很多朋友对微信、QQ等聊天软件的实现原理都非常感兴趣,笔者同样对这些软件有着深厚的兴趣。而且笔者在公司也是做IM的,公司的IM每天承载着上亿条消息的发送!
正好有这样的技术资源和条件,所以前段时间,笔者利用业余时间,基于Netty开发了一套基本功能比较完善的IM系统。该系统支持私聊、群聊、会话管理、心跳检测,支持服务注册、负载均衡,支持任意节点水平扩容。
这段时间,网上的一些读者,也希望笔者分享一些Netty或者IM相关的知识,所以今天笔者把开发的这套IM系统分享给大家。
本文将根据笔者这次的业余技术实践,为你讲述如何基于Netty+Zk+Redis来搭建一套高性能IM集群,包括本次实现IM集群的技术原理和实例代码,希望能带给你启发。
* 重要提示:本文不是一篇即时通讯理论文章,文章内容来自代码实战,如果你对即时通讯(IM)技术理论了解的太少,建议先详细阅读:《新手入门一篇就够:从零开发移动端IM》。
Netty 是一个 Java 开源框架。Netty 提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客户端程序。
也就是说,Netty 是一个基于 NIO 的客户、服务器端编程框架,使用Netty 可以确保你快速和简单的开发出一个网络应用,例如实现了某种协议的客户,服务端应用。
Netty 相当简化和流线化了网络应用的编程开发过程,例如,TCP 和 UDP 的 Socket 服务开发。
Netty源码和API的在线.x 完整源码(在线.x API文档(在线、系统架构
ZK作为服务注册中心,Redis用来做分布式会话的缓存,并保存用户信息和轻量级的消息队列。
对于整个系统架构中各部分的工作原理,我们将在接下来的各章节中一一介绍。
在上述架构中:NettyServer启动,每启动一台Server节点,都会把自身的节点信息,如:ip、port等信息注册到ZK上(临时节点)。
正如上节架构图上启动了两台NettyServer,所以ZK上会保存两个Server的信息。
无论是IM系统,还是分布式的RPC框架,高效的网络数据传输,无疑会极大的提升系统的性能。
在Java领域,Java序列化对象的方式有严重的性能问题,业界常用谷歌的protobuf来实现序列化反序列化(见《Protobuf通信协议详解:代码演示、详细原理介绍等》)。
《一套海量在线用户的移动端IM架构设计实践分享(含详细图文)》一文中,“
3)to_uid:消息接收者的uid;4)format:消息格式,我们使用各种聊天软件时,会发送文字消息,语音消息,图片消息等等等等,每种消息有不同的消息格式,我们用format来表示(由于本系统是java终端,format字段没有太大含义,可有可无);
假设一个群有100人,如果Client1给一个群的所有人发消息,其实相当于Client1分别给其余99人分别发一条消息。我们可以直接在Client端,通过循环,分别给群里的99人发消息即可,相当于Client发送给NettyServer发送了99次相同的消息(除了to_uid不同)。
Client1通过循环99次,分别把消息发给NettyServer,NettyServer收到这99条消息后,分别将消息发给群内其余的用户。先抛开移动端的特殊性(比如循环还没完成手机就有可能退到后台被系统挂起),显然Client1到NettyServer的99次循环存在明显不合理地方。
方式二:上节的消息体中to_uid_list字段就是为了解决这个方式一的性能问题的。Client1把群内其余99个Client的uid保存在to_uid_list中,然后NettyServer只发一条消息,NettyServer收到这一条消息后,通过to_uid_list字段解析群内其余99的Client的uid,再通过循环把消息分别发送给群内其余的Client。
可以看到:方式二的群聊时,Client1与NettyServer只进行1次消息传输,相比于方式一,效率提高了50%。
针对本文中的架构,如果多个Client分别连接在不同的Server上,Client之间应该如何通信呢?
那么:NettyServer1的消息如何转发给NettyServer2呢?答案是通过消息队列,如Redis中的list数据结构。每台NettyServer启动后都需要监听一个自己的Redis中的消息队列,这个队列用户接收其他NettyServer转发给当前NettyServer的消息。
* Jack Jiang点评:上述集群方案中,Redis既作为在线用户列表存储中心,又作为集群中不同IM长连接实例的消息中转服务(此时的Redis作用相当于MQ),那Redis不就成为了整个分布式集群的单点瓶颈了吗?
如果Client与NettyServer,由于某种原因(客户端退出、服务端重启、网络因素等)断开链接,我们必须要从SessionMap删除会话和Redis中保留的数据。
当Client与NettyServer建立链接后,由于双端网络较差,Client与NettyServer断开链接后,如果NettyServer没有感知到,也就没有清除SessionMap和Redis中的数据,这将会造成严重的问题(对于服务端来说,这个Client的会话实际处于“假死”状态,消息是无法实时发送过去的)。
我们需要遍历SessionMap找出所有的uid,然后一一清除Redis的数据,然后优雅退出。此时,我们就需要为我们的NettyServer添加一个Hook,来做数据清理。
Client1给对方发消息,我们通过SessionMap或Redis拿不到对方的会话数据,这就表明对方不在线。
好了,这就是我开发的这个简易的聊天系统,麻雀虽小,五脏俱全,大家有什么不明白的地方,可以直接在下方留言,笔者会一一回复的,谢谢大家。
《跟着源码学IM(一):手把手教你用Netty实现心跳机制、断线重连机制》
《跟着源码学IM(四):拿起键盘就是干,教你徒手开发一套分布式IM系统》
《跟着源码学IM(五):正确理解IM长连接、心跳及重连机制,并动手实现》
《跟着源码学IM(六):手把手教你用Go快速搭建高性能、可扩展的IM系统》
《跟着源码学IM(七):手把手教你用WebSocket打造Web端IM聊天》
《跟着源码学IM(八):万字长文,手把手教你用Netty打造IM聊天》
《跟着源码学IM(十):基于Netty,搭建高性能IM集群(含技术思路+源码)》(* 本文)
声明:该文观点仅代表作者本人,搜狐号系信息发布平台,搜狐仅提供信息存储空间服务。[视频格式转换器哪个好 好用]!
- 最近更新
-
- 01-21矢量绘图软件CorelDRAW X4春季促销
- 01-20海南未来产业园新引进6家企业
- 01-20中国大洋协会多金属结核勘探合同网
- 01-20南昌大事连连啊关乎你我!第一项就
- 01-20昆明乡村太阳能路灯厂商
- 01-20司法纠纷再升级 欧盟向波兰开出700
- 01-20首届江西科技创新产品直播节在南昌
- 01-202020年度广东省科学技术奖正式颁发
- 01-20从“驾校一点通”的体验谈工具类产
- 01-20淘气堡的价格
- 本类推荐
-
- 11-28CorelDRAW X4:全新创作体验和商业
- 11-242020是零工经济爆发元年薪宝科技在
- 01-17广东阳江:税惠“添薪”赋能制造企
- 12-11温氏集团:欺诈需严惩发挥企业责任
- 12-06浅谈电子课本与电子书包市场
- 12-12方便啦!无人智能生鲜柜首现石家庄
- 12-072022年度威海市各级机关招录公务员
- 12-02石家庄设900余台智能自提柜 解决快
- 12-01军改一周年军报发表评论《走好改革
- 11-21方便!无人智能生鲜柜首现石家庄一
- 本类排行
-
- 11-26成都10月会计从业资格证书考试成绩
- 01-15新疆在京召开涉疆问题新闻发布会
- 12-02中国海洋大学经济学院金融硕士在第
- 12-08被代码温暖的世界
- 12-06电子书 - OFweek电子工程网
- 11-21格力高效直流变频离心机亮相石家庄
- 12-03美林基业集团入驻银麓绿建减碳平台
- 12-05科目一考试也要“助攻”?罚!
- 12-07会计从业资格证书编号查询入口
- 10-22安全触网:网警说(二)_新浪新闻