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

相关内容

热门资讯

用这些词语写一段话,描写月夜的... 用这些词语写一段话,描写月夜的优美景色中秋之夜,坐在湖心亭品茶赏月,月光似水般倾泻于树影婆娑之中,并...
南笙在《楚乔传》中饰演谁? 南笙在《楚乔传》中饰演谁?《楚乔传》中南笙饰演的角色:兰淑仪
迪拜的机场的名称是什么 迪拜的机场的名称是什么  迪拜机场即迪拜国际机场,是阿拉伯联合酋长国迪拜的主要机场,也是阿联酋航空公...
C视频丨“机器人总动员”来啦!... 转自:四川在线 四川在线记者 薛维睿 成都观察 王翱化身...
广州多浦乐:5%以上股东减持股... 广州多浦乐电子科技股份有限公司于2025年4月23日在巨潮资讯网披露《关于持股5%以上股东减持股份的...
山羊为什么长胡子? 山羊为什么长胡子?山羊长期生长在山区,经常在树林、杂草、灌木等环境中觅食,为了保护下颚皮肤就进化出了...
“生态警务5.0”升级,崇明今... 转自:上观新闻上海市公安局崇明分局以枫桥式派出所创建为目标,持续升级“生态警务5.0”,将“全生态警...
飙涨超249%!全国第一!“西... 转自:央视财经挖掘机是基础设施建设的“标配”,是反映基础设施建设、观察固定资产投资等经济变化的风向标...
怎样概括文章主旨 怎样概括文章主旨如果想表达内容的主旨可以从文章的题目也可以成为文章的内容也可以从人物形象来判断、从文...
上海龙宇数据股份回购近5000... 上海龙宇数据股份有限公司于2025年6月17日发布关于股份回购进展公告,披露了公司在退市整理期内的股...
辞职写“因个人原因”,还能拿经... 转自:北京日报客户端“如果辞职申请上写了‘因个人原因’,是不是就再也拿不到经济补偿金了?”这是不少打...
英伟达加速布局欧洲,黄仁勋力推...   炒股就看金麒麟分析师研报,权威,专业,及时,全面,助您挖掘潜力主题机会! 21世纪经济报道记者...
在希望篮途计划里,你能看见中国... 姚明希望更多人能够关心和重视青少年体育,特别是乡村的青少年体育教育。“用网络的上话说,乡村老师们也不...
中国纸本艺术国际巡展在保加利亚... 转自:经济日报当地时间6月15日,“纸语千年 艺韵华章——中国当代纸本艺术国际巡展”首展在保加利亚索...
巴奴国际控股有限公司向港交所提... 6月16日,据港交所文件,巴奴国际控股有限公司向港交所提交上市申请书,联席保荐人为中金公司、招银国际...
内蒙古新能源装机规模突破1.4... 来源:中国新闻网 中新社呼和浩特6月16日电 (记者 李爱平)内蒙古自治区能源局16日消息,今年截至...
尺素金声丨工业企业效益恢复向好... 转自:上观新闻增长加快!日前,国家统计局数据显示:4月份,全国规模以上工业企业利润同比增长3.0%,...
英国向中东增派战机,英财政大臣... 来源:环球网 【环球网报道 记者 李梓瑜】据英国《独立报》当地时间15日报道,尽管英国皇家空军在伊朗...
痛心!湖南烟花爆炸事故已致1死... 转自:中华人民共和国应急管理部央视新闻客户端报道,据湖南临澧县委宣传部消息,6月16日8时23分许,...
国信证券-人形机器人行业周报(... (转自:研报虎)  市场表现:本周(6.9-6.13)我们构建的国信人形机器人指数下跌2.34%,弱...