首页 / 知识
在Java Servlet中流式传输大文件
2023-04-14 22:16:00

Streaming large files in a java servlet我正在构建需要扩展的Java服务器。 Servlet之一将提供存储在Amazon S3中的图像。 最近在负载下,我的VM内存不足,这是在我添加了用于提供图像的代码之后,因此,我很确定流较大的servlet响应会引起麻烦。 我的问题是:从数据库或其他云存储读取数据时,如何编写Java Servlet以便将大型(> 200k)响应流回浏览器,是否有最佳实践? 我考虑过将文件写入本地临时驱动器,然后生成另一个线程来处理流,以便可以重新使用tomcat servlet线程。 这似乎很沉重。 任何想法将不胜感激。 谢谢。 如果可能,您不应将要提供的文件的全部内容存储在内存中。取而代之的是,获取数据的InputStream,并将数据分段复制到Servlet OutputStream。例如:
我确实同意toby,您应该改为"将它们指向S3 url"。 至于OOM异常,您确定它与提供图像数据有关吗?假设您的JVM具有256MB的"额外"内存,可用于提供图像数据。在Google的帮助下," 256MB / 200KB" =1310。对于2GB的"额外"内存(目前这是一个非常合理的数量),可以支持10,000个并发客户端。即便如此,1300个并发客户端仍然是一个很大的数目。这是您经历过的负载类型吗?如果不是,则可能需要在其他地方查找OOM异常的原因。 编辑-关于:
几周前阅读S3文档时,我注意到您可以生成可以附加到S3 URL的过期密钥。因此,您不必公开S3上的文件。我对这项技术的理解是: 您为什么不只将它们指向S3网址?从S3中获取工件,然后通过您自己的服务器将其流式传输给我,这使使用S3的目的无法实现,因为S3的工作是卸载带宽并将图像处理服务交付给Amazon。 我已经看到了很多代码,例如john-vasilef的(当前接受的)答案,在紧紧的循环中从一个流中读取块并将它们写入另一流中。 我要提出的观点是反对不必要的代码重复,而赞成使用Apache的IOUtils。如果您已经在其他地方使用过它,或者如果您正在使用的另一个库或框架已经依赖于它,那么这是一条已知且经过良好测试的行。 在以下代码中,我正在将对象从Amazon S3流传输到Servlet中的客户端。
6行定义明确的模式,具有正确的流关闭效果,看起来非常可靠。 我非常同意toby和John Vasileff的看法,如果可以忍受相关问题,S3非常适合卸载大型媒体对象。 (自己的应用程序实例可以处理10-1000MB的FLV和MP4。)例如:不过,没有部分请求(字节范围标头)。必须"手动"处理,偶尔停机等。 如果那不是一个选择,John的代码看起来不错。我发现2k FILEBUFFERSIZE的字节缓冲区在微基准标记中是最有效的。另一个选项可能是共享的FileChannel。 (FileChannel是线程安全的。) 也就是说,我还要补充一点,猜测造成内存不足错误的原因是经典的优化错误。通过使用严格的指标,您将提高成功的机会。 当然还有其他工具,但是Java 5+附带的jmap和jhat都是"开箱即用"的
啊,我不认为你不能那样做。即使可以,听起来也很可疑。管理连接的tomcat线程需要控制。如果遇到线程不足,请增加./conf/server.xml中的可用线程数。同样,指标是检测到此问题的方法-不仅仅是猜测。 问题:您还在EC2上运行吗?您的tomcat的JVM启动参数是什么?
toby是正确的,如果可以的话,您应该直接指向S3。如果您不能这样做,那么这个问题可能会有点含糊,无法给出准确的答案: 如果使用8K缓冲区,则可能有1000个并发流进入?8Megs的堆空间,因此您肯定做错了...。 顺便说一句,我并不是凭空挑出8K的,这是套接字缓冲区的默认大小,发送更多的数据(例如1Meg),您将在tcp / ip堆栈上阻塞以容纳大量内存。 如果您可以对文件进行结构化,以使静态文件分离并位于各自的存储桶中,则可以通过使用Amazon S3 CDN CloudFront来实现当今最快的性能。 除了John建议的内容之外,您还应该重复刷新输出流。根据您的Web容器,它可能会缓存部分甚至全部输出,并一次刷新一次(例如,计算Content-Length标头)。那会消耗很多内存。 您必须检查两件事:
|
最新内容
相关内容
linux服务器基本命令?
linux服务器基本命令?,地址,系统,设备,网络,工作,标准,信息,电脑,命令,密码,linux如何查看ip地址命令(linux如何查看ip地址)1、目录方法1:使用Ulinux服务器下载命令?
linux服务器下载命令?,服务,密码,系统,档案,工具,网络,公共,百度,地址,认证,linux下lftp连接ftp服务器上传下载命令连接ftp服务器 格式:ftp [holinux服务器常用命令?
linux服务器常用命令?,工作,系统,地址,信息,命令,目录,管理,标准,设备,功能,重启服务器的linux命令1、首先我首要把linux开机, 命令 rebot 这个linux命令设置扩展屏?
linux命令设置扩展屏?,工具,系统,电脑,技术,软件,装备,情况,工作,命令,显示器,Linux中如何分屏显示的命令是什么linux中如果想要把某个命令或linux服务器保存命令?
linux服务器保存命令?,时间,状态,档案,电脑,命令,信息,位置,编辑,文件,模式,Linux的vi编辑后如何保存?1、按ESC键回到命令模式,输入:w保存即可,或linux服务器扫盘命令?
linux服务器扫盘命令?,地址,工作,命令,目录,数据,单位,名称,系统,管理,信息,Linux常用命令有哪些1、linux常用命令如下:查看内核版本:uname-a。linux命令切换服务器?
linux命令切换服务器?,地址,名称,系统,环境,实时,命令,服务器,脚本,路径,版本,如何远程管理Linux服务器?1、主控端Windows在控制窗口内点击“linux服务器搭建命令?
linux服务器搭建命令?,系统,服务,软件,地址,平台,在线,密码,工具,环境,百度,linux下简单快速的搭建ftp服务器环境具体步骤如下:检查安装vsftpdlinux磁盘扩展命令?
linux磁盘扩展命令?,在线,信息,扩大,风险,磁盘,虚拟机,容量,分区,目录,链接,LINUX虚拟机磁盘在线扩容不重启虚拟机里添加磁盘 检查磁盘空间:运服务器重启命令linux?
服务器重启命令linux?,工作,标准,设备,服务,系统,名称,命令,百度,网络,密码,怎么使用linux命令重启服务器1、shutdown。poweroff。init。reboolinux服务器删除命令?
linux服务器删除命令?,系统,服务,管理,情况,命令,工作,互动,地址,软件,较大,linux系统里怎么删除已经安装的dns服务器如果是清除NSCD上的Cachelinux服务器负荷命令?
linux服务器负荷命令?,信息,电脑,中科,环境,工具,系统,平均,检测,情况,状态,linux服务器监控的几个方法和命令uptime 该命令直观的显示了服务