Netty基本介绍

Netty基本介绍

Netty是一个异步的完全基于事件驱动的高性能的网络通信框架,目前大部分java生态的分布式框架的通信框架都是基于Netty构建的。比如:Dubbo、Zookeeper、Hadoop、Zuul2等。

Netty之所以能够流行除了其高性能的特性外,还得益于其简单易用的API、全异步和完全基于事件驱动的架构设计。

NIO

所谓NIO其实时相对于BIO而言的,传统的IO在网络请求场景下,从接受一个请求,到开始从内核中读取数据这段时间内一直是阻塞的,而NIO则会在读/写调用没有数据的时候立即返回。

具体的实现,其实是通过操作系统提供的API(Epoll模型,Unix:kqueue),注册一组非阻塞套接字,而操作系统会不断轮询这些套接字,一旦其中一个进入读/写就绪状态,select()函数就会返回。

//创建一个epoll的句柄,size用来告诉内核这个监听的数目一共有多大 
int epoll_create(int size); 
//对指定描述符fd执行op操作。epfd:是epoll_create()的返回值,op:表示op操作,fd:是需要监听的fd,epoll_event:是告诉内核需要监听什么事件
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event); 
//等待epfd上的io事件,最多返回maxevents个事件。 
int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout);

Java原生的NIO便是基于Epoll模型来实现的。而Netty则是基于JavaNIO构建的,只不过提供了统一的API且提供了更加丰富的接口和更灵活的扩展,比如它的pipeline机制,能够让我们对请求的处理做出各种定制。

Netty服务创建-ServerBoostrap

ServerBoostrap创建示例

EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
    ServerBootstrap b = new ServerBootstrap();
    b.group(bossGroup, workerGroup)
     .channel(NioServerSocketChannel.class)
     .childHandler(new ChannelInitializer() {
         @Override
         public void initChannel(SocketChannel ch) {
             ChannelPipeline p = ch.pipeline();
             p.addLast(new DiscardServerHandler());
             p.addLast(new DefaultEventExecutorGroup(16), "handler", new DiscardServerHandler());
         }
     });
    // Bind and start to accept incoming connections.
    ChannelFuture f = b.bind(PORT).sync();
    f.channel().closeFuture().sync();
} finally {
    workerGroup.shutdownGracefully();
    bossGroup.shutdownGracefully();
}

从ServerBoostrap的创建代码,可以看到,启动需要传递的一些基本参数,比如用以处理NioServerSocketChannel连接事件的bossGroup及用以处理NioSocketChannle IO事件的workerChannel,其中
需要注意的是EventExecutorGroup,它是Netty用于处理耗时任务的线程池,当我们提交一个非耗时任务时,直接通过EventLoop去提交就可以了,但是如果要执行耗时任务,就不能再EventLoop上进行处理了,因为一个EventLoop同时负责处理多个Channl的IO事件,如果当前Channel阻塞了,则会影响其他Channel的事件处理。在业务逻辑处理的时候提交任务的代码实例如下:

如何提交耗时和非耗时任务

Channel channel = ctx.channel();
//执行非耗时任务
Future future = channel.eventLoop().scheduleAtFixedRate(new Runnable() {
    @Override
    public void run() {
    }
},6,6, TimeUnit.MINUTES);

Future future1 = ctx.executor().scheduleAtFixedRate(new Runnable() {
    @Override
    public void run() {
        //耗时任务
    }
}, 6, 6, TimeUnit.MINUTES);

channel方法:指定用于服务创建时负责处理客户端连接的class

childHandler方法:指定,当接收到请求创建Channel后,需要为创建的Channel添加的ChannelHandler

b.bind(PORT):绑定端口并启动,下文将根据对服务启动流程进行分析

Netty请求处理流程图

image2018-6-2 22_3_25.png

你可能感兴趣的:(Netty基本介绍)