Netty学习路线
很早就说要写关于Netty的博客了,如今他来了他来了!!!
第一章 Netty入门
1.1 Netty的概述
1.1.1 Netty简介
官网中的解释:
Netty是一个异步事件驱动的网络应用框架,用于快速开发可维护的高性能协议服务器和客户端。(王婆卖瓜自卖自夸)
1.1.2 谁在使用Netty?
Dubbo、zk、RocketMQ、ElasticSearch、Spring5(对HTTP协议的实现)、GRPC、Spark等大型开源项目都在使用Netty作为底层通讯框架
1.1.3 Netty中的核心概念
- Channel
- 管道,其是对Socket的封装,其包含了一组API,大大简化了直接与Socket进行操作的复杂性
- EventLoopGroup
- EventLoopGroup 是一个EventLoop池,包含很多的EventLoop
- Netty为每个Channel分配了一个EventLoop,用于处理用户连接请求、对用户请求的处理等所有事件。EventLoop本身只是一个线程驱动,在其生命周期内只会绑定一个线程,让该线程处理一个Channel的所有IO事件。
- 一个Channel一旦与一个EventLoop相绑定,那么在Channel的整个生命周期内是不能改变的。一个EventLoop可以与多个Channel绑定。即Channel与EventLoop的关系是n:1,而EventLoop与线程的关系是1:1。
- ServerBootStrap
- 用于配制整个Netty代码,将各个组件关联起来。服务端使用的是ServerBootStrap,而客户端使用的是BootStrap。快速开发的脚手架罢了。。
- ChannelHandler与ChannelPipeline
- ChannelHandler是对Channel中数据的处理器,这些处理器可以是系统本身定义好的编解码器,也可以是用户自定义的。这些处理器会被统一添加到一个ChannelPipeline的对象中,然后按照添加的顺序对Channel中的数据进行依次处理。
- ChannelFuture
- Netty中所有IO操作都是异步的,即操作不会立即得到返回结果,所以Netty中定义了一个ChannelFuture对象作为这个异步操作的“代言人”,表示异步操作本身。如果想获取到该异步操作的返回值,可以通过该异步操作对象的addListener()方法为该异步操作添加监听器,为其注册回调:当结果出来马上调用执行
- Netty的异步编程模型都是简历在Future与回调概念之上的。
1.1.4 Netty执行流程
1.2 小尝试
目的:
- 通过该程序达到目的是,对Netty编程的基本结构及流程有所了解
- 该程序是通过Netty实现Http请求的处理,即接受Http,返回Http响应。
1.2.1 创建工程
创建一个普通的Maven的Java工程。
1.2.2 导入依赖
仅导入一个netty-all依赖即可
<dependencies>
<!--netty-all-->
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.65.Final</version>
</dependency>
<!--lombok依赖-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.22</version>
<scope>provided</scope>
</dependency>
</dependencies>
1.2.3 定义服务启动类
public class SomeServer {
public static void main(String[] args) throws InterruptedException {
// 用于处理客户端连接请求,将请求发送给childGroup中的eventLoop
EventLoopGroup parentGroup = new NioEventLoopGroup();
// 用于处理客户端请求
EventLoopGroup childGroup = new NioEventLoopGroup();
try {
// 用户启动ServerChannel
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(parentGroup, childGroup) // 指定eventLoopGroup
.channel(NioServerSocketChannel.class) // 指定使用NIO进行通信
.childHandler(new SomeChannelInitializer()); // 指定childGroup中的eventLoop所绑定的线程所要处理的处理器
// 指定当前服务器所监听的端口号