通过Java套接字发送小文件时的性能问题
我正在构建一个web服务器应用程序,它使用HTTP 1.1协议和分块传输编码,根据请求将不同大小的文件从服务器发送到客户端 我正在使用Java通过Java套接字发送小文件时的性能问题,java,sockets,Java,Sockets,我正在构建一个web服务器应用程序,它使用HTTP 1.1协议和分块传输编码,根据请求将不同大小的文件从服务器发送到客户端 我正在使用JavaSockets/ServerSockets来处理连接。我正在使用从socket.getOutputStream()获取的输出流向客户端发送数据。注意:我没有将套接字的输出流包装在BufferedOutputStream中 (我正在使用chrome调试器分析资源计时) 我看到的问题是,一个1285字节大小的文件(加上头和块编码)需要50毫秒以上的时间才能让c
Sockets
/ServerSockets
来处理连接。我正在使用从socket.getOutputStream()
获取的输出流向客户端发送数据。注意:我没有将套接字的输出流包装在BufferedOutputStream
中
(我正在使用chrome调试器分析资源计时)
我看到的问题是,一个1285字节大小的文件(加上头和块编码)需要50毫秒以上的时间才能让chrome接收请求的第一个字节。(Chrome报告TTFB约为50ms),然后是传输的快速剩余时间(1-2ms)(总传输时间约为52ms)
但是,如果我将文件大小增加到1286字节,TTFB将显著减少到~1ms(总传输时间~3ms)
我曾尝试在不同的点强制flush
刷新OutputStream
,包括在请求头之后、块之后,甚至在每个点尝试多个flush
调用只是为了好玩
我的问题:为什么与任何大于或等于1286字节的文件相比,小文件的传输时间要长得多?我能做些什么来解决这个性能问题
我的理论:底层套接字实现中的某些东西忽略了对
flush
底层套接字缓冲区的Java请求,尽管Java调用了flush()
禁用Nagle的算法可以解决此问题
这可能是因为您总是先测试小文件,然后再测试大文件,并且它可能正在尝试建立连接,您是否可以反过来尝试(先发送大文件,然后发送小文件)看看你是否得到了同样的结果?我刚刚更新了这个问题,以澄清这是一个web服务器类型的应用程序,因此文件在不同的时间被请求。chrome调试器将连接开销拆分为图表的一个单独部分,因此我看到的等待时间不包括任何文件的连接开销。我建议添加一个
BufferedOutputStream
,并删除除最后一个之外的所有刷新,重要的指标不是到第一个字节的时间,而是到最后一个字节的时间。我更新了问题,以显示每个场景中的“总传输时间”。不幸的是,将BufferedOutputStream
添加到混合中只会增加响应的额外延迟。因为在这种情况下,我既有本机套接字缓冲,也有java流缓冲。其他的东西只是测试用的。将打开TCP\u节点延迟
一次。