netty系列之:性能为王,创建多路复用http2服务器

2024-02-24 15:48

本文主要是介绍netty系列之:性能为王,创建多路复用http2服务器,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 简介
  • 多路复用的基础
  • 多路复用在server端的使用
    • 配置TLS处理器
    • 配置clear text upgrade
  • 总结

简介

在之前的文章中,我们提到了在netty的客户端通过使用Http2FrameCodec和Http2MultiplexHandler可以支持多路复用,也就是说在一个连接的channel基础上创建多个子channel,通过子channel来处理不同的stream,从而达到多路复用的目的。

既然客户端可以做到多路复用,同样的服务器端也可以,今天给大家介绍一下如何在netty的服务器端打造一个支持http2协议的多路复用服务器。

多路复用的基础

netty中对于http2多路复用的基础类是Http2FrameCodec、Http2MultiplexHandler和Http2MultiplexCodec。

Http2FrameCodec是将底层的HTTP/2 frames消息映射成为netty中的Http2Frame对象。

有了Http2Frame对象就可以通过Http2MultiplexHandler对新创建的stream开启不同的channel。

Http2MultiplexCodec是Http2FrameCodec和Http2MultiplexHandler的结合体,但是已经不再被推荐使用了。

因为Http2FrameCodec继承自Http2ConnectionHandler,而Http2MultiplexHandler继承自Http2ChannelDuplexHandler,所以这两个类可以同时在客户端和服务器端使用。

客户端使用Http2FrameCodecBuilder.forClient().build()来获得Http2FrameCodec,而服务器端通过Http2FrameCodecBuilder.forServer().build()来获得Http2FrameCodec。

多路复用在server端的使用

配置TLS处理器

对于服务器端,同样需要处理TLS和普通clear text两种情况。对于TLS来说,我们需要自建ProtocolNegotiationHandler继承自ApplicationProtocolNegotiationHandler,然后实现configurePipeline方法,在其中分别处理http2和http1.1的连接:

    protected void configurePipeline(ChannelHandlerContext ctx, String protocol) {if (ApplicationProtocolNames.HTTP_2.equals(protocol)) {//添加多路复用支持ctx.pipeline().addLast(Http2FrameCodecBuilder.forServer().build());ctx.pipeline().addLast(new Http2MultiplexHandler(new CustMultiplexHttp2Handler()));return;}if (ApplicationProtocolNames.HTTP_1_1.equals(protocol)) {ctx.pipeline().addLast(new HttpServerCodec(),new HttpObjectAggregator(MAX_CONTENT_LENGTH),new CustHttp1Handler("ALPN Negotiation"));return;}throw new IllegalStateException("未知协议: " + protocol);}

首先添加Http2FrameCodec,然后添加Http2MultiplexHandler。因为Http2MultiplexHandler已经封装了多路复用的细节,所以自定义的handler只需要实现正常的消息处理逻辑即可。

因为Http2FrameCodec已经对消息进行了转换成为HTTP2Frame对象,所以只需要处理具体的Frame对象:

    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {if (msg instanceof Http2HeadersFrame) {onHeadersRead(ctx, (Http2HeadersFrame) msg);} else if (msg instanceof Http2DataFrame) {onDataRead(ctx, (Http2DataFrame) msg);} else {super.channelRead(ctx, msg);}}

配置clear text upgrade

对于h2c的升级来说,需要向pipline中传入sourceCodec和upgradeHandler两个处理器。

sourceCodec可以直接使用HttpServerCodec。

upgradeHandler可以使用HttpServerUpgradeHandler。

HttpServerUpgradeHandler的构造函数需要传入一个sourceCodec和一个upgradeCodecFactory。

sourceCodec我们已经有了,再构造一个upgradeCodecFactory即可:

    private static final UpgradeCodecFactory upgradeCodecFactory = protocol -> {if (AsciiString.contentEquals(Http2CodecUtil.HTTP_UPGRADE_PROTOCOL_NAME, protocol)) {return new Http2ServerUpgradeCodec(Http2FrameCodecBuilder.forServer().build(),new Http2MultiplexHandler(new CustMultiplexHttp2Handler()));} else {return null;}};

从代码中可以看出,upgradeCodecFactory内部又调用了Http2FrameCodec和Http2MultiplexHandler。这和使用TLS的处理器是一致的。

        final ChannelPipeline p = ch.pipeline();final HttpServerCodec sourceCodec = new HttpServerCodec();p.addLast(sourceCodec);p.addLast(new HttpServerUpgradeHandler(sourceCodec, upgradeCodecFactory));

总结

通过上述方式,就可以创建出支持多路复用的http2 netty服务器了。

本文的例子可以参考:learn-netty4

本文已收录于 http://www.flydean.com/33-netty-multiplex-http2server/

最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧等你来发现!

欢迎关注我的公众号:「程序那些事」,懂技术,更懂你!

这篇关于netty系列之:性能为王,创建多路复用http2服务器的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/742580

相关文章

MySQL 中的服务器配置和状态详解(MySQL Server Configuration and Status)

《MySQL中的服务器配置和状态详解(MySQLServerConfigurationandStatus)》MySQL服务器配置和状态设置包括服务器选项、系统变量和状态变量三个方面,可以通过... 目录mysql 之服务器配置和状态1 MySQL 架构和性能优化1.1 服务器配置和状态1.1.1 服务器选项

Java中对象的创建和销毁过程详析

《Java中对象的创建和销毁过程详析》:本文主要介绍Java中对象的创建和销毁过程,对象的创建过程包括类加载检查、内存分配、初始化零值内存、设置对象头和执行init方法,对象的销毁过程由垃圾回收机... 目录前言对象的创建过程1. 类加载检查2China编程. 分配内存3. 初始化零值4. 设置对象头5. 执行

ElasticSearch+Kibana通过Docker部署到Linux服务器中操作方法

《ElasticSearch+Kibana通过Docker部署到Linux服务器中操作方法》本文介绍了Elasticsearch的基本概念,包括文档和字段、索引和映射,还详细描述了如何通过Docker... 目录1、ElasticSearch概念2、ElasticSearch、Kibana和IK分词器部署

部署Vue项目到服务器后404错误的原因及解决方案

《部署Vue项目到服务器后404错误的原因及解决方案》文章介绍了Vue项目部署步骤以及404错误的解决方案,部署步骤包括构建项目、上传文件、配置Web服务器、重启Nginx和访问域名,404错误通常是... 目录一、vue项目部署步骤二、404错误原因及解决方案错误场景原因分析解决方案一、Vue项目部署步骤

Linux流媒体服务器部署流程

《Linux流媒体服务器部署流程》文章详细介绍了流媒体服务器的部署步骤,包括更新系统、安装依赖组件、编译安装Nginx和RTMP模块、配置Nginx和FFmpeg,以及测试流媒体服务器的搭建... 目录流媒体服务器部署部署安装1.更新系统2.安装依赖组件3.解压4.编译安装(添加RTMP和openssl模块

Android 悬浮窗开发示例((动态权限请求 | 前台服务和通知 | 悬浮窗创建 )

《Android悬浮窗开发示例((动态权限请求|前台服务和通知|悬浮窗创建)》本文介绍了Android悬浮窗的实现效果,包括动态权限请求、前台服务和通知的使用,悬浮窗权限需要动态申请并引导... 目录一、悬浮窗 动态权限请求1、动态请求权限2、悬浮窗权限说明3、检查动态权限4、申请动态权限5、权限设置完毕后

Springboot中分析SQL性能的两种方式详解

《Springboot中分析SQL性能的两种方式详解》文章介绍了SQL性能分析的两种方式:MyBatis-Plus性能分析插件和p6spy框架,MyBatis-Plus插件配置简单,适用于开发和测试环... 目录SQL性能分析的两种方式:功能介绍实现方式:实现步骤:SQL性能分析的两种方式:功能介绍记录

Python创建Excel的4种方式小结

《Python创建Excel的4种方式小结》这篇文章主要为大家详细介绍了Python中创建Excel的4种常见方式,文中的示例代码简洁易懂,具有一定的参考价值,感兴趣的小伙伴可以学习一下... 目录库的安装代码1——pandas代码2——openpyxl代码3——xlsxwriterwww.cppcns.c

JavaWeb-WebSocket浏览器服务器双向通信方式

《JavaWeb-WebSocket浏览器服务器双向通信方式》文章介绍了WebSocket协议的工作原理和应用场景,包括与HTTP的对比,接着,详细介绍了如何在Java中使用WebSocket,包括配... 目录一、概述二、入门2.1 POM依赖2.2 编写配置类2.3 编写WebSocket服务2.4 浏

查询SQL Server数据库服务器IP地址的多种有效方法

《查询SQLServer数据库服务器IP地址的多种有效方法》作为数据库管理员或开发人员,了解如何查询SQLServer数据库服务器的IP地址是一项重要技能,本文将介绍几种简单而有效的方法,帮助你轻松... 目录使用T-SQL查询方法1:使用系统函数方法2:使用系统视图使用SQL Server Configu