CTS 网络通信模块 - Netty Handler的使用

本文介绍了如何在Netty中创建自定义Handler以及自定义Pipeline工厂。重点在于业务逻辑,当需要改变实现时,只需替换Pipeline中的Handler,保持系统的可维护性和效率。同时,注意如果需要定制帧解码器,需谨慎实现ByteToMessageDecoder,确保检查缓冲区中有足够的字节来完成一个完整的帧。必须使用reader index以避免假设帧从缓冲区开始。
摘要由CSDN通过智能技术生成
最近在开发一个软件测试服务平台,底层网络通信部分以前是使用JMX,现在换成TCP通信,使用Netty4,监听在一个指定端口上,支持Http/Telnet访问,模块之间使用ProtoBuf进行信息交互。这里记录了一下在开发过程中涉及到的Netty Handler相关的一些技术点。


Based on Nicholas's blog at http://www.znetdevelopment.com/blogs/2009/04/21/netty-using-handlers/ and made some minor changes for Netty 4.


Before I start, let me say that I am in no way affiliated with JBoss or Netty (although I may choose to submit future code as part of the open source community).  Therefore, all comments, code samples, etc are mine or a derivative of examples provided by Netty.   I apologize up front for any possible discrepancies or errors (please let me know though, so I can fix and update them).  I believe this documentation to be completely accurate, though.


In Netty, the main injection point into your code or business logic is through the use of handlers.  Handlers follow the interceptor pattern similar to filters in a traditional servlet-based web application.  For more information, see Netty documentation.  Handlers provide an event model that allows an application to monitor incoming/outgoing data, modify the data, convert the data, act upon the data, etc.  In essence, they allow you to completely abstract separate concerns into separate classes without needing to have class A know about class B.  As an example, you can add a log handler to listen for incoming data and print it out.  This handler can be added and removed without modifying any other class.  Handlers, however, are more often used to build protocol stacks in which one filter acts as a codec to decode/encode a stream of bytes into higher level objects which are then acted upon by another handler such as a business logic handler.


Channel handlers in Netty start from a channel pipeline.  Handlers are added to the pipeline in a specific order.  The order determines how and when the handlers are invoked.  Thus, if you have a handler that depends on another handler (a codec for instance), you need to make sure that the codec handler comes before in the pipeline.  **As data enters the system, often times asynchronously, the data is wrapped in a channel buffer object in Netty that provides zero copy transparency and higher level access methods.  The object is then flowed from the first handler downstream to the last handler (unless a handler chooses to break the flow or an exception is thrown).  If any write events occur (typically by the last handler), then the data flows upstream from the last handler to the first handler.**  A better diagram of this is available in the channel pipeline API documentation.  This is why order is important to ensure that the handlers get invoked at the proper time.


Channel handlers come in two flavors with one of two (or both) responsibilities.  First, they are either stateful or stateless.  Second, they are either upstream, downstream, or both.  For stateness, a handler can choose to maintain a state inside its class or choose to do all its logic in its event callback method(s).  This choice is critical to the application, however.  **A new pipeline is created for each and every incoming connection**.  Thus, if you add a handler to a pipeline factory and re-use that same handler for each pipeline instance, then multiple asynchronous worker threads can be simultaneously accessing data in the handler.   If you maintain state in your handler, this can quickly become an issue.  The default pipeline factory in Netty actually works this way by re-using handlers.  The opposite side of this is that if you choose to create a new handler every time, you reduce performance and increase memory/garbage collection.  Thus, you need to decide right away how each and every handler will be used.  If a handler is stateless, has no instance variables, and can act as a singleton, then you should re-use that particular handler within the pipeline factory.  If a handler is stateful, such as a frame or codec decoder, then you should create a new instance with every pipeline.  Note that you could also choose to use a singleton instance of a stateful handler and synchronize the methods.  However, I would be hesitant to try that method as you will reduce overall throughput when thousands of connections all try to access the same data.  **In most situations, especially on server class machines, you are b
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值