1.概述
Netty对NIO的API进行了良好的封装,完全可以将业务代码从网络IO中解放出来,具有高性能、 高吞吐量,低延迟等优点。经常被作为通信组件来使用,eg:Dubbo、RocketMq、Zookeeper等。
2.入门
1)依赖
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.35.Final</version>
</dependency>
2)服务端:
package org.example.netty;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import java.nio.charset.StandardCharsets;
public class NettyServerHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
ByteBuf buf = (ByteBuf) msg;
System.out.println("NettyServerHandler ctx:" + ctx);
System.out.println("NettyServerHandler 收到消息:" + buf.toString(StandardCharsets.UTF_8));
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
ByteBuf buf = Unpooled.copiedBuffer("Netty ...".getBytes(StandardCharsets.UTF_8));
ctx.writeAndFlush(buf);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
System.out.println("ctx:" + ctx);
System.out.println("cause:" + cause);
ctx.close();
}
}
package org.example.netty;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
public class NettyServer {
public static void main(String[] args) throws InterruptedException {
NioEventLoopGroup bossGroup = new NioEventLoopGroup();
NioEventLoopGroup workGroup = new NioEventLoopGroup();
try {
ServerBootstrap serverBootstrap = new ServerBootstrap();
serverBootstrap.group(bossGroup, workGroup)
.channel(NioServerSocketChannel.class)
.option(ChannelOption.SO_BACKLOG, 1024)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
socketChannel.pipeline().addLast(new NettyServerHandler());
}
});
System.out.println("netty server start.....");
ChannelFuture sync = serverBootstrap.bind(35599).sync();
System.out.println(".....");
sync.addListener(channelFuture -> {
if (channelFuture.isSuccess()) {
System.out.println("监听端口35599成功");
} else {
System.out.println("监听端口35599失败");
}
});
sync.channel().closeFuture().sync();
System.out.println("通道关闭");
} finally {
bossGroup.shutdownGracefully();
workGroup.shutdownGracefully();
System.out.println("线程池关闭");
}
}
}
3)客户端:
package org.example.netty;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
public class NettyClient {
public static void main(String[] args) throws InterruptedException {
NioEventLoopGroup nioEventLoopGroup=new NioEventLoopGroup();
try {
Bootstrap bootstrap=new Bootstrap();
bootstrap.group(nioEventLoopGroup)
.channel(NioSocketChannel.class)
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
socketChannel.pipeline().addLast(new NettyClientHandler());
}
});
System.out.println("netty Client start.....");
ChannelFuture sync = bootstrap.connect("127.0.0.1", 35599).sync();
System.out.println("netty Client connect.....");
sync.channel().closeFuture().sync();
}finally {
nioEventLoopGroup.shutdownGracefully();
}
}
}
package org.example.netty;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.concurrent.EventExecutorGroup;
import java.nio.charset.StandardCharsets;
public class NettyClientHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
System.out.println("客户端激活: " + ctx);
String msg = "Netty Client ...";
ByteBuf buf = Unpooled.copiedBuffer(msg.getBytes(StandardCharsets.UTF_8));
ctx.writeAndFlush(buf);
System.out.println("客户端发送消息:" + msg);
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
ByteBuf buf = (ByteBuf) msg;
System.out.println("ctx:" + ctx);
System.out.println("客户端收到消息:" + buf.toString(StandardCharsets.UTF_8));
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
System.out.println("ctx:" + ctx);
System.out.println("cause:" + cause);
ctx.close();
}
}
3.线程模型
4.高性能
- NIO多路复用非阻塞
- 零拷贝(使用直接内存,减少了堆内、堆外的拷贝)
- 主从Reactor线程模型提升并发量
- 单线程串行执行(减少竞争)