Looking at the trace from the server on windows vs one I did on my linux machine, there are
three things I notice.
1) There appears to be a smaller window on the windows box. IE acks are sent for the
data packet pretty soon after they are sent. With the linux server, data is sent WAY in
advance of acks being received.
2) The windows server never fills up it's sliding window. The linux server sends data
until the window is full and then waits a bit for acks. 3 to 10 ms is the typical wait.
3) Even without a full window, the windows server stops sending data and then there
is a long pause (200ms) until the client sends an ack. It looks like the client is waiting
for either some return data or a full window before sending the ack.
So there is something about how this data is being sent that is making the windows
TCP/IP stack work really really badly.
Nik - we need to do some experiments to see how we can affect this by making variations
in the aspects discussed below.
Because of the size of this file, it is probably being sent by the DefaultServlet
using the Resource.writeTo() method, which eventually uses the
IO.copy method. This has a buffer size of only 8192 for transfers. We should
try a much larger buffer size ... perhaps 32k
We can adjust the configuration of the DefaultServlet so that the file cache
will accept this file size and use a memoryMapped buffer. This should be
the fastest way to send data. Ifthis works, then we will have to review the
concept of file cace with regards to memory mapped buffers... or perhaps
have temporary mem mapped buffers for large files etc.
Look at the code in DefaultServlet.getContent(String,Resource)
Failing that - turn off useMemoryMapped buffers - so the whole massive
file gets loaded into memory and then served from cache. This is not
a good way to proceed, but will tell us if the problem is how we read the
data or how we write the data.
We should also see what the OS has set Socket.getSendBufferSize() at
for the two types of connector. We should then try setting it to bigger
values to see if that makes a difference. We should research how
big this should be, and potentially we should either make it directly
configurable or set it to the same size as the setResponseBufferSize
Nik - can you do the experiments - as I still don't have a good windows
machine I can use for this.