1.一、Netty简介与IO模型
2.nettyç³»åä¹:å¨nettyä¸ä½¿ç¨nativeä¼ è¾åè®®
3.上为什么没人用t-io?
4.Nettyåç-ä»NIOå¼å§
一、Netty简介与IO模型
Netty,一个异步事件驱动的网络应用程序框架,专注于高效、可维护的悬赏任务app原生源码网络应用开发。由官方描述可知,Netty适用于快速构建高性能服务器和客户端,尤其擅长处理并发量极高的场景。
然而,许多人疑惑:既然有 Tomcat 这样功能丰富的 Servlet 容器支持 NIO(非阻塞 I/O)模式,为何还要采用 Netty?实际上,Netty 的防吾爱源码灵活性在于其对协议的自定义能力。尽管 Tomcat 能胜任 HTTP 协议服务,但 Netty 更加强大,可实现任何协议的编码和解码,使其成为网络应用程序框架的理想选择。
在讨论 IO 模型时,理解“阻塞式 IO”(等待操作完成才返回)、推荐平台源码“非阻塞式 IO”(频繁轮询以检查是否可执行)及“信号驱动 IO”(接收到信号时进行操作,同时保持阻塞状态直至数据复制到用户空间)等不同模型,显得尤为重要。以“阻塞式 IO”为起点,通过“非阻塞式 IO”简化轮询负担,然后“信号驱动 IO”利用信号通知来减少阻塞时间,追元素源码“IO 多路复用”能同时处理多个文件描述符的就绪状态,最后,“异步 IO”实现完全的非阻塞操作。
同步与异步通信的差异体现在主动等待结果上:同步通信需程序主动阻塞直至结果出现,而异步通信在发出调用后立刻返回,结果由调用者接收。黑客攻防源码关于阻塞与非阻塞的区别,则聚焦于程序在等待结果时的状态,阻塞调用意味着在结果返回前,当前线程处于等待状态;而非阻塞调用允许程序在无结果可得时继续执行其他任务。
综上所述,Netty 作为网络编程的强大工具,结合 IO 模型及通信方式的理解,能够有效地提升开发效率与系统性能,尤其在高度并发和协议自定义的场景下展现其独特优势。
nettyç³»åä¹:å¨nettyä¸ä½¿ç¨nativeä¼ è¾åè®®
ç®ä»
对äºIOæ¥è¯´ï¼é¤äºä¼ ç»çblock IO,使ç¨æå¤çå°±æ¯NIOäºï¼é常æ们å¨Nettyç¨åºä¸æ常ç¨å°çå°±æ¯NIO,æ¯å¦NioEventLoopGroup,NioServerSocketChannelçã
æ们ä¹ç¥éå¨IOä¸ææ¯NIOæ´å¿«çIOæ¹å¼ï¼æ¯å¦kqueueåepollï¼ä½æ¯è¿ä¸¤ç§æ¹å¼éè¦nativeæ¹æ³çæ¯æï¼ä¹å°±æ¯è¯´éè¦å¨æä½ç³»ç»å±é¢æä¾æå¡ã
å¦ææ们å¨æ¯æKqueueæè epollçæå¡å¨ä¸ï¼nettyæ¯å¦å¯ä»¥æä¾å¯¹è¿äºä¼ç§IOçæ¯æå¢ï¼
çæ¡æ¯è¯å®çãä½æ¯é¦å kqueueåepolléè¦JNIæ¯æï¼ä¹å°±æ¯è¯´JAVAç¨åºéè¦è°ç¨æ¬å°çnativeæ¹æ³ã
nativeä¼ è¾åè®®çä¾èµè¦æ³ä½¿ç¨kequeueåepollè¿ç§nativeçä¼ è¾æ¹å¼ï¼æ们éè¦é¢å¤æ·»å 项ç®çä¾èµ,å¦ææ¯linuxç¯å¢ï¼åå¯ä»¥æ·»å å¦ä¸çmavenä¾èµç¯å¢ï¼
<dependencies><dependency><groupId>io.netty</groupId><artifactId>netty-transport-native-epoll</artifactId><version>${ project.version}</version><classifier>linux-x_</classifier></dependency>...</dependencies>å ¶ä¸versionéè¦å¹é ä½ æ使ç¨çnettyçæ¬å·ï¼å¦åå¯è½åºç°è°ç¨å¼å¸¸çæ åµã
classifier表示çæ¯ç³»ç»æ¶æï¼å®çå¼å¯ä»¥æ¯linux-x_ï¼ä¹å¯ä»¥æ¯linux-aarch_.
å¦æä½ ä½¿ç¨çmacç³»ç»ï¼é£ä¹å¯ä»¥è¿æ ·å¼å ¥ï¼
<dependencies><dependency><groupId>io.netty</groupId><artifactId>netty-transport-native-kqueue</artifactId><version>${ project.version}</version><classifier>osx-x_</classifier></dependency>...</dependencies>nettyé¤äºåç¬ç个ä½å ä¹å¤ï¼è¿æä¸ä¸ªall in oneçnetty-allå ï¼å¦æä½ ä½¿ç¨äºè¿ä¸ªall in oneçå ï¼é£ä¹ä¸éè¦é¢å¤æ·»å nativeçä¾èµã
å¦ænettyæä¾çç³»ç»æ¶æ并没æä½ æ£å¨ä½¿ç¨çï¼é£ä¹ä½ éè¦æå¨è¿è¡ç¼è¯ï¼ä»¥ä¸æ¯ç¼è¯æä¾èµçç¨åºå , å¦ææ¯å¨RHEL/CentOS/Fedoraç³»ç»ä¸ï¼å使ç¨ï¼
sudo yum install autoconf automake libtool make tar \ glibc-devel \ libgcc.i glibc-devel.iå¦ææ¯å¨Debian/Ubuntuç³»ç»ä¸ï¼å使ç¨ï¼
sudo apt-get install autoconf automake libtool make tar \ gccå¦ææ¯å¨MacOS/BSDç³»ç»ä¸ï¼å使ç¨ï¼
brew install autoconf automake libtoolnettyæ¬å°ä¼ è¾åè®®ç使ç¨å®è£ 好ä¾èµå ä¹åï¼æ们就å¯ä»¥å¨nettyä¸ä½¿ç¨è¿äºnativeä¼ è¾åè®®äºã
nativeä¼ è¾åè®®ç使ç¨åNIOç使ç¨åºæ¬ä¸è´ï¼æ们åªéè¦è¿è¡ä¸é¢çæ¿æ¢å³å¯ã
å¦ææ¯å¨liunxç³»ç»ä¸ï¼åè¿è¡ä¸é¢çæ¿æ¢ï¼
NioEventLoopGroup â EpollEventLoopGroupNioEventLoop â EpollEventLoopNioServerSocketChannel â EpollServerSocketChannelNioSocketChannel â EpollSocketChannelå¦ææ¯å¨macç³»ç»ä¸ï¼åè¿è¡ä¸é¢çæ¿æ¢ï¼
NioEventLoopGroup â KQueueEventLoopGroupNioEventLoop â KQueueEventLoopNioServerSocketChannel â KQueueServerSocketChannelNioSocketChannel â KQueueSocketChannelè¿éè¿æ¯ä½¿ç¨æ们çæçè天æå¡ä¸ºä¾ï¼é¦å çä¸åºäºKqueueçnettyæå¡å¨ç«¯åºè¯¥æä¹åï¼
EventLoopGroup bossGroup = new KQueueEventLoopGroup(1);EventLoopGroup workerGroup = new KQueueEventLoopGroup();try { ServerBootstrap b = new ServerBootstrap();b.group(bossGroup, workerGroup) .channel(KQueueServerSocketChannel.class) .handler(new LoggingHandler(LogLevel.INFO)) .childHandler(new NativeChatServerInitializer());Channel channel = b.bind(PORT).sync().channel();log.info("server channel:{ }", channel);channel.closeFuture().sync();åNIOä¸æ ·ï¼å¨æå¡å¨ç«¯æ们éè¦ä½¿ç¨KQueueEventLoopGroupå建两个EventLoopGroupï¼ä¸ä¸ªæ¯bossGroup, ä¸ä¸ªæ¯workerGroupã
ç¶åå°è¿ä¸¤ä¸ªgroupä¼ å ¥å°ServerBootstrapä¸ï¼å¹¶ä¸æ·»å KQueueServerSocketChannelä½ä¸ºchannelã
å ¶ä»çå 容åNIO serverçå 容æ¯ä¸æ ·çã
æ¥ä¸æ¥æ们çä¸åºäºKqueueçnetty客æ·ç«¯æ¹å¦ä½è·server端建ç«è¿æ¥ï¼
EventLoopGroup group = new KQueueEventLoopGroup();try { Bootstrap b = new Bootstrap();b.group(group) .channel(KQueueSocketChannel.class) .handler(new NativeChatClientInitializer());// 建ç«è¿æ¥Channel ch = b.connect(HOST, PORT).sync().channel();log.info("client channel: { }", ch);è¿é使ç¨çæ¯KQueueEventLoopGroupï¼å¹¶å°KQueueEventLoopGroupæ¾å°Bootstrapä¸ï¼å¹¶ä¸ä¸ºBootstrapæä¾äºåserver端ä¸è´çKQueueSocketChannelã
ç¶åå°±æ¯å®¢æ·ç«¯åchannelä¸åæ¶æ¯ï¼è¿éæ们ç´æ¥ä»å½ä»¤è¡è¾å ¥ï¼
// ä»å½ä»¤è¡è¾å ¥ChannelFuture lastWriteFuture = null;BufferedReader in = new BufferedReader(new InputStreamReader(System.in));for (;;) { String line = in.readLine();if (line == null) { break;}// å°ä»å½ä»¤è¡è¾å ¥çä¸è¡å符åå°channelä¸lastWriteFuture = ch.writeAndFlush(line + "\r\n");// å¦æè¾å ¥'åè§'ï¼åçå¾ serverç«¯å ³échannelif ("åè§".equalsIgnoreCase(line)) { ch.closeFuture().sync();break;}}ä¸é¢ä»£ç çæææ¯å°å½ä»¤è¡æ¶å°çæ¶æ¯åå ¥å°channelä¸ï¼å¦æè¾å ¥çæ¯âåè§âï¼åå ³échannelã
为äºè½å¤å¤çå符串ï¼è¿éç¨å°äºä¸ä¸ªç¼ç 解ç å¨ï¼
<dependencies><dependency><groupId>io.netty</groupId><artifactId>netty-transport-native-kqueue</artifactId><version>${ project.version}</version><classifier>osx-x_</classifier></dependency>...</dependencies>0åå«æ¯è¡åå²å¨ï¼å符ç¼ç å¨åå符解ç å¨ã
è¿è¡ä¸ä¸çï¼ç¨åºè¿è¡æ²¡é®é¢ï¼å®¢æ·ç«¯åæå¡å¨ç«¯å¯ä»¥è¿è¡é讯ã
æ»ç»è¿éæ们åªä»¥Kqueue为ä¾ä»ç»äºnettyä¸nativeä¼ è¾åè®®ç使ç¨ï¼å ·ä½ç代ç ï¼å¤§å®¶å¯ä»¥åèï¼
learn-netty4
æ´å¤å 容请åè?/post/
上为什么没人用t-io?
t-io在质量设计上表现不错,但作者的自大态度令人不满,将其与netty相比时,似乎忽视了netty在业界的广泛认可与深厚底蕴。
t-io的推崇者持有极端信仰,认为其他IO框架都不如t-io,这种观点明显过于偏激。
t-io的文档需要改进,目前存在付费问题,同时其源码注释不足且缺乏关键点解析,这在一定程度上降低了用户的使用体验。
对于netty这类主流框架的批评,似乎忽略了它们在不同场景下的适用性和强大功能,同时也质疑其他IO框架的存在价值,这观点看似武断。
为了避免被这类偏执者的打扰,我选择匿名回复。
Nettyåç-ä»NIOå¼å§
Nettyæ¯åºäºNIOçå¼æ¥éä¿¡æ¡æ¶ï¼æ¾ç»å¼å ¥è¿AIOï¼åæ¥æ¾å¼ï¼ï¼æ è¦è¯´Nettyåçæ们è¦å ä»NIOå¼å§ã
NIO æ¯JAVAå¨JDK4ä¸å¼å ¥çåæ¥éé»å¡é信模åï¼å¨NIOåºç°ä¹åï¼JDK4ä¹åï¼å¸åºä¸åªæä¸ä¸ªBIO模å顾åæä¹BLOCKING IO ï¼åæ¥é»å¡é信模åï¼
BIOï¼BLOCKING I/Oï¼ï¼
BIO 为ä¸ä¸ªè¿æ¥ ä¸ä¸ªçº¿ç¨ç模å¼ï¼å½æè¿æ¥æ¶æå¡å¨ä¼å¼å¯ä¸ä¸ªçº¿ç¨æ¥å¤ç请æ±
è¥æ¤è¯·æ±å¥é½ä¸æ³å¹²æ¤æ¶çº¿ç¨ä¼æä¹æ ·ï¼
æ¤çº¿ç¨ä¼è¿å ¥é»å¡æ¨¡å¼ï¼BLOCKINGï¼ï¼---å¥ä¹ä¸å¹²ï¼å¹²ççzzZZ~
è¿ç§ä¸è¿æ¥ï¼ä¸çº¿ç¨ç模å¼ä¼é ææå¡å¨èµæºä¸å¿ è¦çå¼é并ä¸å¨å¤§éè¿æ¥è®¿é®æ¶ æå¡å¨ä¼åçä»ä¹ï¼è½¦éï¼çº¿ç¨ï¼ä¸è¶³ï¼è½¦å¤ªå¤--æå µè½¦äº
ç±æ¤å°±åºç°äºNIO
â
NIOï¼new/NONBLOCKING I/Oï¼:
NIO为åæ¥éé»å¡é信模åï¼Selectï¼å¤è·¯å¤ç¨å¨ï¼ä¸ºæ¤æ¨¡åçæ ¸å¿ï¼å®ç°äºå¤ä¸ªè¿æ¥ä¸ä¸ªçº¿ç¨
å½æ客æ·ç«¯è¿æ¥è¯·æ±æ¶ æ¤è¿æ¥è¯·æ±ä¼è¢«æ³¨åè³selectä¸ï¼å½selectæ£æµå°æ¤è¿æ¥æI/O请æ±æ¶æä¼æå¼ä¸ä¸ªçº¿ç¨å»å¯¹æ¤I/O请æ±è¿è¡å¤ç-----å线ç¨æ¨¡å
è¿ä¸ªæ¶åæ人é®äºï¼è¿ä¹å¤æä½é½å¨ä¸ä¸ªçº¿ç¨éï¼çº¿ç¨å¿ä¸è¿æ¥æä¹åï¼
æ¤æ¶ ç±äºç½ç»è¯·æ±ãI/O读åãä¸å¡æä½é½å¨ä¸ä¸ªçº¿ç¨ä¸ï¼ä¼å¯¼è´å¨é«å¹¶åçæ åµä¸åå¨æ§è½ç¶é¢ äºæ¯ä¹æ人就æåºæ¥ å°ä¸å¡æä½ä¸¢å°å¦ä¸ä¸ªçº¿ç¨æä¹æ ·ï¼
äºæ¯åºç°äºç¬¬ä¸ç§reactor模å-使ç¨çº¿ç¨æ± è¿è¡æä½ç½ç»è¯·æ±ãIOå¨ä¸ä¸ªçº¿ç¨ï¼ä¸å¡æä½å¨å¦ä¸ªä¸ä¸ªçº¿ç¨ çä¸å¡å离----线ç¨æ± 模å
ä»æ¤å¾ä¸å¯ä»¥çåºæ¤æ¶ 模åä¸ä½¿ç¨ä¸ä¸ªçº¿ç¨æ± æ¥è¿è¡ç½ç»è¯·æ±ãIO读å
å½è¯»åå®æåå°ä¸å¡æä½ç»å®å¨çº¿ç¨æ± ä¸å¦å¤ç线ç¨ä¸-------ç½ç»IOä¸ä¸å¡æä½å¯ä»¥åæ¥è¿è¡äºï¼ä¸åé½å®ç¾äºèµ·æ¥ï¼
ä½æ¯ï¼äºæ è¿æ²¡å®ï¼ï¼è¿ä¸ªæ¶ååæ人æåºé®é¢ï¼å¨é«å¹¶åçæ¶åååï¼ä¼ä¸ä¼ææ§è½ç¶é¢
å 为ç½ç»IOæ¯é常æ¶èCPUçï¼å½ç½ç»è¯·æ±ä¸ç½ç»IOå¨å个线ç¨ä¸æ¶ï¼é CKçæ åµä¸å个线ç¨å¹¶ä¸è¶³ä»¥æ¯æèµ·ææçIOæä½ï¼å æ¤ä¹å½¢æäºå¨é«å¹¶åç¶æä¸çæ§è½ç¶é¢
äºæ¯å¤§ä½¬ä»¬å°±æ³çï¼å¦ææIOæåºæ¥è®©å个线ç¨æ± å»æ¥æ¶ç½ç»è¯·æ±ï¼ç¨å¦ä¸ä¸ªçº¿ç¨æ± æ¥è¿è¡IOä¸ä¸å¡æä½ä¼ä¸ä¼æ´å¥½
äºæ¯ç¬¬åç§Reactor模ååºè¿èç--主ä»Reactorå¤çº¿ç¨æ¨¡å
æ¤æ¨¡åä¸ mainReactoråªç¨äºæ¥æ¶ç½ç»è¯·æ±ï¼èsubReactorä¸ä¸ºä¸ä¸ªçº¿ç¨æ± ï¼çº¿ç¨æ± ä¸æ¯ä¸ªçº¿ç¨ä¸ç»å®ä¸ä¸ªselect
å½mainReactoræ¥æ¶å°è¯·æ±æ¶ï¼ä¸ä¸ªæè¿°ç¬¦ï¼ ç³»ç»ä¼çæä¸ä¸ªæ°çæ述符代表æ¤è¿æ¥çæï¼æ¤æ¶mainReactorä¼å°æ°çæ述符éè¿ä¸ä¸ªç®æ³å¨çº¿ç¨æ± ä¸éå®ä¸ä¸ªçº¿ç¨ å°æ¤æ述符ç»å®è³æ¤çº¿ç¨æ± ä¸çselectä¸ï¼ç±æ¤çº¿ç¨æ¥å¯¹è¯·æ±è¿è¡I/O ä¸ä¸å¡æä½
ä»æ¤ç¾ä¸è¿æ¥é«å¹¶åä¸æ¯é®é¢
åå°è¿ æ们æ¯ä¸æ¯æ³èµ·äºNettyçå¯å¨è¿ç¨
1ã声æ两个EventLoopGroupä¸ä¸ªä¸ºbossï¼mainReactorï¼ä¸ä¸ªä¸ºworkerï¼subReactorï¼
EventLoopGroupï¼çº¿ç¨æ± ï¼åå§åçæ¶åä¼çæï¼æå è½½ï¼æå®æ°éçEventLoopï¼çº¿ç¨ï¼è¥æ æå® åä¼çæCPUæ°X2ç线ç¨
2ã声æä¸ä¸ªå¯å¨è¾ å©ç±»Bootstrap并å°EventLoopGroup注åå°å¯å¨è¾ å©ç±»BootStrapä¸(bootStrap.group)
æ¥çåç»bootstrapæå®channel模åçå±æ§ï¼åæ·»å ä¸ä¸å¡æµæ°´çº¿ï¼channelpipelineï¼å¹¶ä¸å¨pipelineä¸æ·»å ä¸ä¸å¡æä½handlerï¼ï¼éè¿channelpipelineå¯ä»¥å¯¹ä¼ å ¥æ°æ®ä¸ºæ欲为ï¼
3ãç»å®ç«¯å£
Nettyå¯å¨å®æ
è¿æ¶åå¯è½æ人ä¼é®äºï¼è¿åä½ ä¸é¢è¯´çreactorï¼NIOæå¥å ³ç³»ï¼
è¿ä¸ªæ¶åæ们è¦è¿ä¹ç
â
è¥æ们å°bossä¸worker线ç¨æ± 设置为ç¸åçä¸ä¸ªçº¿ç¨æ± ï¼é£ä¹ä¼åçä»ä¹äºï¼
æ¤æ¶å ³æ³¨ä¸ä¸ç¬¬ä¸ä¸ªReactor模åæ¶å°±ä¼åç° å½BOSS=WORKERæ¶å nettyå®ç°çå°±æ¯ç¬¬ä¸ç§Reactor模å 使ç¨çº¿ç¨æ± 模å
èå½bossä¸çäºworkerçæ¶å使ç¨çå°±æ¯ç¬¬åç§ ä¸»ä»å¤çº¿ç¨æ¨¡å
Nettyå°±æ¯åºäºReactor模åæ¥å¯¹NIOè¿è¡äºæç¨åå°è£ ï¼ä»Nettyæºç ä¸å°±å¯ä»¥çåºæ¥å ¶å®åºå±è¿é½æ¯NIOçæ¥å£
æ¤æ¬¡å¤ä¸ºèªå·±è¯»æºç ä¹åçç解 å¦æ误请ææ£
ææ©
åææ¿ä¸ç¬¬ä¸ä¸ªèµ