1、什么是netty
Netty,一个异步事件驱动的网络应用框架,用于快速开发可维护的高性能服务器和客户端。(对java的NIO进行封装,简化开发)
1.1 java Nio
BIO模型,一个client线程请求服务端之后,服务端accept请求,并新建线程来处理请求。当并发量变大,服务端创建线程数量过多,线程上下午切换等问题造成性能下降甚至宕机,同时,如果服务端发出读事件的动作,若数据还未准备好,就会阻塞当前线程。
NIO模型,un-blocking-io,采用非阻塞方式来读取客户端传给服务端的数据。进行了IO复用与非阻塞模式读取数据。
IO多路复用(又称事件驱动):一个线程,监控多个socket的读写就绪状况,这样,多个描述符的IO操作可以在一个线程内并发交替的顺序的完成,这就叫IO多路复用。映射在NIO中即Selector的监听。
非阻塞模式读取数据:线程进行读取数据,若数据为准备好,线程立马返回,不会阻塞当前线程。
1.2 NIO中的组件
1、channel(管道)
主要做数据的写入与读出操作。
2、Buffer(缓冲)
从channel中读出的数据与写入到channel中的数据,都是存放在Buffer中。Buffer有三个属性,容量(capacity),位置(position),长度限制(limit)。写模式下,limit-position,表示还有多少数据可以写入。
3、Selector,即IO多路复用的线程。
1.3 NIO初始化流程
1、初始化channel。
2、初始化Selector并把channel注册到Selector中。
3、轮训Selector返回的SelectKeys,找出就绪事件做对应的处理。
2、netty启动流程分析
客户端代码:
public final class EchoClient {
static final boolean SSL = System.getProperty("ssl") != null;
static final String HOST = System.getProperty("host", "127.0.0.1");
static final int PORT = Integer.parseInt(System.getProperty("port", "8007"));
static final int SIZE = Integer.parseInt(System.getProperty("size", "256"));
public static void main(String[] args) throws Exception {
// Configure SSL.git
final SslContext sslCtx;
if (SSL) {
sslCtx = SslContextBuilder.forClient()
.trustManager(InsecureTrustManagerFactory.INSTANCE).build();
} else {
sslCtx = null;
}
// Configure the client.
EventLoopGroup group = new NioEventLoopGroup();
try {
Bootstrap b = new Bootstrap();
b.group(group)
.channel(NioSocketChannel.class)
.option(ChannelOption.TCP_NODELAY, true)
.handler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline p = ch.pipeline();
if (sslCtx != null) {
p.addLast(sslCtx.newHandler(ch.alloc(), HOST, PORT));
}
//p.addLast(new LoggingHandler(LogLevel.INFO));
p.addLast(new EchoClientHandler());
}
});
// Start the client.
ChannelFuture f = b.connect(HOST, PORT).sync();
// Wait until the connection is closed.
f.channel().closeFuture().sync();
} finally {
// Shut down the event loop to terminate all threads.
group.shutdownGracefully();
}
}
}
服务端代码:
public final class EchoServer {
static final boolean SSL = System.getProperty("ssl") != null;
static final int PORT = Integer.parseInt(System.getProperty("port", "8007"));
public static void main(String[] args) throws Exception {
// Configure SSL.
final SslContext sslCtx;
if (SSL) {
SelfSignedCertificate ssc = new SelfSignedCertificate();
sslCtx = SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey()).build();
} else {
sslCtx = null;
}
// Configure the