最近在学习服务架构和服务器编程,随着学习的进展,给我带来了一些问题,其中QQ服务器是如何实现的让我困惑了一段时间,最近略有感悟,写下来分享一下,以方便大家的交流和学习。
因为以前做过游戏开发对游戏服务器的架构和实现有一定的了解,一组游戏服务器如果能承受2000人同时在线已经算不错了,而且每组服务器和每组服务器是独立的,就是说每个玩家只能和本服务器的玩家进行交流和互动,和其他服务不实现通信,然而QQ好象能做到只要安装客户端的用户,可以查找到任何QQ用户并进行聊天,发送文件,音频,视频等。
经过一些资料的查找和分析,了解的QQ是有p2p通信来实现的,这样不经过服务器的中转,减轻了服务器的负担,其中有一锻文章是这么写的,我抄出其中的一部分,其他的在打开这个连接就能看到全文(http://bbs.51cto.com/thread-591907-1.html):
“A要向B发送一个文件,于是发出一个文件传送请求。服务器收到这个文件传送请求后,转发给B,同时或者在B应答后,将A的IP地址同时发送给B。B这个时候就得到了A的真实IP。这里的IP是你的本机IP。也就是说,如果A处在内网,B得到的地址就是一个内网地址。B得到了A的地址之后,就会尝试去连接A。如果B也处于内网,那么,显然A跟B之间的连接是无法建立的。这个时候,客户端就会请求服务器进行文件中转。因为服务器具有公网 IP,处在内网的A跟B都是可以连接到服务器的,于是,A跟B的文件传送就通过服务器中转的方式,顺利进行”
在这篇文章中写到,“客户端就会请求服务器进行文件中转。因为服务器具有公网 IP,处在内网的A跟B都是可以连接到服务器的,于是,A跟B的文件传送就通过服务器中转的方式,顺利进行”如果是这样的话,那么我们就有一个前提,即A和B连接在同一台服务器上,如果A和B不在同一台服务怎么办呢。估计只能用UDP通信了,能进行UDP通信,进行打洞就可以了,为什么还要服务器中转。
所以我认为应该是这样的,假设A,B是两个客户端, C, D是两台服务器,为了避免混淆,后面就用A客,B客, C服, D服来代表,A客---连接---C服, B客---连接---D服, A和C之间是用TCP建立的连接,B和D之间也是有TCP建立的连接,A和B是在不同的内网上,如果A和B之间要建立ptp连接如何建立?那么A和B之间必须进行NAT打洞,这就要求C服和B客通信,D服和A客通信, 如果C服要给B发信息,因为C和B之间没有TCP面向连接的通信,所以他们只能用UDP通信, 因为C和D是有公网ip的,所以C和B的通过UDP是肯定可以通信,这样A告诉C它要连接B,C通过数据库找的B的地址,和B通信,告诉B A的地址,同样A用同样的方式也可以获得B的地址,这样即可以实现A和B的打洞,又能实现上线通知,而且和连接那台服务器没关系,每次有新用户登陆是,进行负载均衡,和比较空闲的服务器连接就可以了,每组服务器配置相同,只需要增加服务器就能满足不断增长的用户需求。