Netty之EventLoopGroup详解
创始人
2024-05-25 10:09:41

目录

目标

Netty版本

Netty官方API

NioEventLoopGroup和DefaultEventLoop的区别

EventLoopGroup实现对内部EventLoop的轮询

EventLoop对普通任务和定时任务的实现

执行普通任务

执行定时任务

划分EventLoopGroup职责

简言

实现

指定EventLoopGroup操作ChannelHandler

简言

实现


目标

  • 了解io.netty.channel.nio.NioEventLoopGroupio.netty.channel.DefaultEventLoop的区别。
  • 掌握EventLoopGroup如何实现对内部EventLoop的轮询,以及EventLoop对普通任务和定时任务的实现方法。
  • 划分EventLoopGroup职责,指定EventLoopGroup操作ChannelHandler。

Netty版本

        io.nettynetty-all4.1.87.Final

Netty官方API

Netty API Reference (4.1.87.Final)https://netty.io/4.1/api/index.html


NioEventLoopGroupDefaultEventLoop的区别

io.netty.channel.nio.NioEventLoopGroupio.netty.channel.DefaultEventLoop是较为常用的EventLoop,最大的区别在于前者可以处理IO事件、普通任务、定时任务;后者只能处理普通任务和定时任务


EventLoopGroup实现对内部EventLoop的轮询

package com.ctx.netty;import io.netty.channel.DefaultEventLoopGroup;
import lombok.extern.slf4j.Slf4j;@Slf4j
public class EventLoopTest {public static void main(String[] args) {//设置组内2个EventLoopDefaultEventLoopGroup defaultEventLoop = new DefaultEventLoopGroup(2);//循环输出5次for(int i=0;i<5;i++){//根据打印的结果,发现组内的2个对象被轮询了。log.info(String.valueOf(defaultEventLoop.next()));}}
}


EventLoop对普通任务和定时任务的实现

执行普通任务

package com.ctx.netty;import io.netty.channel.DefaultEventLoopGroup;
import lombok.extern.slf4j.Slf4j;@Slf4j
public class EventLoopTest {public static void main(String[] args) {DefaultEventLoopGroup defaultEventLoop = new DefaultEventLoopGroup(2);//执行普通任务//或者defaultEventLoop.next().submit(()->{});defaultEventLoop.next().execute(()->{try {Thread.sleep(2000);} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println("Hello World!");});System.out.println("main");}
}

结果


执行定时任务

package com.ctx.netty;import io.netty.channel.DefaultEventLoopGroup;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.TimeUnit;@Slf4j
public class EventLoopTest {public static void main(String[] args) {DefaultEventLoopGroup defaultEventLoop = new DefaultEventLoopGroup(2);log.info(String.valueOf(System.currentTimeMillis()));//执行普通任务defaultEventLoop.next().scheduleAtFixedRate(//任务对象() -> {log.info(String.valueOf(System.currentTimeMillis()));},//初始延迟时间,0表示不延迟(受到时间单位的影响)。1,//间隔执行时间(受到时间单位的影响)。2,//时间单位TimeUnit.MINUTES);System.out.println("main");}
}


划分EventLoopGroup职责

简言

我在之前的一篇文章《初识Netty并用Netty搭建最基本的网络服务器和客户端_我的身前一尺是我的世界的博客-CSDN博客》中例举了一组简单的服务端和客户端的实现。文章中的服务端我只用了一个EventLoopGroup,但是Netty更推荐将不同的事件划分给不同的EventLoopGroup。

实现

package com.ctx.netty;import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import lombok.extern.slf4j.Slf4j;@Slf4j
public class NettyServer {public static void main(String[] args) {//Netty服务端启动器ServerBootstrap serverBootstrap = new ServerBootstrap();/*** 官方API对group(EventLoopGroup parentGroup,EventLoopGroup childGroup)法的描述:* Set the EventLoopGroup for the parent (acceptor) and the child (client).* These EventLoopGroup's are used to handle all the events and IO for ServerChannel and Channel's.** 译文:* parentGroup对ServerChannel负责,它处理accept事件;默认1个线程数。* childGroup对Channel负责,它处理读写操作;默认cpu核心数*2个线程。*/serverBootstrap.group(new NioEventLoopGroup(),new NioEventLoopGroup(2));//选择服务器的ServerSocketChannel实现,这里我选择NIO。serverBootstrap.channel(NioServerSocketChannel.class);//设置事件类型serverBootstrap.childHandler(new ChannelInitializer() {@Overrideprotected void initChannel(NioSocketChannel nioSocketChannel) throws Exception {//把ByteBuf解码为StringnioSocketChannel.pipeline().addLast(new StringDecoder());//pipeline是流水线,Handler是工序,流水线可以有多个工序。//Handler分为入栈(Inbound)和出栈(Outbound)//自定义HandlernioSocketChannel.pipeline().addLast(new ChannelInboundHandlerAdapter(){//处理读事件@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {log.info(msg.toString());}});}});//设置服务器的监听端口serverBootstrap.bind(8999);}
}

指定EventLoopGroup操作ChannelHandler

简言

我们知道,pipeline是流水线,ChannelHandler相当于工序,一个或多个工序组成了流水线。不同的工序耗时可能不同,如果有的工序耗时太久,则会对其他工序的执行产生影响,为此,Netty为我们提供了指定EventLoopGroup操作ChannelHandler的API。


实现

package com.ctx.netty;import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.DefaultEventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import lombok.extern.slf4j.Slf4j;@Slf4j
public class NettyServer {public static void main(String[] args) {DefaultEventLoopGroup defaultEventLoopGroup = new DefaultEventLoopGroup();//Netty服务端启动器ServerBootstrap serverBootstrap = new ServerBootstrap();serverBootstrap.group(new NioEventLoopGroup(),new NioEventLoopGroup(2));//选择服务器的ServerSocketChannel实现,这里我选择NIO。serverBootstrap.channel(NioServerSocketChannel.class);//设置事件类型serverBootstrap.childHandler(new ChannelInitializer() {@Overrideprotected void initChannel(NioSocketChannel nioSocketChannel) throws Exception {//把ByteBuf解码为StringnioSocketChannel.pipeline().addLast(new StringDecoder());nioSocketChannel.pipeline().addLast("Handler",new ChannelInboundHandlerAdapter(){//处理读事件@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {log.info(msg.toString());//把msg传给下一个Handlerctx.fireChannelRead(msg);}}).addLast(defaultEventLoopGroup,"Handler2",new ChannelInboundHandlerAdapter(){//处理读事件@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {log.info(msg.toString());}});}});//设置服务器的监听端口serverBootstrap.bind(8999);}
}

相关内容

热门资讯

北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...