前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >关于netty你需要了解的二三事.md

关于netty你需要了解的二三事.md

作者头像
山行AI
发布2019-06-28 16:25:08
1.9K0
发布2019-06-28 16:25:08
举报
文章被收录于专栏:山行AI

1. Netty 接受客户的线程(boss线程)和处理IO的线程(worker线程)分别设置,其中:

  • boss线程用来处理accept
  • worker线程用来处理读写
  • boss线程的channel是NioServerChannel
  • worker线程的channel是NioChannel
  • netty 中的channel和handler方法都是针对NioServerChannel的(也就是accept)
  • child channel和child handler都是针对NioChannel的

2. ServerBootStrap的bind方法,主要做select、绑定端口和注册事件三件事。

在nio编程中,select和bind可以不按顺序调用,也可以不在同一个线程中。netty中这是在boss线程中做的事情,可能会出现先select再绑定端口的情况。 这样做的好处就是统一化select逻辑,但是因为要支持tcp,udp,sctp等传输协议,每种协议都是不同类型的channel,所以将注册分离开已达到最大的代码重用。所以, select逻辑都在NioEventLoop的run方法里,而不同协议支持的注册和bind端口由不同类型的channel实现。netty在注册的时候先注册了个0,表示不对任何事件感兴趣,在绑定的时候,才又注册了accept事件。 这就是boss线程和worker线程分离开的原因。

3. ServerBootStrap的bind方法每调用一次就会绑定一个端口,也会使用一个boss线程,这就是为什么boss线程也要设置成线程池的原因。

4. NIO 中,如果一个客户端进程退出,为什么会触发服务器的OP_READ事件?

epoll触发一个对断关闭然后在jvm层被包装成了一个读事件。因为 epoll收到退出事件的时候要触发一个读操作,读到-1认为退出,所以java从实际操作角度认为epoll的退出事件也是读。所以 简化了java层处理的事件数。 但这个时候用channel.read()方法读的时候,会报java.io.IOException: 远程主机强迫关闭了一个现有的连接。如果是主动关闭可以在触发读事件第一件事是判断是否有效吧,比如先读一个字节 看看是不是-1,如果是-1就停止。 如果异常是reset by peer,则表示被动关闭,一个流氓方法是 所有和链接相关的异常都catch,然后关闭这个链接,没有更好的做法了,netty自己也是这样做的。

5. 为什么nettyServer端的流控配置都是硬编码了? 而NettyClient 端可以自定义配置呢?

在配置中对Async和Oneway的情况是有并发限制的,同时在处理的任务数有限制,如果有超出,则会抛出RemotingTooMuchRequestException; 其中Server流控配置中:Async是64,Oneway是256。 不能通过System.property更改,只能通过调用NettyServerConfig.setXxx方法更改。

Netty client端流控配置:

这个设置得比Server的大小限制得大的太多了,默认值根本没什么意义。其中Async和Oneway都是65535,可以通过System Properties来更改。

这些默认值都是一些经验值,所以比较合理。

6. epoll 的两种工作模式:水平触发(LT) 和 边缘触发(ET)

举个例子,你有一个队列,有个队列的consumer,如果consumer从队列拿了一个东西,处理完后,告诉队列:你可以扔了,这大致等价于LT模式。 如果consumer拿完了东西,队列自己就直接扔了,这大概等价于ET模式。一般来说,ET模式下事件触发次数比LT要少很多,所以ET模式效率更高。但是哪个”高速“,现实当中应该用哪个,不得看consumer的处理速度,看业务需求。 场景:

  • select(2) 和 poll(2) 都是LT(水平触发)。epoll默认用的是LT模式。
  • et模式在nginx和redis中大量使用。
  • epoll(5) 是LT 和 ET都支持。不过JDK NIO Linux上实现是用的LT,不支持配置为ET。所以说Java对网络的抽象不是很好。
  • Netty-native两者都支持,默认为ET,可配置为LT。Netty 既有有基于JDK NIO的实现,也有完全不依赖于JDK网络抽象的native实现,即Netty-native。

7. 附录

本公众号后面的文章中会对上面的一些细节进行实例讲解,敬请关注。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-06-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 开发架构二三事 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. Netty 接受客户的线程(boss线程)和处理IO的线程(worker线程)分别设置,其中:
  • 2. ServerBootStrap的bind方法,主要做select、绑定端口和注册事件三件事。
  • 3. ServerBootStrap的bind方法每调用一次就会绑定一个端口,也会使用一个boss线程,这就是为什么boss线程也要设置成线程池的原因。
  • 4. NIO 中,如果一个客户端进程退出,为什么会触发服务器的OP_READ事件?
  • 5. 为什么nettyServer端的流控配置都是硬编码了? 而NettyClient 端可以自定义配置呢?
  • 6. epoll 的两种工作模式:水平触发(LT) 和 边缘触发(ET)
  • 7. 附录
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档