网易首页 > 网易号 > 正文 申请入驻

netty系列之:好马配好鞍,为channel选择配套的selector

0
分享至

简介

我们知道netty的基础是channel和在channel之上的selector,当然作为一个nio框架,channel和selector不仅仅是netty的基础,也是所有nio实现的基础。

同样的,我们知道netty很多种不同的协议,这些协议都是在channel上进行通讯的,那么对于不同的协议来说,使用的channel和selector会有所不同吗?

带着这个疑问,我们一起来深入探究一下吧。

netty服务的基本构建方式

netty可以分为客户端和服务器端,实际上客户端和服务器端的构造方式差别不大,这里为了简单起见,以netty中服务器端的构建为例子进行研究。

回顾一下我们最开始搭建的netty服务器,其对应的代码如下:

//建立两个EventloopGroup用来处理连接和消息
EventLoopGroup bossGroup = new NioEventLoopGroup();
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) throws Exception {
ch.pipeline().addLast(new FirstServerHandler());

.option(ChannelOption.SO_BACKLOG, 128)
.childOption(ChannelOption.SO_KEEPALIVE, true);

// 绑定端口并开始接收连接
ChannelFuture f = b.bind(port).sync();

我们要注意的是两个地方,一个是ServerBootstrap的group方法,一个是它的channel方法。

EventLoopGroup

group有两种实现方式,可以带一个参数,也可以带两个参数。参数都是EventLoopGroup,EventLoopGroup主要用来注册channel, 供后续的Selector进行选择。

如果使用一个参数的形式,则一个EventLoopGroup同时处理acceptor和client的事件,如果使用两个参数,则会将两者分开。

当然,这都不是今天要讲的重点,今天要讲的是EventLoopGroup的构建在不同的协议中有什么不同。

EventLoopGroup本身是一个接口,他有很多种实现,但是本质上还是两种EventLoop:SingleThreadEventLoop和MultithreadEventLoopGroup.

也就是用单线程进行EventLoop处理和多线程进行EventLoop处理。

比如上面我们常用的NioEventLoopGroup,就是一个单线程的EventLoop。

NioEventLoopGroup通常我们使用的是无参的构造函数,实际上NioEventLoopGroup可以传入ThreadFactory,thread的个数,SelectorProvider和SelectStrategyFactory.

netty只提供了一个SelectStrategyFactory的实现:DefaultSelectStrategyFactory。

而对应SelectorProvider来说,默认的实现是SelectorProvider.provider(), 我们看下这个方法的具体实现:

public static SelectorProvider provider() {
synchronized (lock) {
if (provider != null)
return provider;
return AccessController.doPrivileged(
new PrivilegedAction() {
public SelectorProvider run() {
if (loadProviderFromProperty())
return provider;
if (loadProviderAsService())
return provider;
provider = sun.nio.ch.DefaultSelectorProvider.create();
return provider;


可以看到默认情况下,SelectorProvider有三种创建方式。

第一种就是从系统属性中查找:java.nio.channels.spi.SelectorProvider:

String cn = System.getProperty("java.nio.channels.spi.SelectorProvider");
Class c = Class.forName(cn, true,
ClassLoader.getSystemClassLoader());
provider = (SelectorProvider)c.newInstance();

如果有定义,则创建一个实例返回。

如果没有的话,则会从”META-INF/services/”中加载service Loader :

private static boolean loadProviderAsService() {

ServiceLoader sl =
ServiceLoader.load(SelectorProvider.class,
ClassLoader.getSystemClassLoader());
Iterator i = sl.iterator();

如果servie也没有找到的话,则会使用最后默认的sun.nio.ch.DefaultSelectorProvider.

channel

默认情况下,我们使用的是NioServerSocketChannel。他实际是从上面提到的默认的SelectorProvider来创建的。

private static final SelectorProvider DEFAULT_SELECTOR_PROVIDER = SelectorProvider.provider();
return DEFAULT_SELECTOR_PROVIDER.openServerSocketChannel();

所以使用的channel需要跟selector相匹配。

我们可以直接使用channel,也可以使用ChannelFactory,通过这些Factory来生成channel。

如果要使用ChannelFactory,则可以调用ServerBootstrap的channelFactory方法。

多种构建方式

上面提到了最基本的netty server构建方式。对应的是socket协议。

如果是要进行UDP连接,对应的channel应该换成NioDatagramChannel,如下:

EventLoopGroup group = new NioEventLoopGroup();
try {
Bootstrap b = new Bootstrap();
b.group(group)
.channel(NioDatagramChannel.class)
.option(ChannelOption.SO_BROADCAST, true)
.handler(new UDPServerHandler());

b.bind(PORT).sync().channel().closeFuture().await();

EventLoopGroup可以保持不变。

因为netty底层是基于Socket进行通讯的,socket底层又是基于TCP或者UDP协议,所以在netty中实现的http或者http2或者SOCKS协议都是在socket连接基础上进行的。

所以对http或者http2来说,channel还是NioServerSocketChannel。

可以看到只有UDP协议有所不同。同样的基于UDP协议之上的UDT协议也是不同的,其使用如下:

final NioEventLoopGroup acceptGroup = new NioEventLoopGroup(1, acceptFactory, NioUdtProvider.BYTE_PROVIDER);
final NioEventLoopGroup connectGroup = new NioEventLoopGroup(1, connectFactory, NioUdtProvider.BYTE_PROVIDER);

final ServerBootstrap boot = new ServerBootstrap();
boot.group(acceptGroup, connectGroup)
.channelFactory(NioUdtProvider.BYTE_ACCEPTOR)
.option(ChannelOption.SO_BACKLOG, 10)
.handler(new LoggingHandler(LogLevel.INFO))
.childHandler(new ChannelInitializer() {
@Override
public void initChannel(final UdtChannel ch) {
ch.pipeline().addLast(
new LoggingHandler(LogLevel.INFO),
new UDTEchoServerHandler());
}
});

UDT使用的是NioUdtProvider中提供的BYTE_PROVIDER和BYTE_ACCEPTOR分别作为selector和channelFactory。

其他的channel

除了NioSocketChannel之外,还有EpollChannel、KQueueChannel、SctpChannel,这些channel都是针对不同协议来使用的。我们会在后续的文章中详细进行介绍。

总结

channel和selector是netty的基础,在这基础之上,netty可以扩展适配所有基于tcp和udp的协议,可以说非常的强大。

本文已收录于 http://www.flydean.com/39-netty-selecto…r-channelfactory/

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
四川饭店回收剩蘸料,铁证面前还狡辩,当地人爆猛料,市监局介入

四川饭店回收剩蘸料,铁证面前还狡辩,当地人爆猛料,市监局介入

青梅侃史啊
2026-06-21 19:30:11
中国女排输球赢人,张籽萱边哭边拦网,赵勇关键挑战逆转成为经典

中国女排输球赢人,张籽萱边哭边拦网,赵勇关键挑战逆转成为经典

富贵体坛说
2026-06-22 06:13:26
教育专家一语戳破现实:中考是15岁孩子还不懂命运,就已经被分开

教育专家一语戳破现实:中考是15岁孩子还不懂命运,就已经被分开

鬼菜生活
2026-06-22 04:39:31
阿森纳两将带伤战世界杯吐槽赛程密

阿森纳两将带伤战世界杯吐槽赛程密

体坛周报
2026-06-22 04:19:43
韩媒又嘲讽国足:14万人的库拉索世界杯拿分,14亿人中国却做不到

韩媒又嘲讽国足:14万人的库拉索世界杯拿分,14亿人中国却做不到

以茶带书
2026-06-22 00:32:07
心理学揭示一个冷酷的规律:男人对某个女人的占有欲强烈,外在表现绝非苦苦纠缠,而是两种近乎无情的精神囚禁

心理学揭示一个冷酷的规律:男人对某个女人的占有欲强烈,外在表现绝非苦苦纠缠,而是两种近乎无情的精神囚禁

心理观察局
2026-06-21 06:30:07
雨天再暴露电车另一大缺点,事故率远超油车,超强动力太要命!

雨天再暴露电车另一大缺点,事故率远超油车,超强动力太要命!

柏铭锐谈
2026-06-19 18:23:30
别被电视剧骗了!这才是清朝王爷大臣的真实照片,手指甲都很长!

别被电视剧骗了!这才是清朝王爷大臣的真实照片,手指甲都很长!

史不语
2026-06-22 06:00:09
麦科勒姆续约老鹰 老鹰询价库明加

麦科勒姆续约老鹰 老鹰询价库明加

体坛周报
2026-06-22 01:34:14
《浪姐》五公,她俩不努力、唱歌难听、经常失误,凭什么进成团夜

《浪姐》五公,她俩不努力、唱歌难听、经常失误,凭什么进成团夜

一娱三分地
2026-06-22 00:22:01
日本队赢球央视收视率破 3!中国球迷边看边酸:何时轮到我们?

日本队赢球央视收视率破 3!中国球迷边看边酸:何时轮到我们?

十点体坛
2026-06-21 18:37:35
大码模特现实里到底多大?

大码模特现实里到底多大?

飛娱日记
2026-05-12 08:27:55
上海看走眼!昔日全明星控卫或被摆上货架,场均1.4分太让人失望

上海看走眼!昔日全明星控卫或被摆上货架,场均1.4分太让人失望

老叶评球
2026-06-21 11:06:10
马斯克拿下7800亿元天价薪酬,2028年可兑现

马斯克拿下7800亿元天价薪酬,2028年可兑现

界面新闻
2026-06-21 07:43:48
遭中国制裁后,菲总统亲自出面去见普京,却帮了我们一个大忙?

遭中国制裁后,菲总统亲自出面去见普京,却帮了我们一个大忙?

阿库财经
2026-06-22 05:12:01
俄媒女主持人曾言:若中国愿出兵300万,俄军很快就能打败乌克兰

俄媒女主持人曾言:若中国愿出兵300万,俄军很快就能打败乌克兰

南宗历史
2026-03-17 16:53:10
10点睡觉是错误的?医生建议:过了60岁,睡觉尽量要做到这4点

10点睡觉是错误的?医生建议:过了60岁,睡觉尽量要做到这4点

芹姐说生活
2026-06-21 15:54:27
英国又为乌克兰研发出一款大杀器

英国又为乌克兰研发出一款大杀器

史政先锋
2026-06-21 23:18:32
廉价版M9亮相:鸿蒙系为何自己山寨自己

廉价版M9亮相:鸿蒙系为何自己山寨自己

小怪吃美食
2026-06-21 03:28:02
恭喜!CBA顶级后卫!休赛期第一笔顶薪合同

恭喜!CBA顶级后卫!休赛期第一笔顶薪合同

篮球实战宝典
2026-06-21 17:50:27
2026-06-22 06:56:49
flydean程序那些事
flydean程序那些事
最通俗的解读,最深刻的干货!
356文章数 438关注度
往期回顾 全部

科技要闻

马斯克拿下7800亿元天价薪酬 2028年可兑现

头条要闻

世界第10难求一胜!10人比利时0-0伊朗

头条要闻

世界第10难求一胜!10人比利时0-0伊朗

体育要闻

德国的超级替补,10年前还在工厂上班

娱乐要闻

原来她就是张颂文老婆

财经要闻

“床垫界的特斯拉”破产了

汽车要闻

惊出冷汗!重庆实测奥迪A5L,华为智驾这波操作绝了…

态度原创

旅游
教育
艺术
游戏
公开课

旅游要闻

云南十八怪湖泊称作海,滇池滇海叫法流传千年,根源不只是水面大

教育要闻

热议云南中考历史题

艺术要闻

310米!欧盟第一高楼,坐落于波兰

《STRANGER THAN HEAVEN》制作人访谈:它真不是“人中之龙”"/> 主站 商城 论坛 自运营 登录 注册 《STRANGER THAN ...

公开课

李玫瑾:为什么性格比能力更重要?

无障碍浏览 进入关怀版