Evolution of Multimedia Storage and Development of Netty-Based HTTP File Server

This article discusses the evolution of multimedia storage systems and the development of a high-performance HTTP file server using Netty to address issues like lack of support for file download breakpoints and low performance.

Zhengtong Technical Team
Zhengtong Technical Team
Zhengtong Technical Team
Evolution of Multimedia Storage and Development of Netty-Based HTTP File Server

1.背景 多媒体存储是每个业务系统搭建时必备功能,政通的业务系统中多媒体存储部分经历了几个阶段的演进,其结构如图所示:

在传统单体服务的框架下,“多媒体权限管理”和“业务数据关联”部分集成到了业务系统中,作为业务系统中的多媒体管理模块来实现;多媒体管理模块通过相关协议来调用后端的管理服务进行多媒体存取操作,其中最重要的几个功能是文件上传、文件下载和文件删除。管理模块所依赖的操作协议经历了几次更改:

服务器消息块(SMB)协议,即沿用自Windows部署时代的方案,同时可以在Linux上使用samba服务提供文件共享。

文件传输协议(FTP),搭建FTP服务提供文件服务。

超文本传输协议(HTTP),自建HttpFileServer,配合Nginx发布静态文件,通过Http协议上传和下载文件。

另外还有一些项目提供了对象存储服务,也可以归为使用HTTP协议。目前大部分项目都使用了基于Spring框架的HttpFileServer作为文件存储服务,好处在于部署简单、端口开放要求少(只需要一个端口),客户端开发简单(只需要实现几个REST接口的请求)。但在项目运行过程中,自建的HttpFileServer也暴露出了一些功能和性能上的问题,本文将从这些问题出发,探讨问题出现原因引出选择Netty的原因,并简述开发过程及最终成果。

2.相关问题

2.1 断点下载的缺失

起因是和DevOps的同学一起排查现场问题时,发现了Nginx 临时文件大小配置的坑。具体是指Nginx中 proxy_max_temp_file_size 配置,默认是1024M。相关场景为:客户端需要根据附件ID请求从服务端下载附件,在这过程中需要进行鉴权、查询相关多媒体存储位置等操作,具体请求路径如下:

此时Nginx配置了缓存, proxy_max_temp_file_size 使用默认配置,由于客户端与服务端之间网络速度比较慢。此时发生的事情:

Nginx缓存文件很快就达到了1024M,Nginx 就停止从后端服务获取数据;

后端服务等待时间超过Socket Timeout配置后(设置为60s),服务端就抛出异常,停止此次下载请求,关闭连接;

客户端把1024M数据下完了,想继续请求后面数据,通过Nginx再请求服务端时,由于服务端不支持断点续传,就导致下载失败。

临时解决方案: proxy_max_temp_file_size 配置调小,让客户端下的快一些。更深层次的分析可以单独写一篇文章了,各位同学可以自行查找资料,本文就不展开说明。

抛开业务端转发的逻辑,这次也暴露出了HttpFileServer的不足:竟然没有实现文件下载的断点续传。

2.2 文件服务性能

DevOps的同学在验证多媒体相关接口性能的时候,给出的分析结果是:通过HttpFileServer发布的多媒体服务,多媒体获取性能只有Nginx的25%左右(调整了部署参数后)。

同时给了相关建议:

提升HttpFileServer性能;

不需要权限控制的情况下,使用Nginx发布多媒体目录。

其中第二点修改方式不满足一些项目的需求,原因有两点:一是业务产品的多媒体访问权限管理是在业务系统实现,即业务系统不修改的情况下,多媒体的使用必须通过HttpFileServer;二是在复杂网络条件下,为了减少实施运维的配置量,前端访问多媒体是经过了业务系统接口进行数据流转发,需要根据多媒体标识从多媒体服务获取对应文件。

既然存在必须使用多媒体服务的场景,就需要想办法提升HttpFIleServer的性能。

3.选择Netty的原因

考虑新版本HttpFileServer开发需要满足如下条件:

文件服务的基本功能:上传、下载、删除、重命名等;

兼容已有项目的部署和使用;

能够提供较高的并发性能。

Netty框架无疑是最佳的选择,其具有如下特性:

1.设计好 统一的API,支持各种协议实现。基于可扩展的事件驱动模型,方便开发。高度可定制的线程模型。可靠的无连接数据socket支持(UDP)。

2.并发高 Netty是一款基于NIO(Nonblocking I/O,非阻塞IO)开发的网络通信框架,对比于BIO(Blocking I/O,阻塞IO),其并发性能得到了很大提高。

3.传输快 Netty建立在NIO基础上,在NIO之上又提供了高层次的抽象,提供了最基础的并发性能保障。同时借助NIO的零拷贝特性,通过ByteBuf直接对数据进行操作,加快传输速度。

4.封装好 提供各种类型消息的Encoder、Decoder、Handler(例如HttpResponseEncoder、HttpRequestDecoder、ChunkedWriteHandler),通过Pipeline整合后进行消息处理。高度灵活的接口定义,可以实现自己的消息转换类,自行解析协议。

许多有名的软件或者框架都使用到了Netty,例如阿里的Dubbo默认使用Netty作为基础通信组件。

4.开发过程

4.1 开发思路

HttpFileServer的应包含请求鉴权、文件读写。服务核心是文件读写,鉴权部分兼容原应用的鉴权方式即可,文件读写部分自行开发代码实现。

4.2 应用入口

Netty仅是一套开发框架,需要有其他web容器支撑来启用服务。为方便项目启动和后续扩展,选用了Springboot为启动器(也仅仅是作为启动器和Bean管理),整个项目显式引入的依赖仅两个:spring-boot-starter 和 netty-all 。其中netty-all版本为4.1.67.Final(截止发稿时,Netty5已经发布的最新版本为5.0.0.FINAL-SNAPSHOT,Netty4最新版本为 4.1.72.FINAL)。

Netty服务启动后可以直接处理网络消息,不再需要SpringBoot启用Web服务,此时可以关闭SpringBoot的web服务功能。

Tips: SpringBoot项目关闭web服务可以在main方法中处理,示例:

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Zhengtong Technical Team
Written by

Zhengtong Technical Team

How do 700+ nationwide projects deliver quality service? What inspiring stories lie behind dozens of product lines? Where is the efficient solution for tens of thousands of customer needs each year? This is Zhengtong Digital's technical practice sharing—a bridge connecting engineers and customers!

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.