一、简介

1. 课程背景

分布式系统的根基在于网络编程,而 Netty 是 Java 领域网络编程的王者。

2. 课程内容

二、NIO 基础

non Blocking IO 非阻塞 IO

1. 三大组件

1.1 Channel & Buffer

channel 有一点类似于 stream,它就是读写数据的双向通道,可以从 channel 将数据读入 buffer,也可以将 buffer 的数据写入 channel,而之前的 stream 要么是写入,要么是输出。

常见的 Channel 有:

buffer 则用来缓冲读写数据,常见的 buffer 有:

1.2 Selector

使用多线程技术

为每个连接分别开辟一个线程,分别去处理对应的 socket 连接

netty入门讲解(NettyJava领域网络编程的王者)(1)

:exclamation: 多线程缺点

使用线程池技术

使用线程池,让线程池中的线程去处理连接

netty入门讲解(NettyJava领域网络编程的王者)(2)

这种方式存在以下几个问题:

使用 Selector

selector 的作用就是配合一个线程来管理多个 channel(fileChannel 因为是阻塞式的,所以无法使用 selector),获取这些 channel 上发生的事件,这些 channel 工作在非阻塞模式下,当一个 channel 中没有执行任务时,可以去执行其他 channel 中的任务。适合连接数多,但流量较少的场景。

netty入门讲解(NettyJava领域网络编程的王者)(3)

若事件未就绪,调用 selector 的 select 方法会阻塞线程,直到 channel 发生了就绪事件。这些事件就绪后,select 方法就会返回这些事件交给 thread 来处理。

2.ByteBuffer

使用案例

有一普通文本文件 data.txt 内容为

1234567890abc

使用 FileChannel 来读取文件内容

@Slf4jpublicclassTestByteBuffer{publicstaticvoidmain(String[] args) {// FileChannel// 1.输入输出流 2.RandomAccessFiletry {FileChannel fileChannel = new FileInputStream("data.txt").getChannel;// 准备缓冲区ByteBuffer buf = ByteBuffer.allocate(10);// 从 Channel 中读取数据,向 Buffer 写入int len;while ((len = fileChannel.read(buf)) != -1) {log.info("读取到的字节:{}", len);buf.flip; // 切换至读模式log.debug("输出内容为:{}", new String(buf.array, 0, len));// while (buf.hasRemaining) { // 是否还剩余数据// byte b = buf.get;// log.debug("输出内容为:{}", (char) b);// }// 切换为写模式buf.clear;}} catch (IOException e) {e.printStackTrace;}}}

2.1 ByteBuffer 使用步骤

  1. 向 buffer 写入数据,e.g. 调用 channel.read(buf)

  2. 调用 flip切换至读模式

  3. 向 buffer 读取数据,e.g. 调用 buf.get

  4. 调用 clearcompact切换至写模式

  5. 重复 1~4 步骤

2.2 ByteBuffer 结构

核心属性

字节缓冲区的父类 Buffer 中有几个核心属性,如下:

// Invariants: mark <= position <= limit <= capacityprivate int mark = -1;private int position = 0;private int limit;private int capacity;

核心方法:

put方法

flip方法

get方法

rewind方法

clean方法

markreset方法

compact方法

此方法为 ByteBuffer 的方法,而不是 Buffer 的方法

2.2 ByteBuffer 结构

ByteBuffer 有以下重要属性

刚开始

netty入门讲解(NettyJava领域网络编程的王者)(4)

写模式下,position 是写入位置,limit 等于容量,下图表示写入了 4 个字节后的状态。

netty入门讲解(NettyJava领域网络编程的王者)(5)

flip 动作发生后,position 切换为读取位置,limit 切换为读取限制。

netty入门讲解(NettyJava领域网络编程的王者)(6)

读取 4 个 byte 后,状态:

netty入门讲解(NettyJava领域网络编程的王者)(7)

clear 动作发生后,状态变为一开始。

compact 方法,是把未读完的部分向前压缩,然后切换至写模式。

netty入门讲解(NettyJava领域网络编程的王者)(8)