用 Golang 日志定位瓶颈,再按指标对 CentOS 网络做最小化调整,可快速提升稳定性与性能。下面给出一套可落地的闭环方案。
一、整体思路与关键指标
二、在 Golang 中埋点与输出结构化日志
package main
import (
"context"
"crypto/tls"
"log/slog"
"net"
"net/http"
"net/http/httptrace"
"time"
)
var log = slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelDebug}))
func timedHTTPGet(ctx context.Context, url string) error {
var dnsStart, dnsDone, connStart, connDone, tlsStart, tlsDone time.Time
var addr string
trace := &httptrace.ClientTrace{
DNSStart: func(i httptrace.DNSStartInfo) { dnsStart = time.Now(); slog.Debug("DNS start", "host", i.Host) },
DNSDone: func(i httptrace.DNSDoneInfo) {
dnsDone = time.Now()
slog.Debug("DNS done", "addrs", i.Addrs, "err", i.Err, "dns_ms", time.Since(dnsStart).Milliseconds())
},
ConnectStart: func(_, _ string) { connStart = time.Now() },
ConnectDone: func(_, addr string, err error) {
connDone = time.Now()
slog.Debug("Connect done", "addr", addr, "err", err, "connect_ms", time.Since(connStart).Milliseconds())
},
TLSHandshakeStart: func() { tlsStart = time.Now() },
TLSHandshakeDone: func(_ tls.ConnectionState, err error) {
tlsDone = time.Now()
slog.Debug("TLS done", "err", err, "tls_ms", time.Since(tlsStart).Milliseconds())
},
GotConn: func(i httptrace.GotConnInfo) { addr = i.Conn.RemoteAddr().String() },
}
ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
defer cancel()
req, _ := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
req = req.WithContext(httptrace.WithClientTrace(ctx, trace))
start := time.Now()
resp, err := http.DefaultClient.Do(req)
total := time.Since(start).Milliseconds()
status := 0
if resp != nil {
status = resp.StatusCode
defer resp.Body.Close()
}
log.Info("http_request",
"event", "http_request",
"url", url,
"method", http.MethodGet,
"status", status,
"remote_addr", addr,
"duration_ms", total,
"dns_ms", dnsDone.Sub(dnsStart).Milliseconds(),
"connect_ms", connDone.Sub(connStart).Milliseconds(),
"tls_ms", tlsDone.Sub(tlsStart).Milliseconds(),
"err", err,
)
return err
}
三、用系统日志与远程收集承载 Golang 日志
import "gopkg.in/natefinch/lumberjack.v2"
logger := slog.New(slog.NewJSONHandler(&lumberjack.Logger{
Filename: "/var/log/myapp/access.log",
MaxSize: 100, // MB
MaxBackups: 7,
MaxAge: 28, // days
Compress: true,
}, nil))
module(load="imudp")、input(type="imudp" port="514")module(load="imtcp")、input(type="imtcp" port="514")local0.* /var/log/golang.logsystemctl restart rsyslog四、根据日志指标优化 CentOS 网络配置
firewall-cmd --query-port=8080/tcp;必要时 firewall-cmd --permanent --add-port=8080/tcp && firewall-cmd --reload。export HTTP_PROXY=http://proxy:8080; export HTTPS_PROXY=https://proxy:8080。firewall-cmd --zone=public --add-port=8080/tcp --permanent && firewall-cmd --reload。setsebool -P httpd_can_network_connect 1(更细粒度可用 audit2allow 生成模块)。五、排障闭环与工具组合