#include<stdio.h>
多服务器的动态负载均衡
一个服务器连接数量跟端口好无关系!
跟线程有关系,跟机器配置和操作系统最大限度有关系
比如说WIN2K支持255个线程 在加个线程共享池就能支持到1K个 在加上集群 1k*n*0。8=
在加上地域布置,1亿都能搞定!!
QQ 只是连接服务器查找自己的信息和朋友的信息,再就是接受QQ的广告而已,直接P2P朋友
刚开始是把自己的登录IP、时间发给服务器,
并从服务器获取好友的IP列表(最近1天登录过的),
再刷新到历史记录(本地数据库)存的好友中的IP地址中
然后依据这些IP,用UDP一个接一个地点他们……看是否在线……
接到响应的就是在线,没有响应的就不在线;
然后每隔一断时间向服务器发送自己的IP地址(也可能每隔一段时间向好友们发送在线的UDP数据包P2P的),但不获取好友IP列表,(减轻服务器负载)在线好友的更新,通过好友上线时(或者定时)发送的UDP数据包判断。
如果对方在线,点对点聊天不经过服务器;
聊天时建立基于TCP连接的SOCKET……
或视频时建立UDP连接的SOCKET……
传文件时很可能是建立基于TCP连接的……
如果对方不在线,聊天记录存入服务器数据库,三层C/S模式。
我认为从编程和服务器的负载情况来看,上面的方法是最简单的,
所以QQ是基于TCP/IP协议的,
不过他肯定自己开发了一套类似FTP协议的聊天协议规则……
服务端接受请求时应该建立的应该是异步SOCKET……
我觉得QQ服务器维持2000万人同时在线没什么稀奇的,因为这个在线的概念不是我们想的那样2000万用户都登录到服务器了,正如前面的所讲,服务器只是维护一个QQ用户状态列表而已,这对于现在大型的服务器来说没什么难的。QQ客户端通过一定的时间间隔向服务器发送自己的状态(也有可能是服务器通过一定的时间间隔来查询他所维护的QQ列表里所有QQ客户端的在线状态),我们用QQ的时候可以发现,如果我们本地网络正常,而与服务器断开后,本地机器的QQ并没有马上显示离线,而是过一定的时间,可以得知,QQ不是时时刻刻“在线”的!
实际上QQ采用的是UDP协议,而不是TCP协议.
UDP是无连接的, 所以任务与服务器的通讯都是断开的,不存在什么连接问题, 这也是为什么你们有时候会看见"刚才的消息XXXX, 没有成功发送...", 这是因为在规定的时间内,发送的UDP数据包没有收到响应信息,登陆的时候,也是通过这种方式, 验证成功后,会返回一个成功的状态信息到客户端,并在服务器记录当前用户在线, 这就是为什么有的人机器宕掉了,没有向服务器发送退出的信息,所以别人看到该用户"在线", 直到服务器在规定的时间内没有收到客户端的响应信息,所以才清除用户状态.此时别的用户才能知道此用户已经下线了.
最重要的是QQ只负责维护用户列表而已,真正的通讯除了转发的都是P2P连接,除了第一次向服务器获取对方地址外就不会叨扰服务器了(当然,QQ会定期上服务器告知服务器自己还健在,顺便下载好友在线情况)
我的blog有一片文章
类似于QQ游戏百万人同时在线的服务器架构实现!
http://221.8.9.2/youyou/boblog/read.php?41
还有大型服务器设计的代码
一般windows采用IOCP + ThreadPool
linux采用异步 + non-Blocking + ThreadPool实现
当然按照socket的规定
最大只能支持2^32并发
也就是6w多一点
然而实际根本就不可能的
一般QQ是大概5000并发但台PC的实现,他们使用服务器集群
对于一个QQ游戏100w量,起码需要200台机器的集群
在网络通信模型方面,现在的技术都是比较成熟的了,在win下使用iocp,在linux下使用epoll。它们的使用方法,相对来说,还是比较有章可循的。
内存之于高性能,大致有以下两个方面需要特别注意:
1.尽可能地减少内存的动态申请和释放;
2.尽可能地减少内存数据的复制;
解决第1个问题,我们可以使用内存池;而解决第2个问题,就会牵涉到程序的架构设计了。
理想的情况是:
在数据接收方面,一个包,只要从网络模块接收下来后,直到它被上层逻辑使用完毕之后才会丢弃,而不应该在网络接收模块和上层逻辑模块之间增加任何的有关复制该包的行为和操作;
在数据发送方面,发送的时所用的缓冲区,不应该是即时申请的,而是从内存池中取的可用缓冲区,用完后再放回。
而我们看到,对于前者,也只有在架构方面作一些精巧布局才能达到目的。
转自:http://liouwei20051000285.blog.163.com/blog/static/2523674201141025422491/
http://blog.csdn.net/sodme/article/details/490905