与 Servlet 相比,使用 Websocket 下载文件速度较慢

Posted

技术标签:

【中文标题】与 Servlet 相比,使用 Websocket 下载文件速度较慢【英文标题】:File download using Websocket is slow compared to Servlet 【发布时间】:2015-04-10 09:34:51 【问题描述】:

我使用tomcat 7.0.47 WebSocket API编写了一个简单的文件下载程序。 以下是将文件作为二进制消息发送给客户端的方法。

    @OnMessage
    public void onMessage(Session session, String path) 
        ReadableByteChannel channel = null;
        int capacity = 1024 * 100;
        ByteBuffer buffer = ByteBuffer.allocate(capacity);
        try 
            channel = Channels.newChannel(new FileInputStream(path));
            while(channel.read(buffer) != -1)
                buffer.flip();
                session.getBasicRemote().sendBinary(buffer);
                buffer.clear();
            
         catch (IOException e) 
            logger.error("Error while reading the file to download", e);
         finally 
            if (channel != null) 
                try 
                    channel.close();
                 catch (IOException e) 
                    logger.error("Error while closing the stream", e);
                
            
            
        session.getAsyncRemote().sendText("done");
    

我已经使用 SCP、基于 Servlet 的实现和 Websocket 实现对 5GB 文件的总下载时间进行了计时。使用 WebSocket 下载文件要慢得多。对于 5GB 文件,SCP 和 servlet 在我的测试机器上大约需要 50 秒,WebSocket 大约需要 180 秒。

谁能帮我理解我的实现有什么问题?

WebSockets 不适合这种用例吗?任何 tomcat 配置参数需要调整以实现更好的性能?

【问题讨论】:

你应该使用compact(),而不是clear(). 谢谢,但这并没有太大帮助。 Clear 应该比 compact 便宜,因为它只将位置设置为零。 它是作为评论发布的,而不是作为答案发布的。我知道clear() 做了什么。我的观点是,这是错误的调用方法。在调用clear() 正确的情况下,调用compact(), 也是正确的,而且不会更贵;在调用clear() 不正确的情况下,您别无选择,只能调用compact(). 【参考方案1】:

在 tomcat 中发送二进制数据有一个最大有效载荷大小,即 org.apache.tomcat.websocket.binaryBufferSize 引用自 tomcat doc。它的默认值为8192。所以capacity必须小于等于这个值。

所以你的代码必须修改成这样的

int capacity = session.getMaxBinaryMessageBufferSize();

现在,将org.apache.tomcat.websocket.binaryBufferSize 的大小增加到某个合理的更高值,这可能会提高数据传输速度,从而提高下载速度。

您可以使用web.xml 中的上下文初始化参数更改此值。

例如:

<context-param>
    <param-name>org.apache.tomcat.websocket.binaryBufferSize</param-name>
    <param-value>16384</param-value>
</context-param> 

【讨论】:

以上是关于与 Servlet 相比,使用 Websocket 下载文件速度较慢的主要内容,如果未能解决你的问题,请参考以下文章

struts2做控制器相比servlet有啥优点

使用Netty作为业务服务器与Tomcat相比有何优势

简易服务端之Servlet实现Websocket消息通信

简易服务端之Servlet实现Websocket消息通信

Socket 与 WebSocket

tomcat websocket servlet监听端口