1、什么是 Netty
Netty is an asynchronous event-driven network application framework
for rapid development of maintainable high performance protocol servers & clients.
复制代码
Netty 是一个异步的、基于事件驱动的网络应用框架,用于疾速开发可保护、高性能的网络服务器和客户端

留神:netty的异步还是基于多路复用的,并没有实现真正意义上的异步IO

2、Netty 的劣势
如果应用传统 NIO,其工作量大,bug 多

须要本人构建协定
解决 TCP 传输问题,如粘包、半包
因为 bug 的存在,epoll 空轮询导致 CPU 100%

Netty 对 API 进行加强,使之更易用,如

FastThreadLocal => ThreadLocal
ByteBuf => ByteBuffer

3、入门案例
1、服务器端代码
public class HelloServer {

public static void main(String[] args) {    // 1、启动器,负责拆卸netty组件,启动服务器    new ServerBootstrap()            // 2、创立 NioEventLoopGroup,能够简略了解为 线程池 + Selector            .group(new NioEventLoopGroup())            // 3、抉择服务器的 ServerSocketChannel 实现            .channel(NioServerSocketChannel.class)            // 4、child 负责解决读写,该办法决定了 child 执行哪些操作            // ChannelInitializer 处理器(仅执行一次)            // 它的作用是待客户端 SocketChannel 建设连贯后,执行 initChannel 以便增加更多的处理器            .childHandler(new ChannelInitializer<NioSocketChannel>() {                @Override                protected void initChannel(NioSocketChannel nioSocketChannel) throws Exception {                    // 5、SocketChannel的处理器,应用StringDecoder解码,ByteBuf=>String                    nioSocketChannel.pipeline().addLast(new StringDecoder());                    // 6、SocketChannel的业务解决,应用上一个处理器的处理结果                    nioSocketChannel.pipeline().addLast(new SimpleChannelInboundHandler<String>() {                        @Override                        protected void channelRead0(ChannelHandlerContext channelHandlerContext, String s) throws Exception {                            System.out.println(s);                        }                    });                }                // 7、ServerSocketChannel绑定8080端口            }).bind(8080);}

}
复制代码
2、客户端代码
public class HelloClient {

public static void main(String[] args) throws InterruptedException {    new Bootstrap()            .group(new NioEventLoopGroup())            // 抉择客户 Socket 实现类,NioSocketChannel 示意基于 NIO 的客户端实现            .channel(NioSocketChannel.class)            // ChannelInitializer 处理器(仅执行一次)            // 它的作用是待客户端SocketChannel建设连贯后,执行initChannel以便增加更多的处理器            .handler(new ChannelInitializer<Channel>() {                @Override                protected void initChannel(Channel channel) throws Exception {                    // 音讯会通过通道 handler 解决,这里是将 String => ByteBuf 编码收回                    channel.pipeline().addLast(new StringEncoder());                }            })            // 指定要连贯的服务器和端口            .connect(new InetSocketAddress("localhost", 8080))            // Netty 中很多办法都是异步的,如 connect            // 这时须要应用 sync 办法期待 connect 建设连贯结束            .sync()            // 获取 channel 对象,它即为通道形象,能够进行数据读写操作            .channel()            // 写入音讯并清空缓冲区            .writeAndFlush("hello world");}

}
复制代码
3、运行流程
左:客户端 右:服务器端

组件解释

channel 能够了解为数据的通道
msg 了解为流动的数据,最开始输出是 ByteBuf,但通过 pipeline 中的各个 handler 加工,会变成其它类型对象,最初输入又变成 ByteBuf
handler 能够了解为数据的解决工序

工序有多道,合在一起就是 pipeline(传递路径),pipeline 负责公布事件(读、读取实现…)流传给每个 handler, handler 对本人感兴趣的事件进行解决(重写了相应事件处理办法)

pipeline 中有多个 handler,解决时会顺次调用其中的 handler

handler 分 Inbound 和 Outbound 两类

Inbound 入站

Outbound 出站

eventLoop 能够了解为解决数据的工人

eventLoop 能够治理多个 channel 的 io 操作,并且一旦 eventLoop 负责了某个 channel,就会将其与 channel 进行绑定,当前该 channel 中的 io 操作都由该 eventLoop 负责
eventLoop 既能够执行 io 操作,也能够进行工作解决,每个 eventLoop 有本人的工作队列,队列里能够堆放多个 channel 的待处理工作,工作分为一般工作、定时工作
eventLoop 依照 pipeline 程序,顺次依照 handler 的布局(代码)解决数据,能够为每个 handler 指定不同的 eventLoop