Netty in Action (二十一) 第十一章节 第一部分 Netty提供的一些原生Handler和codecs

本章内容包括(分2次翻译):

1)利用SSL/TLS构建安全的Netty应用

2)构建HTTP/HTTPS的应用

3)处理闲置的连接和超时

4)空格符切分协议和长度切分的协议的解码

5)写入大数据

Netty为各式各样的协议提供了很多译码器和处理器的类,这些类你可以做到拿来即用,可以使你在有些比较麻烦的事件上不用花费不必要的时间和精力,在这个章节我们将会把这些工具介绍给你,且一一分析他们的作用,这些工具包括:支持SSL/TLS和Websocket的工具,也有比HTTP天然的数据压缩更高性能的数据挤压功能,等等

11.1 Securing Netty applications with SSL/TLS

数据隐私是当代一个比较重要的议题,所以作为开发者的我们应该做好十足的准备去处理这个问题,首先我们必须熟悉一些比较常见的加密协议,例如SSL或者TLS协议,这两种协议处于数据保密协议的最重要的位置,当我们去浏览一些安全性比较高的网站的时候,我们就会接触到这些协议,当然这些协议也是可以用于不是基于HTTP协议的应用中的,例如SMTPS邮件服务中,甚至是相关的数据库系统中

为了支持SSL和TLS,Java提供了javax.net.ssl工具包,这个包里面的SSLContext和SSLEngine可以简单直接地实现加密和解密,Netty利用这个Java实现的API去实现ChannelHandler接口名为SslHandler的类,这个类其实是内部使用SSLEngine来做一些真实的事

TIPS:Netty的OpenSSL/SSLEngine实现

Netty也提供了使用OpenSSL工具类实现的SSLEngine,这个类叫做OpenSslEngine,这个类比原始的JDK提供的SSLEngine有着更好的性能

当OpenSSL的jar包库在提供的情况下,Netty的客户端和服务端默认是使用的OpenSslEngine的,如果没有提供的情况下,将会在使用JDK提供的,更多关于OpenSSL的介绍可以查看Netty的文档

注意到不管你是用JDK实现的还是Netty的OpenSslEngine对于数据传输来说其实是一样的

代码清单展示了一个SslHandler是如何通过一个ChannelInitializer来增加到ChannelPipeline中的,回想一下,一旦Channel被注册ChannelInitializer将会被设置到ChannelPipeline中

在很多的案例中,SslHandler经常是作为ChannelPipeline中的第一个ChannelHandler的,这样可以保证加密的动作是发生在所有的业务逻辑操作之后

SslHandler有一些比较有用的方法,如表11.1所示,具体来说,在握手阶段,两个终端相互验证且达成一个加密方式,你可以配置SslHandler来编辑它的行为或者当SSL/TLS握手完成的时候提供通知,等做完这一切,所有的数据被加密,SSL/TLS的握手将会被自动执行

11.2 Building Netty HTTP/HTTPS applications

HTTP/HTTPS是我们最最常见的协议之一,随着移动手机端的日夜发展,对于任何一家公司来说,有一个支持手机端的网页已经变成了一个必不可少的需求,这些协议也被用在了其他的方面,WebService的API被很多组织暴露出来用来与他们的企业合作伙伴基于Http协议通信

接下来,我们将看见Netty提供的一些相关方面的ChanneHandler,有了这些工具你可以不需要编写自定义的译码器来使用HTTP和HTTPS协议

11.2.1 HTTP decoder, encoder, and codec

HTTP是基于请求响应模式的,客户端发送Http请求到服务器端,服务器端反馈一个HTTP响应,Netty提供了一系列的编码和解码的类来简化对该协议的使用,图11.2和11.3分别展示了完整的HTTP请求体和响应体

如图11.2和11.3展示的一样,一个HTTP请求或者响应包括多个数据组成部分,他们都是以一个LastHttpContent部分作为终止,FullHttpRequest和FullHttpResponse信息是具体的衍生类分别代表了一个完整的请求和响应,所有的实现HttpObject接口的Http信息类型的模型类Request或者LastHttpContent如下列表图11.2和表11.2展示:

表11.2给出了HTTP解码和编码一些常用的类一个总览

下面的代码清单中的HttpPipelineInitializer展示了如何将Netty对HTTP的支持运用到你的应用中去的示例,作为使用者的你几乎只需要将正确的ChannelHandler降入到ChannelPipeline中去就可以了

11.2.2 HTTP message aggregation

当所有的初始化的工作已经将处理器安装到ChannelPipeline中去后,你就可以操作不同类型的HttpObject对象了,但是我们之前讲过一个HTTP请求或者响应是由多个部分组成的,所以你需要将这些信息聚合一下组成一个完整的信息,为了消除这种令人头疼的工作,Netty提供了一个聚合工具可以使多个信息体合并成一个FullHttpRequest或者FullHttpResponse信息体,通过这种方法你就可以总是看见完整的信息内容了

这个聚合操作是有一定的性能损失的,因为到达的信息端需要在缓存区等待直到组装成完整的信息转向到下一个ChannelInboundHandler中,这种折中的好处就是你不需要担心信息破碎的问题

介绍这种自动的聚合只需要做一件事:增加一个ChannelHandler到管道中去就可以了,下面的代码清单展示了如何做:

11.2.3 HTTP compression

当使用HTTP协议的时候,我们推荐使用压缩技术来尽可能的减少传输消息体的大小,尽管压缩会花费CPU的部分性能,但是总而言之,压缩思想是一个不错的主意,特别是在文本传输的时候

Netty提供了ChannelHandler来支持压缩和解压缩,并且支持gzip和deflate两种编码格式

下面的代码清单展示了这个例子:

TIPS:压缩的jar包依赖

如果你使用JDK1.6或者更早的版本,你可能需要增加JZlib包的依赖到你的classpatch下来支持压缩功能,如果使用的是Maven,请使用如下的依赖

11.2.4 Using HTTPS

下面的代码清单展示了如果想要支持HTTPS,只需要增加一个SslHandler到混合的Handler中去就可以了

这个代码很好的展示了Netty的架构理念:可重复利用组件,诚如,你只需要增加一个ChannelHandler到ChannelPipeline中就可以提供一个高性能的且加密的应用了

11.2.5 WebSocket

Netty对基于HTTP协议的应用提供了大量的工具包,使用这些工具包可以支持很多现金的特性,在这个小节中,我们将初探WebSocket,一个由IETF在2011年提出的一个年轻的协议

WebSocket处理了“世纪”的难题,如果基于底层的基础协议HTTP去实时推送信息,HTTP做一个典型的请求响应交互协议原生是不支持这种场景的,虽然AJAX技术做了一些弥补,但是数据流的驱动依旧依赖于客户端,还有一些其他的其他的解决方案,但是到目前为止,这些解决方案都是在一种限制中为客户工作着

WebSocket规范和它具体的实现代表了这个领域更加先进的一次尝试,简而言之,WebSocket提供了一个单独的TCP连接用来进行双向的数据传输,有了WebSocket的API,现在对了数据双向传输有了新的方案,不需要像以前客户端轮询服务器端来获取双向数据传输这种功能了

WebSocket提供了服务器端和客户端一个真实的数据双向交互的技术,这个小节,我们并不会深入WebSocket技术内部去探究实现的更多的细节,但是我们必须意识到一些早期的双向通信是受限于文本数据传输的,现在这种限制将不复存在了,WebSocket可以为任何数据使用,看起来更像一种正常的协议了

图11.4展示了Websocket的设计理念图,在这种设计场景下,那么通信将以普通的HTTP协议为基础,且能升级功能使其有双向数据传输的功能

为了将WebSocket的功能增加到我们的应用中去,我们需要增加恰当的客户端或者服务器端的ChannelHandler到管道中去,这个类是专门用来处理WebSocket定义的一些特殊类型的信息,比我们我们熟知的frames,如表11.3所示,WebSocket可以被分类为数据或者控制帧

因为Netty原则上是服务器端的技术,所以我们偏向于创建一个WebSocket服务器,代码清单11.6向我们展示了使用WebSocketServerProtocolHandler构建一个简单的示例,这个类处理了协议,升级了握手阶段的处理,也使用了三个控制帧,Close,Ping,Pong,文本和字节的数据帧将通过此handler会随着管道传输到下一个handler中

TIPS:安全的WebSocket

为了增加WebSocket的安全性,我们只需将SslHandler当做第一个ChannelHandler增加到管道中就可以了

关于WebSocket的更多例子,详细请参考第十二章的内容,该章节的内容将会深入讲解一个实时webSocket应用的设计

11.3 Idle connections and timeouts

到目前为止,我们已经讲解了Netty通过给以几个具体的代码和处理类来提供对HTTP,HTTPS,Websocket的支持,这些技术可以使你的应用更加的高效,安全,利用率变得更高,并且可以更加高效地管理你的应用资源,所以,我们现在来聊聊一个比较核心的概念-------连接管理

检测空置的连接和超时对于及时的释放资源是至关重要的,对于这个重要而又普通的任务,Netty提供了几个具体的ChannelHandler实现来实现这方面的功能,表11.4给出了这个类的总览:

我们详细地说明一下IdleStateHandler,这是在实际项目里使用最频繁的类,代码清单11.7展示了当在60秒内没有数据接收或者发送的时候获取到一个通知的案例,使用一个比较大众的解决方案发送一个心跳包到远程端,如果没有响应,那么则把连接关闭

这个例子说明了如何雇佣一个IdleStateHandler来测试远程端是否还存活,如果远程端没有存活那么可以通过关闭资源来释放资源,IdleStateHandler以IdleStateEvent为入参如果连接在60秒内没有接受或者发送数据的时候调用userEventTriggered方法,HeartbeatHandler方法具体实现了userEventTriggered方法,这个方法会检测IdleStateEvent,这个事件会发送一个心跳信息,且增加了一个ChannelFutureListener当发送心跳包失败的情况下来关闭连接

时间: 2024-09-30 00:04:10

Netty in Action (二十一) 第十一章节 第一部分 Netty提供的一些原生Handler和codecs的相关文章

Netty in Action (二十二) 第十一章节 第二部分 Netty提供的一些原生Handler和codecs

11.4 Decoding delimited and length-based protocols 如果你使用Netty工作的时候,你经常会遇到使用分隔符或者指定字节数的方法来解码,接下来的一个小节中将讲解Netty在处理这种问题给出的一些具体实现 11.4.1 Delimited protocols 分隔符协议使用某个固定的字符来标记一个信息或者一个信息端的开头和结尾,被分割的消息块我们称之为"帧",由RFC文档定义的有很多正式的规范协议,例如SMTP,POP3,IMAP,Teln

《Netty In Action中文版》第二章:第一个Netty程序

注:本篇内容出自<Netty In Action>一书:         注:本人原创译文,转载请注明出处! 本章介绍 获取Netty4最新版本 设置运行环境来构建和运行netty程序 创建一个基于Netty的服务器和客户端 拦截和处理异常 编写和运行Netty服务器和客户端 本章将简单介绍Netty的核心概念,这个狠心概念就是学习Netty是如何拦截和处理异常,对于刚开始学习netty的读者,利用netty的异常拦截机制来调试程序问题很有帮助.本章还会介绍其他一些核心概念,如服务器和客户端的

Netty In Action中国版 - 第二章:第一Netty程序

本章介绍 获得Netty4最新的版本号 设置执行环境,以构建和执行netty程序 创建一个基于Netty的server和client 拦截和处理异常 编制和执行Nettyserver和client 本章将简介Netty的核心概念,这个狠心概念就是学习Netty是怎样拦截和处理异常.对于刚開始学习netty的读者.利用netty的异常拦截机制来调试程序问题非常有帮助.本章还会介绍其它一些核心概念.如server和client的启动以及分离通道的处理程序.本章学习一些基础以便后面章节的深入学习. 本

Netty in Action (十二) 第五章节 第一部分 简介ByteBuf

第五章 ByteBuf(分四部分翻译) 本章节包括: 1)ByteBuf------Netty的数据容器 2)API介绍 3)使用案例 4)内存分配 我们之前提到过很多次,网络传输数据的最基本的数据单元是byte,Java的NIO提供了ByteBuffer作为字节的容器,但是这个类的使用有些过于复杂和麻烦 Netty对ByteBuffer提供了一个可选方案ByteBuf,一个很好的解决方案,解决了JDK原生的ByteBuffer的API使用不易的问题,同时ByteBuf为应用程序开发者提供了一系

Netty in Action (十五) 第六章节 第一部分 ChannelHandler和ChannelPipeline

本章内容包括: 1)ChannelHandler和ChannelPipeline的APIs 2)检测内存泄漏 3)异常处理 在之前的一个章节中,我们学习了ByteBuf,Netty的数据容器,在这个章节中,我们将讲解Netty的数据流和对应的处理组件,然后我们将我们已经学过的所有组件整合在一起 你已经知道多个ChannelHandler可以被链式的放入ChannelPipeline来将所有的处理逻辑组织在一起,我们将学习包涵这些有关类的很多用户案例和他们之间的对应关系------ChannelH

Netty in Action (十六) 第六章节 第二部分 ChannelHandlerContext和异常处理

6.3 Interface ChannelHandlerContext 一个ChannelHandlerContext代表了一个ChannelHandler和ChannelPipeline之间的关系,ChannelHandlerContext创建于ChannelHandler被载入到ChannelPipeline的时候,ChannelHandlerContext主要功能是管理在同一ChannelPipeline中各个ChannelHandler的交互 ChannelHandlerContext有

Netty in Action (十七) 第七章节 EventLoop和线程模型

本章节包括: 1)线程模型总览 2)Event Loop概念和具体实现 3)任务调度 4)实现细节 简单地陈述一下,对于一个操作系统,编程语言,框架,或者应用来说,线程模型对其都是至关重要的一部分,在什么时间如何创建一个线程都会对你的代码执行有很重要的影响,所以对于开发人员而言,懂得在各种线程模型里面权衡利弊就是一个很重要的事情,是直接使用线程模型本身还是通过一些框架或者语言提供的线程框架对于开发者而言都是需要选择的 在这个章节,我们将会详细地讲解Netty的线程模型,这个模型是很强大的,且易于

《Netty in action》目录修复版本分享

最近阅读了Netty in action一书.深感外国友人的书籍编写能力强大.作者由简入深.精简描述了Netty的相关知识,如何使用等等. 本来想翻译一下的.尝试着翻译了一点之后.发现非常痛苦啊.ps.笔者英语不是很好. 很多时候需要自己先把英文理解成中文然后再拼凑起来.写出来的中文译文感觉好奇怪.所以就不拿出来献丑了.把网上的PDF电子书分享一下. 前段时间去找的电子书目录都存在问题的. NIA一书分为四个部分.16个章节.网上的第五版书籍是完整的.但是目录结构完全错误了.再次使用软件修复了.

Netty In Action中文版 - 第四章:Transports(传输)

本章内容 Transports(传输) NIO(non-blocking IO,New IO), OIO(Old IO,blocking IO), Local(本地), Embedded(嵌入式) Use-case(用例) APIs(接口) 网络应用程序一个非常重要的工作是数据传输. 数据传输的过程不一样取决是使用哪种交通工具,可是传输的方式是一样的:都是以字节码传输.Java开发网络程序数据传输的过程和方式是被抽象了的.我们不须要关注底层接口.仅仅须要使用Java API或其它网络框架如Net