diff --git a/command/agent/check.go b/command/agent/check.go index ef0eea3ad1..bae76ca5d2 100644 --- a/command/agent/check.go +++ b/command/agent/check.go @@ -286,15 +286,24 @@ func (c *CheckHTTP) Start() { defer c.stopLock.Unlock() if c.httpClient == nil { + // Create the transport. We disable HTTP Keep-Alive's to prevent + // failing checks due to the keepalive interval. + trans := *http.DefaultTransport.(*http.Transport) + trans.DisableKeepAlives = true + + // Create the HTTP client. + c.httpClient = &http.Client{ + Timeout: 10 * time.Second, + Transport: &trans, + } + // For long (>10s) interval checks the http timeout is 10s, otherwise the // timeout is the interval. This means that a check *should* return // before the next check begins. if c.Timeout > 0 && c.Timeout < c.Interval { - c.httpClient = &http.Client{Timeout: c.Timeout} + c.httpClient.Timeout = c.Timeout } else if c.Interval < 10*time.Second { - c.httpClient = &http.Client{Timeout: c.Interval} - } else { - c.httpClient = &http.Client{Timeout: 10 * time.Second} + c.httpClient.Timeout = c.Interval } } @@ -325,7 +334,6 @@ func (c *CheckHTTP) run() { c.check() next = time.After(c.Interval) case <-c.stopCh: - http.DefaultTransport.(*http.Transport).CloseIdleConnections() return } } diff --git a/command/agent/check_test.go b/command/agent/check_test.go index b55d5a6580..3fbd0ff97a 100644 --- a/command/agent/check_test.go +++ b/command/agent/check_test.go @@ -305,3 +305,19 @@ func TestCheckHTTPTimeout(t *testing.T) { t.Fatalf("should be critical %v", mock.state) } } + +func TestCheckHTTP_disablesKeepAlives(t *testing.T) { + check := &CheckHTTP{ + CheckID: "foo", + HTTP: "http://foo.bar/baz", + Interval: 10 * time.Second, + Logger: log.New(os.Stderr, "", log.LstdFlags), + } + + check.Start() + defer check.Stop() + + if !check.httpClient.Transport.(*http.Transport).DisableKeepAlives { + t.Fatalf("should have disabled keepalives") + } +}