« | August 2025 | » | 日 | 一 | 二 | 三 | 四 | 五 | 六 | | | | | | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | | | | | | | |
| 公告 |
戒除浮躁,读好书,交益友 |
Blog信息 |
blog名称:邢红瑞的blog 日志总数:523 评论数量:1142 留言数量:0 访问次数:9694425 建立时间:2004年12月20日 |

| |
[java语言]java服务器如何处理更多的连接 原创空间, 软件技术, 电脑与网络
邢红瑞 发表于 2006/4/24 13:55:37 |
在即时通信领域如何让服务器处理更多的连接,如何解决10K并发连接,当用户装上千兆网卡,是否发挥了网卡的威力,这都是程序员和设计者要解决的问题。最早网络使用阻塞IO,后来提出了异步IO,bsd实现了select函数,异步IO和非阻塞IO的区别,异步IO就是把IO提交给系统,让系统替你做,做完了再用某种方式通知你;非阻塞IO就是你要通过某种方式不定时地向系统询问你是否可以开始做某个IO,当可以开始后,还是要自己来完成IO。后来在Solaris 7系统上,Sun引入了/dev/poll设备。在使用 /dev/poll的时候,你首先要打开/dev/poll作为一个普通文件。然后构造pollfd结构,方式同普通的poll()函数调用一样。这些pollfd结构随后写入到打开的 /dev/poll 文件描述符。在打开句柄的生存周期内, /dev/poll会根据pollfd结构返回事件(注意,pollfd结构内的事件字段中的特定POLLREMOVE将从/dev/poll的列表中删除对应的fd)。通过调用特定的ioctl (DP_POLL) 和dvpoll,程序就可以从/dev/poll获得需要的信息。在使用dvpoll结构的情况下,发生的事件就可以被检测到了。后来linux的开发者将poll加入了linux kernel。在FreeBSD 4.1中推出后,FreeBSD的kqueue API设计为比其他对应函数提供更为广泛的事件通知能力。kqueue API提供了一套通用过滤器,可以模仿poll()语法(EVFILT_READ和EVFILT_WRITE)。不过,它还实现了文件系统变化(EVFILT_VNODE)、进程状态变更(EVFILT_PROC)和信号交付(EVFILT_SIGNAL)的有关通知。一般来说,使用select()支持的客户端最大连接数不够,重定义宏 FD_SETSIZE是不行的 ,FD_SETSIZE在内核中 默认值是2048,使用setrlimit加大file descriptor的上限也不行(两者区别,FD_SETSIZE的话,会影响到所有的进程,在系统配置文件里修改,但是如果在程序中使用setrlimit的话就只会影响到你当前的进程或进程树,FD_SETSIZE是定义你的fd_set结构的最大容量,也就是你可以一次 select多少个socket,setrlimit改每进程最大打开文件数)。 各个平台使用的方法不同,用 iocp (windows), kqueue(freebsd), 或是 epoll(linux)。对于用2.6内核的epoll,没有这个2048的限制,更能发挥服务器的性能。从e-donkey的主页上得知,他们采用的EPOLL模型跑在4G内存的LINUX上,支持的最大用户已经超过了280K,由此可见EPOLL的威力.对于java开发,jdk6,加入了对epool的支持,sun\nio\ch\EPollArrayWrapper.c文件JNIEXPORT void JNICALLJava_sun_nio_ch_EPollArrayWrapper_init(JNIEnv *env, jclass this) { epoll_create_func = (epoll_create_t) dlsym(RTLD_DEFAULT, "epoll_create"); epoll_ctl_func = (epoll_ctl_t) dlsym(RTLD_DEFAULT, "epoll_ctl"); epoll_wait_func = (epoll_wait_t) dlsym(RTLD_DEFAULT, "epoll_wait"); if ((epoll_create_func == NULL) || (epoll_ctl_func == NULL) || (epoll_wait_func == NULL)) { JNU_ThrowInternalError(env, "unable to get address of epoll functions, pre-2.6 kernel?"); }}jdk5不是默认使用epoll的,需要设置一下,-Djava.nio.channels.spi.SelectorProvider=sun.nio.ch.EPollSelectorProvider很不幸的是,windows的nio不是由IOCP写的,所以同样的网络程序,linux的性能要比windows好些.参考UNPv1 的第27章“客户-服务器程序其他设计方法”中Richard Stevens也给出了采用不同的服务器设计方法所带来的任务调度运算时间消耗。 |
|
|