Netty启动原理

典型的Netty服务端启动代码:12345678910111213141516171819202122232425262728293031323334353637public class MyServer { public static void main(String[] args) throws Exception{ EventLoopGroup bossGroup = new NioEventLoopGroup(1); EventLoopGroup workerGroup = new NioEventLoopGroup(); try { ServerBootstrap serverBootstrap = new ServerBootstrap(); serverBootstrap.group(bossGroup,workerGroup) .channel(NioServerSocketChannel.class) .childHandler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel ch) throws Exception { ChannelPipeline pipeline = ch.pipeline(); //入站编码处理器 pipeline.addLast(new MyByteToLongDecoder()); //出站的handler进行编码 pipeline.addLast(new MyLongToByteEncoder()); //自定义的handler 处理业务逻辑 pipeline.addLast(new MyServerHandler()); } }); ChannelFuture channelFuture = serverBootstrap.bind(7000).sync(); channelFuture.channel().closeFuture().sync(); }finally { bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); } }}

Netty之ChannelHandler

Channel的生命周期Channel包含4个状态: ChannelUnregistered Channel已经被创建,但还未注册到EventLoop ChannelRegistered Channel已经被注册到EventLoop ChannelActive Channel处于活动状态,它现在可以接受和发送数据了 ChannelInactive Channel没有连接到远程节点

Netty之ByteBuf

简介ByteBuf是Netty的数据容器,它解决了JDK API的局限性,能为网络应用程序的开发者提供更好的API支持。ByteBufAPI的优点如下: 它可以被用户自定义的缓冲区类型拓展 通过内置的复合缓冲区类型实现了透明的零拷贝。 容量可以按需增长 在读和写这两种模式下切换不需要调用BuyteBuffer的flip()方法 读和写使用了不同的索引 方式支持链式调用 支持引用计数 支持池化

Netty线程模型

Reactor线程模型Netty的线程模型实际上就是Reactor模型的一种实现。 Reactor模型是基于事件驱动开发的,核心组成部分是一个Reactor和一个线程池,其中Reactor负责监听和分配事件,线程池负责处理事件。根据Reactor的数量有线程池的数量,又可以将Reactor分为三种模型: 单线程模型(单Reactor,单线程) 多线程模型(单Reactor,多线程) 主从多线程模型(多Reactor,多线程)

Netty启动流程分析

示例代码我们就以下面这段代码为例,来分析一个Netty是如何启动的。 123456789101112131415161718192021222324252627282930313233343536public class HttpServer { public static void main(String[] args) throws InterruptedException { //负责接收客户端连接 EventLoopGroup bossGroup = new NioEventLoopGroup(1); //负责网络读写 EventLoopGroup workerGroup = new NioEventLoopGroup(); try { ServerBootstrap bootstrap = new ServerBootstrap(); bootstrap.group(bossGroup,workerGroup) .channel(NioServerSocketChannel.class) .childHandler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel socketChannel) throws Exception { ChannelPipeline pipeline = socketChannel.pipeline(); //http编解码器 pipeline.addLast(new HttpServerCodec()); //自定义的handler pipeline.addLast(new HttpServerHandler()); } }); final ChannelFuture future = bootstrap.bind(3333).sync(); future.channel().closeFuture().sync(); }finally { bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); } }} 这段代码我们首先创建了两个EventLoopGroup。然后创建了ServerBootstrap并设置设置了一系列的属性。然后调用了bind方法完成了服务器的启动。所以要分析Netty服务端的启动过程就需要从bind方法入手。

Netty学习笔记二

什么是TCP粘包和拆包?TCP是一个“流”协议,所谓流就是没有界限的一串数据。TCP协议会根据TCP缓冲区的实际情况对包进行划分,所以业务上的一个包,可能被TCP拆分为多个包发送(拆包),多个小的包也可能被TCP合并为一个包进行发送(粘包)。 TCP粘包和拆包发生的原因原因有三个: 应用程序write写入的字节大小大于套接字缓冲区的大小 进行MSS(maximum segment size,最大分节大小,为TCP数据包每次传输的最大数据分段大小)大小的TCP分段 以太帧的payload大于MTU(maximum transmission unit,最大传输单元,由硬件规定)进行IP分片

Netty学习笔记一

Netty是是什么?Netty是基于NIO的客户,服务器端的编程框架,它提供了异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠的网络服务器和客户端程序。 Netty有什么特点?