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

相关文章

基于Python打造一个可视化FTP服务器

《基于Python打造一个可视化FTP服务器》在日常办公和团队协作中,文件共享是一个不可或缺的需求,所以本文将使用Python+Tkinter+pyftpdlib开发一款可视化FTP服务器,有需要的小... 目录1. 概述2. 功能介绍3. 如何使用4. 代码解析5. 运行效果6.相关源码7. 总结与展望1

使用Python开发一个简单的本地图片服务器

《使用Python开发一个简单的本地图片服务器》本文介绍了如何结合wxPython构建的图形用户界面GUI和Python内建的Web服务器功能,在本地网络中搭建一个私人的,即开即用的网页相册,文中的示... 目录项目目标核心技术栈代码深度解析完整代码工作流程主要功能与优势潜在改进与思考运行结果总结你是否曾经

使用Python实现快速搭建本地HTTP服务器

《使用Python实现快速搭建本地HTTP服务器》:本文主要介绍如何使用Python快速搭建本地HTTP服务器,轻松实现一键HTTP文件共享,同时结合二维码技术,让访问更简单,感兴趣的小伙伴可以了... 目录1. 概述2. 快速搭建 HTTP 文件共享服务2.1 核心思路2.2 代码实现2.3 代码解读3.

Python如何使用__slots__实现节省内存和性能优化

《Python如何使用__slots__实现节省内存和性能优化》你有想过,一个小小的__slots__能让你的Python类内存消耗直接减半吗,没错,今天咱们要聊的就是这个让人眼前一亮的技巧,感兴趣的... 目录背景:内存吃得满满的类__slots__:你的内存管理小助手举个大概的例子:看看效果如何?1.

Java的IO模型、Netty原理解析

《Java的IO模型、Netty原理解析》Java的I/O是以流的方式进行数据输入输出的,Java的类库涉及很多领域的IO内容:标准的输入输出,文件的操作、网络上的数据传输流、字符串流、对象流等,这篇... 目录1.什么是IO2.同步与异步、阻塞与非阻塞3.三种IO模型BIO(blocking I/O)NI

idea中创建新类时自动添加注释的实现

《idea中创建新类时自动添加注释的实现》在每次使用idea创建一个新类时,过了一段时间发现看不懂这个类是用来干嘛的,为了解决这个问题,我们可以设置在创建一个新类时自动添加注释,帮助我们理解这个类的用... 目录前言:详细操作:步骤一:点击上方的 文件(File),点击&nbmyHIgsp;设置(Setti

CentOS 7部署主域名服务器 DNS的方法

《CentOS7部署主域名服务器DNS的方法》文章详细介绍了在CentOS7上部署主域名服务器DNS的步骤,包括安装BIND服务、配置DNS服务、添加域名区域、创建区域文件、配置反向解析、检查配置... 目录1. 安装 BIND 服务和工具2.  配置 BIND 服务3 . 添加你的域名区域配置4.创建区域

Redis中高并发读写性能的深度解析与优化

《Redis中高并发读写性能的深度解析与优化》Redis作为一款高性能的内存数据库,广泛应用于缓存、消息队列、实时统计等场景,本文将深入探讨Redis的读写并发能力,感兴趣的小伙伴可以了解下... 目录引言一、Redis 并发能力概述1.1 Redis 的读写性能1.2 影响 Redis 并发能力的因素二、

Windows Server服务器上配置FileZilla后,FTP连接不上?

《WindowsServer服务器上配置FileZilla后,FTP连接不上?》WindowsServer服务器上配置FileZilla后,FTP连接错误和操作超时的问题,应该如何解决?首先,通过... 目录在Windohttp://www.chinasem.cnws防火墙开启的情况下,遇到的错误如下:无法与

Spring 中使用反射创建 Bean 实例的几种方式

《Spring中使用反射创建Bean实例的几种方式》文章介绍了在Spring框架中如何使用反射来创建Bean实例,包括使用Class.newInstance()、Constructor.newI... 目录1. 使用 Class.newInstance() (仅限无参构造函数):2. 使用 Construc