Skip to content

Commit

Permalink
Enable HTTP Keepalive's to reduce number of TLS handshakes
Browse files Browse the repository at this point in the history
We found that when using Credhub with Concourse, there was a massive spike in
CPU usage. We profiled ATC (Concourse component that interacts with Credhub) and
found that >90% of samples were in TLS handshake methods. We did not profile
credhub, but presumably it was much the same.

This commit ensures HTTP response body's are read to completion, which is
required for net/http to reuse the connection and avoid a costly TLS handshake.
It also increases the maximum number of idle HTTP connections to 100, from the
default of 2, which is required to work around limitations in net/http:

golang/go#13801

Signed-off-by: Ife Runsewe <[email protected]>
  • Loading branch information
takeyourhatoff authored and Ife Runsewe committed Jul 6, 2018
1 parent 516d531 commit 7a03af3
Show file tree
Hide file tree
Showing 11 changed files with 35 additions and 2 deletions.
3 changes: 3 additions & 0 deletions credhub/auth/uaa/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"encoding/json"
"errors"
"fmt"
"io"
"io/ioutil"
"net/http"
"net/url"
Expand Down Expand Up @@ -79,6 +80,7 @@ func (u *Client) Metadata() (*Metadata, error) {
return nil, err
}
defer response.Body.Close()
defer io.Copy(ioutil.Discard, response.Body)

if response.StatusCode != 200 {
return nil, errors.New("unable to fetch metadata successfully")
Expand Down Expand Up @@ -167,6 +169,7 @@ func (u *Client) tokenGrantRequest(headers url.Values) (token, error) {
}

defer response.Body.Close()
defer io.Copy(ioutil.Discard, response.Body)

decoder := json.NewDecoder(response.Body)

Expand Down
3 changes: 3 additions & 0 deletions credhub/bulk_regenerate.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package credhub

import (
"encoding/json"
"io"
"io/ioutil"
"net/http"

"code.cloudfoundry.org/credhub-cli/credhub/credentials"
Expand All @@ -22,6 +24,7 @@ func (ch *CredHub) BulkRegenerate(signedBy string) (credentials.BulkRegenerateRe
}

defer resp.Body.Close()
defer io.Copy(ioutil.Discard, resp.Body)
dec := json.NewDecoder(resp.Body)
err = dec.Decode(&creds)

Expand Down
5 changes: 3 additions & 2 deletions credhub/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,9 @@ func httpsClient(insecureSkipVerify bool, rootCAs *x509.CertPool, cert *tls.Cert
Certificates: certs,
RootCAs: rootCAs,
},
Proxy: http.ProxyFromEnvironment,
Dial: dialer,
Proxy: http.ProxyFromEnvironment,
Dial: dialer,
MaxIdleConnsPerHost: 100,
}

return client
Expand Down
3 changes: 3 additions & 0 deletions credhub/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package credhub

import (
"encoding/json"
"io"
"io/ioutil"
"net/http"

"code.cloudfoundry.org/credhub-cli/credhub/credentials"
Expand Down Expand Up @@ -75,6 +77,7 @@ func (ch *CredHub) generateCredential(name, credType string, gen interface{}, ov
}

defer resp.Body.Close()
defer io.Copy(ioutil.Discard, resp.Body)
dec := json.NewDecoder(resp.Body)

if err := ch.checkForServerError(resp); err != nil {
Expand Down
5 changes: 5 additions & 0 deletions credhub/get.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package credhub
import (
"encoding/json"
"errors"
"io"
"io/ioutil"
"net/http"
"net/url"

Expand Down Expand Up @@ -114,6 +116,7 @@ func (ch *CredHub) makeCredentialGetRequest(query url.Values, cred interface{})
}

defer resp.Body.Close()
defer io.Copy(ioutil.Discard, resp.Body)
dec := json.NewDecoder(resp.Body)

response := make(map[string][]json.RawMessage)
Expand Down Expand Up @@ -142,6 +145,7 @@ func (ch *CredHub) makeCredentialGetByIdRequest(id string, cred *credentials.Cre
}

defer resp.Body.Close()
defer io.Copy(ioutil.Discard, resp.Body)
dec := json.NewDecoder(resp.Body)

if err := dec.Decode(cred); err != nil {
Expand All @@ -167,6 +171,7 @@ func (ch *CredHub) makeMultiCredentialGetRequest(query url.Values) ([]credential
}

defer resp.Body.Close()
defer io.Copy(ioutil.Discard, resp.Body)
dec := json.NewDecoder(resp.Body)

response := make(map[string][]credentials.Credential)
Expand Down
3 changes: 3 additions & 0 deletions credhub/info.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package credhub
import (
"encoding/json"
"errors"
"io"
"io/ioutil"

"code.cloudfoundry.org/credhub-cli/credhub/server"
)
Expand All @@ -16,6 +18,7 @@ func (ch *CredHub) Info() (*server.Info, error) {
}

defer response.Body.Close()
defer io.Copy(ioutil.Discard, response.Body)

info := &server.Info{}
decoder := json.NewDecoder(response.Body)
Expand Down
3 changes: 3 additions & 0 deletions credhub/permissions.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package credhub

import (
"io"
"io/ioutil"
"net/http"

"net/url"
Expand All @@ -26,6 +28,7 @@ func (ch *CredHub) GetPermissions(credName string) ([]permissions.Permission, er
}

defer resp.Body.Close()
defer io.Copy(ioutil.Discard, resp.Body)
var response permissionsResponse

if err := json.NewDecoder(resp.Body).Decode(&response); err != nil {
Expand Down
3 changes: 3 additions & 0 deletions credhub/regenerate.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package credhub

import (
"encoding/json"
"io"
"io/ioutil"
"net/http"

"code.cloudfoundry.org/credhub-cli/credhub/credentials"
Expand All @@ -24,6 +26,7 @@ func (ch *CredHub) Regenerate(name string) (credentials.Credential, error) {
}

defer resp.Body.Close()
defer io.Copy(ioutil.Discard, resp.Body)
dec := json.NewDecoder(resp.Body)
err = dec.Decode(&cred)

Expand Down
3 changes: 3 additions & 0 deletions credhub/request.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package credhub
import (
"bytes"
"encoding/json"
"io"
"io/ioutil"
"net/http"
"net/url"
)
Expand Down Expand Up @@ -65,6 +67,7 @@ func (ch *CredHub) request(client requester, method string, pathStr string, quer
func (ch *CredHub) checkForServerError(resp *http.Response) error {
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
defer resp.Body.Close()
defer io.Copy(ioutil.Discard, resp.Body)
dec := json.NewDecoder(resp.Body)

respErr := &Error{}
Expand Down
3 changes: 3 additions & 0 deletions credhub/server_version.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package credhub

import (
"encoding/json"
"io"
"io/ioutil"

"code.cloudfoundry.org/credhub-cli/credhub/server"
"github.com/hashicorp/go-version"
Expand Down Expand Up @@ -29,6 +31,7 @@ func (ch *CredHub) getVersion() (string, error) {
}

defer response.Body.Close()
defer io.Copy(ioutil.Discard, response.Body)

versionData := &server.VersionData{}
decoder := json.NewDecoder(response.Body)
Expand Down
3 changes: 3 additions & 0 deletions credhub/set.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package credhub

import (
"encoding/json"
"io"
"io/ioutil"
"net/http"

"code.cloudfoundry.org/credhub-cli/credhub/credentials"
Expand Down Expand Up @@ -92,6 +94,7 @@ func (ch *CredHub) setCredential(name, credType string, value interface{}, mode
}

defer resp.Body.Close()
defer io.Copy(ioutil.Discard, resp.Body)
dec := json.NewDecoder(resp.Body)
return dec.Decode(cred)
}

0 comments on commit 7a03af3

Please sign in to comment.