云自無心水自閑

          天平山上白云泉,云自無心水自閑。何必奔沖山下去,更添波浪向人間!
          posts - 288, comments - 524, trackbacks - 0, articles - 6
            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

          Netty

          Posted on 2014-11-27 07:36 云自無心水自閑 閱讀(9865) 評論(0)  編輯  收藏 所屬分類: Java心得體會
           Netty作為一個異步非阻塞式的框架,是不允許在ChannelHandler中長時間處理事務(比如數據庫的操作),阻塞I/O的讀寫處理的。

          在Netty in Action中是這樣描述的:
          While the I/O thread must not be blocked at all, thus prohibiting any direct blocking operations within your ChannelHandler, there is a way to implement this requirement. 
          You can specify an EventExecutorGroup when adding ChannelHandlers to the ChannelPipeline. 
          This EventExecutorGroup will then be used to obtain an EventExecutor, which will execute all the methods of the ChannelHandler. 
          This EventExecutor will use a different thread from the I/O thread, thus freeing up the EventLoop.
          I/O線程是不允許被阻塞的,也就是不能在ChannelHandler中進行任何阻塞式的處理,但是對此我們也有相應的解決方法.
          就是在把ChannelHanders添加到ChannelPipeline的時候,指定一個EventExecutorGroup,ChannelHandler中所有的方法都將會在這個指定的EventExecutorGroup中運行。
          而這個EVentExecutorGroup運行的線程與I/O線程不同,達到不阻塞I/O的目的。 
          程序示例如下:
          Channel ch = ...;
          ChannelPipeline p = ch.pipeline();
          EventExecutor e1 = new DefaultEventExecutorGroup(16);
          EventExecutor e2 = new DefaultEventExecutorGroup(8);
           
          p.addLast(new MyProtocolCodec());
          p.addLast(e1, new MyDatabaseAccessingHandler());
          p.addLast(e2, new MyHardDiskAccessingHandler());
          需要補充說明一下,上面的示例程序似乎有點問題。使用上述方法添加ChannelHandler到pipeline中以后,channelHandler的所有方法確實什么在一個單獨的線程中被處理。
          但是,每次DefaultEventExcutorGroup線程池中的線程不能被重用,每次都會生成一個新的線程,然后在新的線程中調用ChannelHandler, 在visualvm可以看到線程數量直線增長。

          解決的方法是:不能使用局部變量形式的DefaultEventExecutorGroup。而使用類靜態成員變量:
          static final EventExecutor e1 = new DefaultEventExecutorGroup(16);

          我分析原因可能是:在新的連接到來,創建ChannelPipeline給新Channel的時候,如果不使用靜態的共享變量,而使用局部變量的話,就造成DefaultEventExecutorGroup被多次重復創建。因此,雖然一個DefaultEventExecutorGroup中的Thread數量是固定的,但是卻產生了多余的DefaultEventExecutorGroup。從VisualVM中也可以看到,DefaultEventExecutorGroup線程的名字會是:
          xxx-2-1
          xxx-3-1
          xxx-4-1
          xxx-n-1
          說明是Group的數量(第一個數字)在增多,而不是Group中的線程數量(第二個數字)在增多
          改成靜態變量后,線程名會是:
          xxx-2-1
          xxx-2-2
          xxx-2-3
          xxx-2-n
          最后一個n就是在創建DefaultEventExecutorGroup時候,傳入的線程個數參數的大小。


          主站蜘蛛池模板: 仁怀市| 盖州市| 社会| 陆河县| 中超| 木里| 瑞安市| 岳阳市| 玉环县| 江口县| 张掖市| 二连浩特市| 宜州市| 桦南县| 阿城市| 辰溪县| 普定县| 麻城市| 岗巴县| 聂拉木县| 革吉县| 博白县| 龙岩市| 安图县| 苗栗县| 宜昌市| 磐安县| 昌江| 惠州市| 彰武县| 海淀区| 鹿邑县| 廊坊市| 武平县| 广河县| 平陆县| 焦作市| 南木林县| 且末县| 西乌珠穆沁旗| 营山县|