Netty学习笔记
1.Netty简介
1.1Netty是什么?
- Netty是JBOSS的Java开源框架。(1.github地址2.官网地址)
- Netty是基于异步的,事件驱动的网络框架,可以快速开发高性能,高可靠性的网络IO程序。
- Netty适用于高并发,大数据传输场景。
- Netty是一个NIO框架。
1.2 Netty应用场景
- 互联网行业,用于分布式项目的RPC,如:Dubbo
- 游戏行业
- 大数据领域
2.IO模型
- IO模型通俗理解:采取什么通道进行数据的接收和发送。Java支持三种IO模式:BIO,NIO,AIO
(1) BIO
- 概念: BIO即Blocking IO,同步阻塞IO
- 服务器实现模式:一个线程处理一个连接
- 优点:开发简单,代码易于理解
- 缺点:①连接空闲时,造成资源浪费 ②高并发场景下,服务压力大,对硬件资源要求高
- 适用场景:连接数目小而且固定的架构
(2) NIO
- 概念:NIO即non-blocking io, 同步非阻塞IO
- 服务实现模式:通过多路复用器轮询,一个线程可以处理多个连接
- 优点:①一个线程可以处理多个连接 ②轮询提高IO吞吐性能
- 缺点:开发复杂,代码不好理解
- 适用场景:连接数多而且连接比较短的场景
(3) AIO
- 异步非阻塞,AIO 引入异步通道的概念,采用了 Proactor 模式,简化了程序编写,有效的请求才启动线程,它的特点是先由操作系统完成后才通知服务端程序启动线程去处理,一般适用于连接数较多且连接时间较长的应用
3.BIO
3.1 Java BIO基本介绍
- Java BIO就是传统的Java IO编程,相关类和接口都在java.io包中
- BIO(Blocking IO) 同步阻塞,一个请求需要开启一个线程处理,如果改连接空闲,也会一直阻塞,浪费资源。
- BIO适用于并发数小而且固定的架构。
3.2 BIO 程序案例
- BIO开发流程:
- 创建服务端程序ServerSocket。
- 创建客户端程序Socket,去连接服务器,服务器默认情况下都会开启一个线程处理请求。
- 客户端发出请求之后,先看服务端是否有线程响应,否则,等待,连接拒绝。
- 如果有响应,客户端等待服务端执完毕返回。
/**
* 一个线程处理一个请求
* BIO服务端
*/
public class BIOServer {
public static void main(String[] args) throws IOException {
//启动一个ServerSocket,监听8888
ServerSocket serverSocket = new ServerSocket(8888);
System.out.println("开启了一个服务器端程序,端口8888......");
//每个请求都用一个线程来处理
ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();
System.out.println("开启了线程池,管理连接请求......");
while (true) {
//等待客户端连接
System.out.println("等待连接......");
Socket socket = serverSocket.accept();
//开启线程处理请求
newCachedThreadPool.execute(() -> {
System.out.println("开启线程...." + Thread.currentThread().getName());
msgHandler(socket);
});
}
}
/**
* 请求处理方法
*
* @param socket
*/
private static void msgHandler(Socket socket) {
try {
//获取输入流
InputStream inputStream = socket.getInputStream();
//处理乱码
Reader reader = new InputStreamReader(inputStream, "GBK");
char[] cbuf = new char[1024];
int len = -1;
while ((len = reader.read(cbuf)) != -1) {
String msg = new String(cbuf, 0, len);
System.out.println(msg);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
1.运行程序。
2.开启cmd,输入telnet 127.0.0.1 8888
3.输入ctrl+]
4.使用 send xxxx,发送消息
运行结果:
3.3Java BIO问题分析
- 每个请求需要创建独立的线程来处理连接,与对应的客户端进行数据的read,业务处理和write。
- 当并发数大时,需要创建大量的线程来处理请求,占用服务器资源
- 连接创建后,当前线程没有数据读,程序会阻塞在read上,造成资源的浪费