Avro
  1. Avro
  2. AVRO-1069

HttpTransceiver never closes its OutputStream, hinders java reuse of HTTP connections

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: 1.7.1
    • Component/s: java
    • Labels:
      None

      Description

      The class org.apache.avro.ipc.HttpTransceiver opens an OutputStream and never explicitly closes it. That seems like very bad behavior.

      I think you should also be closing the InputStream.

      In particular, Java has built-in the ability to keep HttpURLConnections open, and re-use them. You might think that not closing these streams would help Java in this effort, but actually, the streams are not the raw connections, but wrappers. The javadoc says: "Calling the close() methods on the InputStream or OutputStream of an HttpURLConnection after a request may free network resources associated with this instance but has no effect on any shared persistent connection."

      In other words, when you fail to close these streams, Java doesn't know you are done with the request, so it cannot re-use the connection. You only end up able to re-use the connection when the HttpURLConnection gets garbage-collected.

      1. AVRO-1069.patch
        1 kB
        Doug Cutting

        Activity

        Hide
        Thomas Andrews added a comment -

        When I rolled my own transceiver which was a copy of HttpTransceiver with close() calls to the InputStream and OutputStream added, I got much better connection re-use in Java. Specifically, in load test with four streams sending requests to the server, using Avro's HttpTransceiver, I used "netstat" to see that there were anywhere from 3-4 sockets open to handle the requests, but when I used my custom transceiver, it used only one socket for all four streams.

        Since Java (by default) has a maximum of 5 cached open connections, this means at slightly higher load, HttpTransceiver is going to be opening lots of one-shot sockets.

        Show
        Thomas Andrews added a comment - When I rolled my own transceiver which was a copy of HttpTransceiver with close() calls to the InputStream and OutputStream added, I got much better connection re-use in Java. Specifically, in load test with four streams sending requests to the server, using Avro's HttpTransceiver, I used "netstat" to see that there were anywhere from 3-4 sockets open to handle the requests, but when I used my custom transceiver, it used only one socket for all four streams. Since Java (by default) has a maximum of 5 cached open connections, this means at slightly higher load, HttpTransceiver is going to be opening lots of one-shot sockets.
        Hide
        Doug Cutting added a comment -

        Here's a patch that addresses this.

        Show
        Doug Cutting added a comment - Here's a patch that addresses this.
        Hide
        Doug Cutting added a comment -

        I'll commit this soon unless there are objections.

        Show
        Doug Cutting added a comment - I'll commit this soon unless there are objections.
        Hide
        Doug Cutting added a comment -

        I committed this.

        Show
        Doug Cutting added a comment - I committed this.

          People

          • Assignee:
            Doug Cutting
            Reporter:
            Thomas Andrews
          • Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development