java.nio对Web服务器有什么好处?
我知道这是一个反复出现的问题,我读过像下面这样的文章
http://www.mailinator.com/tymaPaulMultithreaded.pdf说nio比io更好地扩展并不一定是真的.
但是我很难看到java nio在开发Web服务器时比传统的acceptor / worker线程架构更好地扩展吗?让我解释: 通常,Java Web服务器使用以下模式来处理连接: >一些受限线程仅限于ServerSocket的accept()方法中的核心块数: while (true) { socket = serverSocket.accept(); // handleRequest submits the socket to a queue handleRequest(socket); socket.close(); } >检索客户端套接字时,它将提交到非阻塞队列,然后由工作线程池中的工作线程处理.工作线程数取决于正在执行的操作的持续时间. 如何使用java.nio使这个架构更具可扩展性? 我的意思是我仍然需要工作线程来处理将执行阻塞操作的请求(访问数据库或文件系统,调用外部服务).如果后端操作不像node.js那样异步执行,我仍然需要工作线程来限制整体可扩展性与1或2个事件调度程序线程的关系. 解决方法
我真的很喜欢Paul Tyma关于这个问题的文章,它真的很深入.我在他的文章中看到两个要点:
>使用传统的阻塞IO可以获得更好的吞吐量(他测量过) 使用非阻塞NIO的主要原因是当您有多个同时的空闲请求时.原因是:使用NIO,您可以从同一个线程提供多个请求,这样做会更好. 好的,这是你可以随处阅读的内容.现在……为什么这样更好? 有两个主要原因,它们与每个线程带来的两种不同类型的开销有关: >当调度程序更改处理器正在执行的线程时,会出现“上下文切换”,这可能是一项昂贵的操作(即,线程在处理器中有一些状态 – 寄存器中的值,L1中加载的大量数据,L2,L3缓存等 – 当线程停止时必须“保存”某个地方,并在线程继续执行时“重新加载”;同样,当你丢失L1,L3缓存的内容时,你可能会得到吨数缓存未命中,可能是坏的(或不是,取决于工作量)) 因此,每个线程都带有一些更“浪费”的内存和可能“浪费”的处理器周期(以执行“上下文切换”). 现在,假设您有一个聊天服务器,客户端建立HTTP连接请求新消息,并且只有当有新消息发送到该客户端时,您的服务器才会回答它们(以便客户端立即接收新消息).假设您有10k这样的客户端.在传统的,阻塞的,每个连接的线程模型中,你有10k个线程.在Java中,线程堆栈大小(-Xss)的典型标准值是256kb.使用10k线程,您将自动使用大约2GB的内存!!!!!!!!更糟糕的是:即使聊天服务器上根本没有任何活动,也没有发送任何消息,客户端仍然会浪费那些2GB.添加大量的上下文切换,您会发现问题. 在这种情况下,你最好使用非阻塞NIO,其中较少的线程(最终只有1!)足以处理所有10k客户端,因此你将保存上下文切换(即cpu时间)和线程堆栈(即内存),即使以更复杂的代码为代价,这通常是使用非阻塞NIO的副作用. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- java – 设置SurfaceView的背景图像
- java – 构造函数PrintWriter(BufferedWriter)未定义
- Java String和hadoop的Text差异性比较
- JDK 、 JRE 、 JVM 关系
- java – 无法将JSF ViewScoped bean注入Validator作为Manag
- java – 使用iText在Web浏览器中显示PDF文件
- java – 在执行Html.fromHtml后更改TextViews中的html链接样
- java – 为什么类型提升优先于重载方法的varargs
- java – Hazelcast分区计数和线程并发
- java-为应用程序添加脚本安全性