注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

小葫芦君(汉斯的博客)

博客迁移到新博客:https://blog.ssxingshou.com

 
 
 

日志

 
 
关于我

小小葫芦商城,为您提供高品质的商品,一流的产品,一流的包装服务,一流的物流服务,放心购买

网易考拉推荐

Netty 4.0 新的特性及需要注意的地方 2  

2014-04-11 21:51:29|  分类: 默认分类 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

Channel API的变化

在4.0中,许多io.netty.channel包中的类都经历大量修改,因此文本上的简单搜索-替换是无法让你基于3.x的程序迁移到4.0上。这个部分会尝试将这些重大变更背后的思考过程展示出来,而不只是简单地作为展示所有变更。

翻新后的ChannelHandler接口

Upstream → Inbound, Downstream → Outbound

对于初学者来说,术语'upstream'(译者注:直译为向上游,有点像TCP/IP协议栈中从下往上,从物理层最终到达应用层这么一个流程)和'downstream'有点让人迷惑。在4.0中,只要可能,都会使用'inbound'(译者注:直译为开往内地的,相对于upstream确实更贴切,即指数据从外部网络经历层层filter到达我们的处理逻辑)和'outbound'来替换他们。

新的ChannelHandler继承层次

在3.x时代,ChannelHandler只是一个标记接口,而在ChannelUpstreamHandler、ChannelDownstreamHandler、LifeCycleAwareChannelHandler定义了具体的处理器方法。在Netty 4中,ChannelHandler将LifeCycleAwareChannelHandler接口和一堆实现辅助方法融合到了一起,具体见代码:

01public interface ChannelHandler {
02  
03    void beforeAdd(ChannelHandlerContext ctx) throws Exception;
04    void afterAdd(ChannelHandlerContext ctx) throws Exception;
05    void beforeRemove(ChannelHandlerContext ctx) throws Exception;
06    void afterRemove(ChannelHandlerContext ctx) throws Exception;
07  
08    void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throwsException;
09    void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception;
10    ...
11}

下方的图表描述了这个新的类型集成层次:

fixme(原文中还没有插入此图)

事件对象从ChannelHandler中消失了

在3.x时代,所有的I/O操作都会创建一个新的ChannelEvent对象。对每个读或写的操作,还会额外创建一个新的ChannelBuffer对象。由于将资源管理和buffer的池化交给了JVM,这实际上极大地简化了Netty的内部实现。但是,基于Netty开发的应用在高负载下运行时,有时会观察到GC(Garbage Collection)的压力增大或变化不定,这些问题的根源也来自于这里。

4.0通过把事件对象替换为直接与类型相对应(译者注:原文为strongly typed,但是我觉得直译为强类型不太容易理解)的方法调用,几乎完全避免了事件对象的创建。3.x中,有类似于handleUpstream()和handleDownstream()这种能够捕获所有相关类型事件的处理器方法,4.0中你将不会再看到它们的身影了。所有的事件类型现在都有各自对应的处理器方法:

01// 3.x时代:
02void handleUpstream(ChannelHandlerContext ctx, ChannelEvent e) throws Exception;
03void handleDownstream(ChannelHandlerContext ctx, ChannelEvent e) throws Exception;
04  
05// 4.0:
06void channelRegistered(ChannelHandlerContext ctx) throws Exception;
07void channelUnregistered(ChannelHandlerContext ctx) throws Exception;
08void channelActive(ChannelHandlerContext ctx) throws Exception;
09void channelInactive(ChannelHandlerContext ctx) throws Exception;
10void inboundBufferUpdated(ChannelHandlerContext ctx) throws Exception;
11  
12void bind(ChannelHandlerContext ctx, SocketAddress localAddress, ChannelFuture future) throws Exception;
13void connect(
14        ChannelHandlerContext ctx, SocketAddress remoteAddress,
15        SocketAddress localAddress, ChannelFuture future) throws Exception;
16void disconnect(ChannelHandlerContext ctx, ChannelFuture future) throws Exception;
17void close(ChannelHandlerContext ctx, ChannelFuture future) throws Exception;
18void deregister(ChannelHandlerContext ctx, ChannelFuture future) throws Exception;
19void flush(ChannelHandlerContext ctx, ChannelFuture future) throws Exception;
20void read(ChannelHandlerContext ctx);
21void sendFile(ChannelHandlerContext ctx, FileRegion region, ChannelPromise promise)throws Exception;

ChannelHandlerContext类也被修改来反映上述提到的变化:

1// Before:
2ctx.sendUpstream(evt);
3  
4// After:
5ctx.fireInboundBufferUpdated();

所有这些变化意味着用户无法去扩展ChannelEvent这个已经不存在的接口了。那用户要怎样才能定义他或她自己的事件类型呢,就像IdleStateEvent?4.0中的ChannelHandler有一个处理器方法叫做userEventTriggered(),它就是被设计用来满足这种特殊的用户需求。

Simplified channel state model

在3.x中,当一个新的Channel被创建并连接成功,至少三个ChannelStateEvent会被触发:channelOpen、channelBound以及channelConnected。当一个Channel关闭,则对应channelDisconnected、channelUnbound以及channelClosed三个事件。

fixme

但是,触发这么多事件的意义并不那么明显。如果在一个Channel进入可读或可写的状态时通知用户,想来会更有帮助。

fixme

channelOpen、channelBoundchannelConnected被合并为channelActive。channelDisconnected、channelUnboundchannelClosed被合并为channelInactive。类似的,Channel.isBound()和Channel.isConnected()也被合并为了Channel.isActive()。

需要注意的是,channelRegistered和channelUnregistered这两个事件与channelOpen和channelClosed具有的意义是不一样的。它们(channelRegistered和channelUnregistered)是在支持Channel的动态注册、注销以及再注册时被引入的,就像下图所示:

fixme




  评论这张
 
阅读(490)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017