Netty完胜Java I/O与NIO?

前言

在面对不少当前的互联网应用程序时,其核心底层功能大多须要高性能网络编程来支撑,而对于Java来讲是幸运的,由于在这个领域已经有了一个正在不断健壮的框架,他就是Netty(一款异步的事件驱动的网络应用程序框架,支持快速地开发可维护的高性能的面向协议的服务器和客户端)。java

那么这个框架入手容易吗?git

实际上是有必定难度的,即便是一些例子(具有高性能的系统),想要了解并熟知,不只须要一流的编程技巧,还须要几个复杂领域(网络编程、多线程处理和并发)的专业知识。github

可是Netty确实提供了极为丰富的网络编程工具集,值得咱们花大量时间来消化它。编程

其终究是框架

Netty的架构方法和设计原则是:每一个小点都和它的技术性内容同样重要,无比精妙。咱们能够更关注如下几点:安全

关注点分离——业务和网络逻辑解耦
模块化和可复用性
可测试性做为首要的要求

了解Java I/O与NIO

代码示例 阻塞I/O
ServerSocket serversocket = new ServerSocket(portNumber);
Socket clientSocket = serverSocket.accept();
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
String request, response;
while((request = in.readLine()) != null){
    if("Done".equals(request)){
        break;
    }
    response = processRequest(request);
    out.println(response);
}

恰如以上代码就实现了Socket API的基本模式之一。或许你应该注意到如下几点:服务器

  • ServerSocket上的accept()方法将会一直阻塞到一个链接创建,随后返回一个新的Socket用于客户端和服务器之间的通讯。该ServerSocket将继续监听传入的链接。
  • BufferedReader和PrintWriter都衍生自Socket的输入输出流,前者从一个字符输入流中读取文本,后者打印对象的格式化的表示到文本输出流。
  • readLine()方法将会阻塞,直到有一个换行符或者回车符结尾的字符串被读取到。
  • processRequest()方法即服务端对客户端的请求进行处理。
这段代码是否存在弊端?
  • 其只能同时处理一个链接,要管理多个并发客户端,须要为每一个新的客户端Socket建立一个新的Thread。(以下图所示)

图片描述

那么你或许能够考虑到如下几点影响?
  • 一、在任什么时候候均可能有大量的线程处于休眠状态,只是等待输入或者输出数据就绪,这可能算是一种资源浪费。
  • 二、为每一个线程的调用栈分配内存,根据操做系统默认值区间通常为64KB到1MB。
  • 三、即便Java虚拟机(JVM)在物理上能够支持很是大数量的线程,可是远在到达该极限以前,上下文切换所带来的开销就已经很是麻烦了。
结论是?

虽然以上对于支撑中小数量的客户端来讲还算能够接受,可是在面对100 000或更多并发链接资源使用它是很不理想的。网络

很幸运,你还可使用NIO这种方式!(2002年Java引入对于非阻塞I/O的支持)
  • 使用setsocket()方法配置套接字,以便读/写调用在没有数据的时候当即返回
  • 使用操做系统的事件通知API注册一组非阻塞套接字,以肯定它们中是否有任何的套接字已经有数据可供读写。
  • 以上两点就字面理解可能比较困难,那么你能够抽象记忆如下的观点与流程图!
使用Selector的非阻塞I/O

图片描述

  • 上图是一种非阻塞设计,Java.nio.channels.Selector是Java的非阻塞I/O实现的关键。
  • 它使用了事件通知API以肯定在一组非阻塞套接字中有哪些已经就绪可以进行I/O相关的操做。
  • 一个单一的线程即可以处理多个并发的链接。
相比之下,与阻塞I/O相比,它能更好的利用资源
  • 使用较少的线程即可以处理许多链接,减小了内存管理和上下文切换带来的开销
  • 当没有I/O操做须要处理的时候,线程也能够被用于其余任务。

Netty的出场!!!

尽管你能够直接使用这些API进行直接构建应用程序(在高负载下可靠和高效的处理和调度I/O操做),可是要作到彻底正确与安全是很难处理,那么这是咱们将工做留给高性能的网络编程专家Netty或许更合适。多线程

相关项目 By GitHub

项目名:InChat
项目地址:https://github.com/UncleCatMy...
项目介绍:基于Netty4与SpringBoot,聊天室WebSocket(文字图片)加API调用Netty长连接执行发送消息(在线数、用户列表)、Iot物联网-MQTT协议、TCP/IP协议单片机通讯,异步存储聊天数据架构


若是本文对你有所帮助,欢迎关注我的技术公众号并发

图片描述

相关文章
相关标签/搜索