下面是我和一网友在邮件组的一组对话,就是关于“是否客户端和服务端创建并保持一个长连接,在服务端就会相应的创建一个线程”的问题:
我们的意见如下:
A:当连接较少时,一个连接一个线程是可以接受的。但,网游的接入服务器连接都几千个,一个连接一个线程肯定不行。
Me:我觉得服务器端被客户端一个连接然后开一个线程是很合理的。否则,怎么实现啊
A:不是吧, 那要建多少个线程啊, 现在一般不都是完成端口模型吗, 多个连接共享一个线程。
me:太多 Thread 不合理的, 请求处理 Thread 和 数据处理 Thread 各一个.用数据队列和信号之类同步.
每个 client 一个Thread 不太好.除非用户量小.
A:如果一个长连接就一个线程 5000个线程 那不是电脑都挂了!
Me:
不会产生这种情况的,举个很简单的case,QQ游戏大厅玩过的吧,前面的Login server,大厅server,都是短连接,那就不说了,和房
间服务器保持长连接,看看每台房间服务器的上限人数:500,也就是说最多,最终和一台room server保持长连接的上限也就500,我觉得一个长连接开一个线程还是可以满足这种需求的。
A:每个server只负责一个room?这个结论从哪来的
Me:这不是结论,你完全可以这样设置,不过一台server有时候会有多个room,而这些room都是在不同的进程中,比如3个,4个,还是完全可以承受
A是对方,Me是我,我知道在windows下用iocp,在linux下使用epoll比起我目前的方式要好的多,但是我不知道Java中相应的有没有IOCP完成端口,epoll的模型,NIO是否和这两种方式有关?觉得目前我的这种实现方式也是满足需求的,下面是引自一篇文章上的话题,大家可以参考:
大多数的网络游戏的服务器都会选择非阻塞select这种结构,为什么呢?因为网络游戏的服务器需要处理的连接非常之多,并且大部分会选择在Linux/Unix下运行,那么为每个用户开一个线程实际上是很不划算的,一方面因为在Linux/Unix下的线程是用进程这么一个概念模拟出来的,比较消耗系统资源,另外除了I/O之外,每个线程基本上没有什么多余的需要并行的任务,而且网络游戏是互交性非常强的,所以线程间的同步会成为很麻烦的问题。由此一来,对于这种含有大量网络连接的单线程服务器,用阻塞显然是不现实的。诚心请教,期待回复!谢谢!分数只有100分左右了,全都拿出来了,顺便弱弱的问一句:分数散光了哪里去赚快一点?哈哈
我们的意见如下:
A:当连接较少时,一个连接一个线程是可以接受的。但,网游的接入服务器连接都几千个,一个连接一个线程肯定不行。
Me:我觉得服务器端被客户端一个连接然后开一个线程是很合理的。否则,怎么实现啊
A:不是吧, 那要建多少个线程啊, 现在一般不都是完成端口模型吗, 多个连接共享一个线程。
me:太多 Thread 不合理的, 请求处理 Thread 和 数据处理 Thread 各一个.用数据队列和信号之类同步.
每个 client 一个Thread 不太好.除非用户量小.
A:如果一个长连接就一个线程 5000个线程 那不是电脑都挂了!
Me:
不会产生这种情况的,举个很简单的case,QQ游戏大厅玩过的吧,前面的Login server,大厅server,都是短连接,那就不说了,和房
间服务器保持长连接,看看每台房间服务器的上限人数:500,也就是说最多,最终和一台room server保持长连接的上限也就500,我觉得一个长连接开一个线程还是可以满足这种需求的。
A:每个server只负责一个room?这个结论从哪来的
Me:这不是结论,你完全可以这样设置,不过一台server有时候会有多个room,而这些room都是在不同的进程中,比如3个,4个,还是完全可以承受
A是对方,Me是我,我知道在windows下用iocp,在linux下使用epoll比起我目前的方式要好的多,但是我不知道Java中相应的有没有IOCP完成端口,epoll的模型,NIO是否和这两种方式有关?觉得目前我的这种实现方式也是满足需求的,下面是引自一篇文章上的话题,大家可以参考:
大多数的网络游戏的服务器都会选择非阻塞select这种结构,为什么呢?因为网络游戏的服务器需要处理的连接非常之多,并且大部分会选择在Linux/Unix下运行,那么为每个用户开一个线程实际上是很不划算的,一方面因为在Linux/Unix下的线程是用进程这么一个概念模拟出来的,比较消耗系统资源,另外除了I/O之外,每个线程基本上没有什么多余的需要并行的任务,而且网络游戏是互交性非常强的,所以线程间的同步会成为很麻烦的问题。由此一来,对于这种含有大量网络连接的单线程服务器,用阻塞显然是不现实的。诚心请教,期待回复!谢谢!分数只有100分左右了,全都拿出来了,顺便弱弱的问一句:分数散光了哪里去赚快一点?哈哈
1.线程没有得到充分的利用。
A。按时间配比来讲,线程阻塞时长所占的比例要绝对大于处理数据的时长。
B。系统会为每个线程分配内存资源(LZ也说了在Linux/Unix下的线程是用进程这么一个概念模拟出来的,比较消耗系统资源)
2.线程数量超过某一数值时,会对系统的整体性能造成影响。(个人觉得这个峰值和服务器内存容量有关)
3.如果用阻塞方式来处理的话,对线程的可控性就不太好设计了。(比如,看哪个客户端连接不顺眼,要断开连接)
一条线程维护多个连接,具体使用哪些类,我还没有使用过。但是,推荐采用线程池技术来提高处理效率。
Java中类似IOCP,epoll的模型具体位置应该在java.nio.channels包下面,
着重查看Selector、SelectableChannel、SelectionKey、ServerSocketChannel和SocketChannel这几个类。
我想还是服务器端做线程池比较合理,可以服务更多的客户请求。不过对于长连接个人觉得,为了改善客户的感受,值得。一个用户一个线程,设计简单,实用,我认为比较好。