Netty尝鲜
何谓Netty
- Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients.
- Netty: Home,不要怕英文。
异步、事件驱动。
第一个程序
环境依赖
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.78.Final</version>
</dependency>
写一个经典的Hello World程序
- 先不管用到的类有啥功能。
import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.*;
import io.netty.util.CharsetUtil;
public class HttpServer {
public static void main( String[] args ) {
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
try{
ServerBootstrap serverBootstrap = new ServerBootstrap();
serverBootstrap.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new MyServerInitializer());
ChannelFuture channelFuture = serverBootstrap.bind(8899).sync();
channelFuture.channel().closeFuture().sync();
}catch (Exception exception){
exception.printStackTrace();
}finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}
class MyServerInitializer extends ChannelInitializer<SocketChannel> {
@Override
protected void initChannel(SocketChannel ch) {
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast("httpServerCodec", new HttpServerCodec())
.addLast("testHttpServerHandler", new MyHttpServerHandler())
.addLast("myException",new ExceptionHandler());
}
}
class MyHttpServerHandler extends SimpleChannelInboundHandler<HttpObject> {
@Override
protected void channelRead0(ChannelHandlerContext ctx, HttpObject msg) {
ByteBuf content = Unpooled.copiedBuffer("Hello World", CharsetUtil.UTF_8);
FullHttpResponse fullHttpResponse = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1,
HttpResponseStatus.OK, content);
fullHttpResponse.headers().set(HttpHeaderNames.CONTENT_TYPE,"text/plain");
fullHttpResponse.headers().set(HttpHeaderNames.CONTENT_LENGTH, content.readableBytes());
ctx.writeAndFlush(fullHttpResponse);
}
}
class ExceptionHandler extends ChannelInboundHandlerAdapter {
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
System.err.println(this.getClass().getName() + " 异常处理,e:" + cause);
}
}
用到的Netty组件
大致名称及功能
- Netty的核心组件包括:
- Channel:代表一个网络连接,可以读取和写入数据。
- EventLoop:处理Channel上的所有事件,包括连接的建立和关闭、读取和写入数据等。
- ChannelHandler:处理所有的I/O事件,例如数据的读取和写入、连接的建立和关闭等。
- ChannelPipeline:是一组有序的ChannelHandler,用于处理Channel的I/O事件。数据在进入和离开Channel时,会经过一系列的ChannelHandler进行处理。
- Netty的架构采用了Reactor模式。当一个Channel有I/O事件发生时,Netty会通过EventLoop将事件派发给对应的ChannelHandler进行处理。由于Netty采用了异步非阻塞的I/O模型,可以大大提高网络应用程序的性能和可伸缩性。
- 当使用Netty开发应用程序时,通常需要配置ChannelPipeline,这可以通过使用ChannelInitializer来完成。ChannelInitializer是一种特殊类型的ChannelHandler,它负责初始化ChannelPipeline。在初始化过程中,开发者可以添加自己的ChannelHandler,并设置不同的ChannelHandler的顺序。
- 另外,ChannelHandler有许多不同的方法可以实现,例如:
- channelActive:在连接建立时被调用。
- channelRead:当读取到数据时被调用。
- channelReadComplete:当读取到的数据已经被处理完毕时被调用。
- channelInactive:在连接关闭时被调用。
- exceptionCaught:在发生异常时被调用。
启动的特定模式
- 首先,通过创建两个EventLoopGroup来分别处理连接的请求和网络I/O事件。其中,bossGroup用于接收连接请求,workerGroup用于处理I/O事件。
- 然后,通过创建一个ServerBootstrap对象来启动服务器,其中:
- group方法将bossGroup和workerGroup设置为服务器的两个EventLoopGroup。
- channel方法设置了服务器使用的通道类型,这里使用了NioServerSocketChannel。
- handler方法添加的处理器是针对bossGroup。
- childHandler方法设置了用于处理Channel的初始化器,就是针对workerGroup。
- 最后,通过调用bind方法来绑定服务器的端口号,并调用sync方法来阻塞等待服务器启动完成。在启动完成后,使用closeFuture方法来等待服务器的关闭,以确保程序的正常退出。
- 在程序退出时,通过调用shutdownGracefully方法来优雅地关闭EventLoopGroup,以释放资源和清理内存。
转载自:https://juejin.cn/post/7227003532480970808