Java文件上传速度非常慢

Posted

技术标签:

【中文标题】Java文件上传速度非常慢【英文标题】:Java file uploading painfully slow 【发布时间】:2016-05-21 07:33:02 【问题描述】:

我构建了一个小型服务,它从 android 设备接收图像并将它们保存到 Amazon S3 存储桶中。代码非常简单,但速度非常慢。它是这样的:

public synchronized static Response postCommentPicture(Response response, Request request)
    JsonObject ret = new JsonObject();
    OutputStream outputStream;
    String meepId = request.params(":id");
    System.out.println("1");
    if(meepId == null)
        ret.addProperty("Error", "Missing meep id");
        response.body(ret.getAsString());
        return response;
    
    try 
        System.out.println("2");
        //Chequeamos que vengan los datos del sender
        Map<String, String> urlData = Utils.splitQuery(request.queryString());
        if(!urlData.containsKey("senderName") || !urlData.containsKey("senderId"))
            throw new Exception("senderName or senderId missing");
        System.out.println("3");
        MultipartConfigElement multipartConfigElement = new MultipartConfigElement("/temp");
        System.out.println("3.1");
        request.raw().setAttribute("org.eclipse.jetty.multipartConfig", multipartConfigElement);
        System.out.println("3.2");
        Collection<Part> files = request.raw().getParts();
        System.out.println("3.3");
        if(files.size() == 0 || files.size() > 1)
            throw new Exception("No files or more than 1 file detected");
        
        //Rest of the code...
     catch (Exception e2)
        System.out.println(e2.getMessage());
        ret.addProperty("Error", e2.getMessage());          
     finally 
        response.body(ret.toString());
        return response;
    

所以,如您所见,我会在某些步骤上打印日志。代码运行顺利,直到“3.2”,它开始从客户端设备传输文件。因此,完成传输需要一些时间,但是,一旦完成上传(我可以使用 Android Studio 网络监视器来判断),服务器在处理下一行并打印“3.3”之前还需要 3 到 4 分钟。其余代码也运行流畅,我终于可以在客户端得到响应了。

所以,我的问题是为什么request.raw().getParts() 最多需要 6 分钟,即使上传已完成。

【问题讨论】:

我无法回答那个确切的问题,但我碰巧正在使用 Retrofit to Scala 做同样的事情,而且它工作得很好。您是否尝试过通过 .getParts() 的功能进行调试? 所以你说问题可能出在客户端(即Android Http库)? 我想知道是不是问题,我先尝试从服务器上传一个本地文件到S3,看看是服务器代码还是Android代码。如果您在 Android 上错误地上传二进制文件,您最终会逐字节发送数据,这可能会造成伤害! 必须有一个 360 秒的超时......看起来你没有在将数据从 android 发送到服务器后关闭/刷新通道。可能是某个地方的默认超时...... 我将客户端库从 HttpClient 更改为 OkHttp,现在它就像一个魅力,感谢@Ewald 【参考方案1】:

从客户端(android/ios),尝试发送文件块,而不是发送整个文件。服务器将接收这些块,合并并创建一个文件。

为了让它更快。从客户端使用多个线程发送块。

或使用某些库进行上传,例如 https://github.com/square/okhttp 或 https://github.com/koush/AndroidAsync

【讨论】:

我认为文件/多部分数据是通过块发送的。无论如何,我解决了将客户端库更改为 OkHttp 的问题。 完美!抱歉刚刚看到您对共享代码的评论。你还想要吗?【参考方案2】:

听起来好像从 Android 端发送数据的应用在完成发送数据后并没有关闭连接。

这将导致两端都坐在那里,直到触发读取超时之一。

您是自己在 Android 设备上编写代码,还是使用浏览器或某些第三方应用?

【讨论】:

我觉得这可能是对的,我在使用 HttpClient 时从未关闭过连接,谢谢。

以上是关于Java文件上传速度非常慢的主要内容,如果未能解决你的问题,请参考以下文章

FTP上传速度慢

FTP上传文件速度太慢怎么办?

如何提高ftp的上传速度

请问fckeditor的filemanager(java)中,上传完文件后怎么返回文件名到页面上去啊?

用flask做了个文件管理,上传速度太慢了

使用 Python 在 Azure 存储容器上上传多个文件时,上传时间非常慢