Netty 简介
创始人
2024-05-30 15:10:49
0

da6076f445844910a61943e436f0c9c6.jpg一、Netty 简介

 

Netty 是基于 Java NIO 的异步事件驱动的网络应用框架,使用 Netty 可以快速开发网络应用,Netty 提供了高层次的抽象来简化 TCP 和 UDP 服务器的编程,但是你仍然可以使用底层的 API。

 

Netty 的内部实现是很复杂的,但是 Netty 提供了简单易用的API从网络处理代码中解耦业务逻辑。Netty 是完全基于 NIO 实现的,所以整个 Netty 都是异步的。

 

Netty 是最流行的 NIO 框架,它已经得到成百上千的商业、商用项目验证,许多框架和开源组件的底层 rpc 都是使用的 Netty,如 Dubbo、Elasticsearch 等等。下面是官网给出的一些 Netty 的特性:

 

设计方面

 

对各种传输协议提供统一的 API(使用阻塞和非阻塞套接字时候使用的是同一个 API,只是需要设置的参数不一样)。

基于一个灵活、可扩展的事件模型来实现关注点清晰分离。

高度可定制的线程模型——单线程、一个或多个线程池。

真正的无数据报套接字(UDP)的支持(since 3.1)。

易用性

 

完善的 Javadoc 文档和示例代码。

不需要额外的依赖,JDK 5 (Netty 3.x) 或者 JDK 6 (Netty 4.x) 已经足够。

性能

 

更好的吞吐量,更低的等待延迟。

更少的资源消耗。

最小化不必要的内存拷贝。

安全性

 

完整的 SSL/TLS 和 StartTLS 支持

对于初学者,上面的特性我们在脑中有个简单了解和印象即可, 下面开始我们的实战部分。

 

二、一个简单 Http 服务器

开始前说明下我这里使用的开发环境是 IDEA+Gradle+Netty4,当然你使用 Eclipse 和 Maven 都是可以的,然后在 Gradle 的 build 文件中添加依赖 compile 'io.netty:netty-all:4.1.26.Final',这样就可以编写我们的 Netty 程序了,正如在前面介绍 Netty 特性中提到的,Netty 不需要额外的依赖。

 

第一个示例我们使用 Netty 编写一个 Http 服务器的程序,启动服务我们在浏览器输入网址来访问我们的服务,便会得到服务端的响应。功能很简单,下面我们看看具体怎么做?

 

首先编写服务启动类

 

复制代码

public class HttpServer {

    public static void main(String[] args) {

        //构造两个线程组

        EventLoopGroup bossrGroup = new NioEventLoopGroup();

        EventLoopGroup workerGroup = new NioEventLoopGroup();

        try {

            //服务端启动辅助类

            ServerBootstrap bootstrap = new ServerBootstrap();

 

            bootstrap.group(bossGroup, workerGroup)

            .channel(NioServerSocketChannel.class)

            .childHandler(new HttpServerInitializer());

 

            ChannelFuture future = bootstrap.bind(8080).sync();

            //等待服务端口关闭

            future.channel().closeFuture().sync();

        } catch (InterruptedException e) {

            e.printStackTrace();

        }finally {

            // 优雅退出,释放线程池资源

            bossGroup.shutdownGracefully();

            workerGroup.shutdownGracefully();

        }

    }

}

复制代码

 

 

在编写 Netty 程序时,一开始都会生成 NioEventLoopGroup 的两个实例,分别是 bossGroup 和 workerGroup,也可以称为 parentGroup 和 childGroup,为什么创建这两个实例,作用是什么?可以这么理解,bossGroup 和 workerGroup 是两个线程池, 它们默认线程数为 CPU 核心数乘以 2,bossGroup 用于接收客户端传过来的请求,接收到请求后将后续操作交由 workerGroup 处理。

 

在这里我向大家推荐一个架构学习交流群。交流学习群号:747981058 里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化、分布式架构等这些成为架构师必备的知识体系。

 

接下来我们生成了一个服务启动辅助类的实例 bootstrap,boostrap 用来为 Netty 程序的启动组装配置一些必须要组件,例如上面的创建的两个线程组。channel 方法用于指定服务器端监听套接字通道 NioServerSocketChannel,其内部管理了一个 Java NIO 中的ServerSocketChannel实例。

 

channelHandler 方法用于设置业务职责链,责任链是我们下面要编写的,责任链具体是什么,它其实就是由一个个的 ChannelHandler 串联而成,形成的链式结构。正是这一个个的 ChannelHandler 帮我们完成了要处理的事情。

 

接着我们调用了 bootstrap 的 bind 方法将服务绑定到 8080 端口上,bind 方法内部会执行端口绑定等一系列操,使得前面的配置都各就各位各司其职,sync 方法用于阻塞当前 Thread,一直到端口绑定操作完成。接下来一句是应用程序将会阻塞等待直到服务器的 Channel 关闭。

 

启动类的编写大体就是这样了,下面要编写的就是上面提到的责任链了。如何构建一个链,在 Netty 中很简单,不需要我们做太多,代码如下:

 

复制代码

public class HttpServerInitializer extends ChannelInitializer {

    protected void initChannel(SocketChannel sc) throws Exception {

        ChannelPipeline pipeline = sc.pipeline();

        //处理http消息的编解码

        pipeline.addLast("httpServerCodec", new HttpServerCodec());

        //添加自定义的ChannelHandler

        pipeline.addLast("httpServerHandler", new HttpServerHandler());

    }

}

复制代码

 

 

我们自定义一个类 HttpServerInitializer 继承 ChannelInitializer 并实现其中的 initChannel方法。

 

ChannelInitializer 继承 ChannelInboundHandlerAdapter,用于初始化 Channel 的 ChannelPipeline。通过 initChannel 方法参数 sc 得到 ChannelPipeline 的一个实例。

 

当一个新的连接被接受时, 一个新的 Channel 将被创建,同时它会被自动地分配到它专属的 ChannelPipeline。

 

ChannelPipeline 提供了 ChannelHandler 链的容器,推荐读者仔细自己看看 ChannelPipeline 的 Javadoc,文章后面也会继续说明 ChannelPipeline 的内容。

 

Netty 是一个高性能网络通信框架,同时它也是比较底层的框架,想要 Netty 支持 Http(超文本传输协议),必须要给它提供相应的编解码器。

 

所以我们这里使用 Netty 自带的 Http 编解码组件 HttpServerCodec 对通信数据进行编解码,HttpServerCodec 是 HttpRequestDecoder 和 HttpResponseEncoder 的组合,因为在处理 Http 请求时这两个类是经常使用的,所以 Netty 直接将他们合并在一起更加方便使用。所以对于上面的代码:

 

pipeline.addLast("httpServerCodec", new HttpServerCodec())

 

 

我们替换成如下两行也是可以的。

 

pipeline.addLast("httpResponseEndcoder", new HttpResponseEncoder());

pipeline.addLast("HttpRequestDecoder", new HttpRequestDecoder());

 

 

通过 addLast 方法将一个一个的 ChannelHandler 添加到责任链上并给它们取个名称(不取也可以,Netty 会给它个默认名称),这样就形成了链式结构。在请求进来或者响应出去时都会经过链上这些 ChannelHandler 的处理。

 

最后再向链上加入我们自定义的 ChannelHandler 组件,处理自定义的业务逻辑。下面就是我们自定义的 ChannelHandler。

 

复制代码

public class HttpServerChannelHandler0 extends SimpleChannelInboundHandler {

    private HttpRequest request;

 

    @Override

    protected void channelRead0(ChannelHandlerContext ctx, HttpObject msg) throws Exception {

        if (msg instanceof HttpRequest) {

            request = (HttpRequest) msg;

            request.method();

            String uri = request.uri();

            System.out.println("Uri:" + uri);

        }

        if (msg instanceof HttpContent) {

 

            HttpContent content = (HttpContent) msg;

            ByteBuf buf = content.content();

            System.out.println(buf.toString(io.netty.util.CharsetUtil.UTF_8));

 

            ByteBuf byteBuf = Unpooled.copiedBuffer("hello world", CharsetUtil.UTF_8);

            FullHttpResponse response = new Defaul

相关内容

热门资讯

人的一生就是为了,传宗接代吗? 人的一生就是为了,传宗接代吗?那当然不是,每个人都有自己的价值观,如果你有这个想法,证明你被他们影响...
洛克王国诙谐神殿怎么打啊,我有... 洛克王国诙谐神殿怎么打啊,我有70的罗隐和51的少林咕咕,和45的音速,还有一只44的火神,这样能过...
手机屏幕上怎么弄出字 手机屏幕上怎么弄出字手机屏幕上怎么弄出字手机屏幕上怎么弄出字:长按手机桌面,然后点击窗口小工具或小组...
跪求花开伊吕波的结局是怎么样的... 跪求花开伊吕波的结局是怎么样的!真的是得了白血病吗?是的话!KIR了编剧楼主哪里得到的消息? 花开...
苏格兰民歌 一路平安 苏格兰民歌 一路平安还没听过,不好意思,帮不了你
谁能帮我起一个好听的英文名(要... 谁能帮我起一个好听的英文名(要中文)男女?女 我比较喜欢--joy(乔伊)、Renee(瑞妮)、Ma...
寻高手对下联~ 寻高手对下联~琵琶琴瑟八大王 王王在上魑魅魍魉四小鬼,鬼鬼靠边!魑魅魍魉四小鬼,鬼鬼靠边魑魅魍魉四...
《一位母亲与家长会》的3道阅读... 《一位母亲与家长会》的3道阅读题1.我没有原文。对不起。2.因为母亲在鼓励她的孩子,她要使自己的孩子...
深深的喜欢等于爱吗? 深深的喜欢等于爱吗?喜欢不等于爱。但当你站在你喜欢的人面前,你只感到开心但当你与你喜欢的人四目交投,...
《人性的弱点》一书作者是谁? 《人性的弱点》一书作者是谁?《人性的弱点》·作者:(美)戴尔·卡耐基文名:DaleCarnegie戴...
浪漫一生的英文怎么写 浪漫一生的英文怎么写a so long liferomance all one's lifeRoma...
古代什么词可以指代美女? 古代什么词可以指代美女?谢谢!一楼的你说的不对吧?我说的是指代,不是形容啊。形容我也会,倾国倾城,冰...
以前有看过部分小说是《神雕侠侣... 以前有看过部分小说是《神雕侠侣》后面的,不知是那部小说? 想问问?不是,是别人续写的一部小说?只是记...
在工作中学习到什么?” 在工作中学习到什么?”工作中可以学到与本职工作相关的技术、技巧。了解工作的流程。以及本工作的重点及注...
《西游记》中女妖怪有不少,其中... 《西游记》中女妖怪有不少,其中最可怜的女妖怪是谁?中女妖怪有不少,其中最可怜的女妖怪是白骨夫人最可怜...
英文名字‘爱丽儿’的英文到底怎... 英文名字‘爱丽儿’的英文到底怎么写?!Alier Ariel作为英文名字,这两个里哪个更好?先谢谢...
武术在实战中有用吗 武术在实战中有用吗真的打架能不能那么帅?有用,一个会武术的人和一个会武术的人格斗,就要使用一些较为复...
关于模拟人生3夜店人生 关于模拟人生3夜店人生1你的Net Framework版本过低,去安装 一个最新版的4.0的2这个问...
吴启华版倚天屠龙记张无忌哪一集... 吴启华版倚天屠龙记张无忌哪一集上的武当山吴启华版倚天屠龙记张无忌哪一集上的武当山,就是扮成个小道童,...
《三国演义》战长沙的时候,如果... 《三国演义》战长沙的时候,如果关羽的拖刀计用全了,能够斩杀黄忠吗?我认为是可以斩杀黄忠的,因为当时黄...