日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

关于Netty的一些理解、实践与陷阱

發布時間:2025/3/20 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 关于Netty的一些理解、实践与陷阱 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

核心概念的理解

Netty對于網絡層進行了自己的抽象,用Channel表示連接,讀寫就是Channel上發生的事件,ChannelHandler用來處理這些事件,ChannelPipeline基于unix哲學提供了一種優雅的組織ChannelHandler的方式,用管道解耦不同層面的處理。現在回過頭來看看,真的是非常天才和優雅的設計,是我心中API設計的典范之一了。

TCP半包、粘包

使用Netty內置的LineBasedFrameDecoder或者LengthFieldBasedFrameDecoder,我們只要在pipeline中添加,就解決了這個問題。

Writtable問題

有時候,由于TCP的send buffer滿了,向channel的寫入會失敗。我們需要檢查channel().isWritable()標記來確定是否執行寫入。

處理耗時任務

Netty In Action以及網上的一些資料中,都沒有很直接的展示如何在Netty中去處理耗時任務。其實也很簡單,只要給handler指定一個事件循環就可以,例如

public class MyChannelInitializer extends ChannelInitializer<Channel> {private static EventExecutorGroup longTaskGroup = new DefaultEventExecutorGroup(5);protected void initChannel(Channel channel) throws Exception {ChannelPipeline pipeline = channel.pipeline();...pipeline.addLast(longTaskGroup, new PrintHandler());} }復制代碼

Pitfall

Netty的ChannelPipeline只有一條雙向鏈,消息入站,經過一串InBoundHandler之后,以相反的順序再經過OutBoundHandler出站.因此,我們自定義的handler一般會處于pipeline的末尾!

舉個例子,當以如下順序添加handler時,如果調用ChannelHandlerContext上的writeAndFlush方法,出站消息是無法經過StringEncoder的

public class MyChannelInitializer extends ChannelInitializer<Channel> {private static EventExecutorGroup longTaskGroup = new DefaultEventExecutorGroup(5);protected void initChannel(Channel channel) throws Exception {ChannelPipeline pipeline = channel.pipeline();pipeline.addLast(new LineBasedFrameDecoder(64 * 1024));pipeline.addLast(new StringDecoder(CharsetUtil.UTF_8));pipeline.addLast(longTaskGroup, new PrintHandler());pipeline.addLast(new StringEncoder(CharsetUtil.UTF_8));} }復制代碼

這個問題有兩個解決方式

  • 調整handler的順序
  • 調用channel上的writeAndFlush方法,強制使消息在整個pipeline上流動
  • 調整handler的順序

    public class MyChannelInitializer extends ChannelInitializer<Channel> {private static EventExecutorGroup longTaskGroup = new DefaultEventExecutorGroup(5);protected void initChannel(Channel channel) throws Exception {ChannelPipeline pipeline = channel.pipeline();pipeline.addLast(new LineBasedFrameDecoder(64 * 1024));pipeline.addLast(new StringDecoder(CharsetUtil.UTF_8));pipeline.addLast(new StringEncoder(CharsetUtil.UTF_8));pipeline.addLast(longTaskGroup, new PrintHandler());} }復制代碼

    調用Channel上的writeAndFlush方法

    public class PrintHandler extends SimpleChannelInboundHandler<String> {protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception { // ctx.writeAndFlush(msg);ctx.channel().writeAndFlush(msg);System.out.println(msg);} }復制代碼

    參考

    www.voidcn.com/article/p-y…
    stackoverflow.com/questions/3…
    《Netty In Action》

    與50位技術專家面對面20年技術見證,附贈技術全景圖

    總結

    以上是生活随笔為你收集整理的关于Netty的一些理解、实践与陷阱的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。