Fix service monitor connection leak
This commit is contained in:
18
services.go
18
services.go
@@ -74,6 +74,20 @@ type ServiceHistoryPoint struct {
|
|||||||
LatencyMS float64 `json:"latencyMs"`
|
LatencyMS float64 `json:"latencyMs"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var serviceHTTPTransport = &http.Transport{
|
||||||
|
Proxy: http.ProxyFromEnvironment,
|
||||||
|
DialContext: (&net.Dialer{Timeout: 10 * time.Second, KeepAlive: 30 * time.Second}).DialContext,
|
||||||
|
ForceAttemptHTTP2: true,
|
||||||
|
MaxIdleConns: 32,
|
||||||
|
MaxIdleConnsPerHost: 2,
|
||||||
|
IdleConnTimeout: 30 * time.Second,
|
||||||
|
TLSHandshakeTimeout: 10 * time.Second,
|
||||||
|
ExpectContinueTimeout: time.Second,
|
||||||
|
TLSClientConfig: &tls.Config{InsecureSkipVerify: true, MinVersion: tls.VersionTLS12},
|
||||||
|
}
|
||||||
|
|
||||||
|
var serviceHTTPClient = &http.Client{Transport: serviceHTTPTransport}
|
||||||
|
|
||||||
func (s *Store) Services() ([]MonitoredService, error) {
|
func (s *Store) Services() ([]MonitoredService, error) {
|
||||||
rows, err := s.db.Query(`SELECT id,name,url,local_address,check_type,expected_code,expected_text,timeout_seconds,enabled FROM services ORDER BY id`)
|
rows, err := s.db.Query(`SELECT id,name,url,local_address,check_type,expected_code,expected_text,timeout_seconds,enabled FROM services ORDER BY id`)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -296,14 +310,12 @@ func checkServiceEndpoint(v MonitoredService, kind, label, target string) Servic
|
|||||||
st.Error = strings.TrimSpace(string(out))
|
st.Error = strings.TrimSpace(string(out))
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
tr := &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true, MinVersion: tls.VersionTLS12}}
|
|
||||||
client := &http.Client{Transport: tr, Timeout: time.Duration(v.TimeoutSeconds) * time.Second}
|
|
||||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, target, nil)
|
req, err := http.NewRequestWithContext(ctx, http.MethodGet, target, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
st.Error = err.Error()
|
st.Error = err.Error()
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
resp, err := client.Do(req)
|
resp, err := serviceHTTPClient.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
st.Error = err.Error()
|
st.Error = err.Error()
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import "testing"
|
import (
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
func TestServiceCRUD(t *testing.T) {
|
func TestServiceCRUD(t *testing.T) {
|
||||||
store, err := openStore(":memory:")
|
store, err := openStore(":memory:")
|
||||||
@@ -38,3 +41,15 @@ func TestValidateServiceChecksBothHTTPAddresses(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestHTTPServiceTransportHasBoundedIdlePool(t *testing.T) {
|
||||||
|
if serviceHTTPClient.Transport != serviceHTTPTransport {
|
||||||
|
t.Fatal("проверки сервисов должны использовать общий HTTP transport")
|
||||||
|
}
|
||||||
|
if serviceHTTPTransport.IdleConnTimeout < time.Second {
|
||||||
|
t.Fatal("idle-соединения должны автоматически закрываться")
|
||||||
|
}
|
||||||
|
if serviceHTTPTransport.MaxIdleConnsPerHost < 1 || serviceHTTPTransport.MaxIdleConnsPerHost > 4 {
|
||||||
|
t.Fatalf("небезопасный размер пула на хост: %d", serviceHTTPTransport.MaxIdleConnsPerHost)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user