Fix service monitor connection leak

This commit is contained in:
Maxim
2026-08-05 20:04:29 +03:00
parent a14001b373
commit c01b4b6630
2 changed files with 31 additions and 4 deletions

View File

@@ -74,6 +74,20 @@ type ServiceHistoryPoint struct {
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) {
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 {
@@ -296,14 +310,12 @@ func checkServiceEndpoint(v MonitoredService, kind, label, target string) Servic
st.Error = strings.TrimSpace(string(out))
}
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)
if err != nil {
st.Error = err.Error()
break
}
resp, err := client.Do(req)
resp, err := serviceHTTPClient.Do(req)
if err != nil {
st.Error = err.Error()
} else {

View File

@@ -1,6 +1,9 @@
package main
import "testing"
import (
"testing"
"time"
)
func TestServiceCRUD(t *testing.T) {
store, err := openStore(":memory:")
@@ -38,3 +41,15 @@ func TestValidateServiceChecksBothHTTPAddresses(t *testing.T) {
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)
}
}