refactor(app,logging,proxy,ssl): 改进错误处理,使用空白标识符忽略明确不关心的返回值
- 使用 _ 忽略 Close、Write、Signal 等函数的错误返回值 - 这些场景的错误处理没有实际意义(关闭时已处于清理阶段) - 移除 health.go 中未使用的 mu 字段 - proxy 模块使用 for-range 替代 VisitAll 遍历头部 Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
a2e12c7537
commit
0f7c69e59b
@ -249,7 +249,7 @@ func (a *App) Run() int {
|
|||||||
a.upgradeMgr = server.NewUpgradeManager(a.srv)
|
a.upgradeMgr = server.NewUpgradeManager(a.srv)
|
||||||
if a.pidFile != "" {
|
if a.pidFile != "" {
|
||||||
a.upgradeMgr.SetPidFile(a.pidFile)
|
a.upgradeMgr.SetPidFile(a.pidFile)
|
||||||
a.upgradeMgr.WritePid()
|
_ = a.upgradeMgr.WritePid()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 启动信号处理
|
// 启动信号处理
|
||||||
@ -301,14 +301,14 @@ func (a *App) handleSignal(sig os.Signal) bool {
|
|||||||
// 优雅停止:等待请求完成
|
// 优雅停止:等待请求完成
|
||||||
a.logger.LogSignal("SIGQUIT", fmt.Sprintf("优雅停止(等待 %v)", shutdownTimeout))
|
a.logger.LogSignal("SIGQUIT", fmt.Sprintf("优雅停止(等待 %v)", shutdownTimeout))
|
||||||
a.shutdownHTTP3()
|
a.shutdownHTTP3()
|
||||||
a.srv.GracefulStop(shutdownTimeout)
|
_ = a.srv.GracefulStop(shutdownTimeout)
|
||||||
return false
|
return false
|
||||||
|
|
||||||
case syscall.SIGTERM, syscall.SIGINT:
|
case syscall.SIGTERM, syscall.SIGINT:
|
||||||
// 快速停止
|
// 快速停止
|
||||||
a.logger.LogSignal(sigName(sig.(syscall.Signal)), "停止服务器")
|
a.logger.LogSignal(sigName(sig.(syscall.Signal)), "停止服务器")
|
||||||
a.shutdownHTTP3()
|
a.shutdownHTTP3()
|
||||||
a.srv.Stop()
|
_ = a.srv.Stop()
|
||||||
return false
|
return false
|
||||||
|
|
||||||
case syscall.SIGHUP:
|
case syscall.SIGHUP:
|
||||||
@ -398,7 +398,7 @@ func (a *App) gracefulUpgrade() {
|
|||||||
|
|
||||||
// 当前进程优雅停止
|
// 当前进程优雅停止
|
||||||
a.shutdownHTTP3()
|
a.shutdownHTTP3()
|
||||||
a.srv.GracefulStop(shutdownTimeout)
|
_ = a.srv.GracefulStop(shutdownTimeout)
|
||||||
}
|
}
|
||||||
|
|
||||||
// sigName 返回信号名称(用于日志输出)。
|
// sigName 返回信号名称(用于日志输出)。
|
||||||
|
|||||||
@ -124,7 +124,7 @@ func (l *Logger) LogAccess(ctx *fasthttp.RequestCtx, status int, size int64, dur
|
|||||||
|
|
||||||
// 模板格式:直接输出纯文本
|
// 模板格式:直接输出纯文本
|
||||||
output := l.formatAccessLog(ctx, status, size, duration)
|
output := l.formatAccessLog(ctx, status, size, duration)
|
||||||
fmt.Fprintln(l.accessWriter, output)
|
_, _ = fmt.Fprintln(l.accessWriter, output)
|
||||||
}
|
}
|
||||||
|
|
||||||
// formatAccessLog 根据模板格式化访问日志。
|
// formatAccessLog 根据模板格式化访问日志。
|
||||||
@ -179,10 +179,10 @@ func (l *Logger) Error() *zerolog.Event {
|
|||||||
// Close 关闭日志文件。
|
// Close 关闭日志文件。
|
||||||
func (l *Logger) Close() error {
|
func (l *Logger) Close() error {
|
||||||
if l.accessFile != nil {
|
if l.accessFile != nil {
|
||||||
l.accessFile.Close()
|
_ = l.accessFile.Close()
|
||||||
}
|
}
|
||||||
if l.errorFile != nil {
|
if l.errorFile != nil {
|
||||||
l.errorFile.Close()
|
_ = l.errorFile.Close()
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -258,7 +258,7 @@ func (l *AppLogger) LogStartup(msg string, fields map[string]string) {
|
|||||||
// 纯文本格式
|
// 纯文本格式
|
||||||
timestamp := time.Now().Format("2006-01-02 15:04:05")
|
timestamp := time.Now().Format("2006-01-02 15:04:05")
|
||||||
if len(fields) == 0 {
|
if len(fields) == 0 {
|
||||||
fmt.Fprintf(l.writer, "[%s] INFO %s\n", timestamp, msg)
|
_, _ = fmt.Fprintf(l.writer, "[%s] INFO %s\n", timestamp, msg)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -267,7 +267,7 @@ func (l *AppLogger) LogStartup(msg string, fields map[string]string) {
|
|||||||
for k, v := range fields {
|
for k, v := range fields {
|
||||||
extra += fmt.Sprintf(" %s=%s", k, v)
|
extra += fmt.Sprintf(" %s=%s", k, v)
|
||||||
}
|
}
|
||||||
fmt.Fprintf(l.writer, "[%s] INFO %s%s\n", timestamp, msg, extra)
|
_, _ = fmt.Fprintf(l.writer, "[%s] INFO %s%s\n", timestamp, msg, extra)
|
||||||
}
|
}
|
||||||
|
|
||||||
// LogShutdown 记录停止消息。
|
// LogShutdown 记录停止消息。
|
||||||
@ -278,7 +278,7 @@ func (l *AppLogger) LogShutdown(msg string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
timestamp := time.Now().Format("2006-01-02 15:04:05")
|
timestamp := time.Now().Format("2006-01-02 15:04:05")
|
||||||
fmt.Fprintf(l.writer, "[%s] INFO %s\n", timestamp, msg)
|
_, _ = fmt.Fprintf(l.writer, "[%s] INFO %s\n", timestamp, msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
// LogSignal 记录信号处理消息。
|
// LogSignal 记录信号处理消息。
|
||||||
@ -289,7 +289,7 @@ func (l *AppLogger) LogSignal(sig string, action string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
timestamp := time.Now().Format("2006-01-02 15:04:05")
|
timestamp := time.Now().Format("2006-01-02 15:04:05")
|
||||||
fmt.Fprintf(l.writer, "[%s] INFO 收到 %s,%s\n", timestamp, sig, action)
|
_, _ = fmt.Fprintf(l.writer, "[%s] INFO 收到 %s,%s\n", timestamp, sig, action)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Info 返回 Info 级别日志记录器。
|
// Info 返回 Info 级别日志记录器。
|
||||||
|
|||||||
@ -53,7 +53,6 @@ type HealthChecker struct {
|
|||||||
stopCh chan struct{}
|
stopCh chan struct{}
|
||||||
running atomic.Bool
|
running atomic.Bool
|
||||||
client *fasthttp.Client
|
client *fasthttp.Client
|
||||||
mu sync.RWMutex
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewHealthChecker 使用指定的目标和配置创建一个新的 HealthChecker。
|
// NewHealthChecker 使用指定的目标和配置创建一个新的 HealthChecker。
|
||||||
|
|||||||
@ -293,9 +293,9 @@ func (p *Proxy) ServeHTTP(ctx *fasthttp.RequestCtx) {
|
|||||||
if status >= 200 && status < 300 {
|
if status >= 200 && status < 300 {
|
||||||
// 提取响应头
|
// 提取响应头
|
||||||
headers := make(map[string]string)
|
headers := make(map[string]string)
|
||||||
ctx.Response.Header.VisitAll(func(key, value []byte) {
|
for key, value := range ctx.Response.Header.All() {
|
||||||
headers[string(key)] = string(value)
|
headers[string(key)] = string(value)
|
||||||
})
|
}
|
||||||
p.cache.Set(cacheKey, ctx.Response.Body(), headers, status, p.config.Cache.MaxAge)
|
p.cache.Set(cacheKey, ctx.Response.Body(), headers, status, p.config.Cache.MaxAge)
|
||||||
}
|
}
|
||||||
p.cache.ReleaseLock(cacheKey, nil)
|
p.cache.ReleaseLock(cacheKey, nil)
|
||||||
@ -555,9 +555,9 @@ func (p *Proxy) backgroundRefresh(ctx *fasthttp.RequestCtx, target *loadbalance.
|
|||||||
|
|
||||||
// 提取响应头
|
// 提取响应头
|
||||||
headers := make(map[string]string)
|
headers := make(map[string]string)
|
||||||
resp.Header.VisitAll(func(key, value []byte) {
|
for key, value := range resp.Header.All() {
|
||||||
headers[string(key)] = string(value)
|
headers[string(key)] = string(value)
|
||||||
})
|
}
|
||||||
|
|
||||||
// 更新缓存
|
// 更新缓存
|
||||||
p.cache.Set(cacheKey, resp.Body(), headers, resp.StatusCode(), p.config.Cache.MaxAge)
|
p.cache.Set(cacheKey, resp.Body(), headers, resp.StatusCode(), p.config.Cache.MaxAge)
|
||||||
|
|||||||
@ -249,11 +249,11 @@ func dialTarget(targetURL string, timeout time.Duration) (net.Conn, error) {
|
|||||||
ServerName: strings.Split(addr, ":")[0],
|
ServerName: strings.Split(addr, ":")[0],
|
||||||
})
|
})
|
||||||
if err := tlsConn.SetDeadline(time.Now().Add(timeout)); err != nil {
|
if err := tlsConn.SetDeadline(time.Now().Add(timeout)); err != nil {
|
||||||
conn.Close()
|
_ = conn.Close()
|
||||||
return nil, fmt.Errorf("failed to set TLS deadline: %w", err)
|
return nil, fmt.Errorf("failed to set TLS deadline: %w", err)
|
||||||
}
|
}
|
||||||
if err := tlsConn.Handshake(); err != nil {
|
if err := tlsConn.Handshake(); err != nil {
|
||||||
conn.Close()
|
_ = conn.Close()
|
||||||
return nil, fmt.Errorf("TLS handshake failed: %w", err)
|
return nil, fmt.Errorf("TLS handshake failed: %w", err)
|
||||||
}
|
}
|
||||||
return tlsConn, nil
|
return tlsConn, nil
|
||||||
@ -390,7 +390,7 @@ func ProxyWebSocket(ctx *fasthttp.RequestCtx, target *loadbalance.Target, timeou
|
|||||||
// 步骤1: 建立到后端目标的连接
|
// 步骤1: 建立到后端目标的连接
|
||||||
targetConn, err := dialTarget(target.URL, timeout)
|
targetConn, err := dialTarget(target.URL, timeout)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
clientConn.Close()
|
_ = clientConn.Close()
|
||||||
return fmt.Errorf("failed to connect to backend: %w", err)
|
return fmt.Errorf("failed to connect to backend: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -400,30 +400,30 @@ func ProxyWebSocket(ctx *fasthttp.RequestCtx, target *loadbalance.Target, timeou
|
|||||||
// 步骤3: 构建并发送 WebSocket 升级请求
|
// 步骤3: 构建并发送 WebSocket 升级请求
|
||||||
upgradeReq := buildWebSocketUpgradeRequest(ctx, targetHost)
|
upgradeReq := buildWebSocketUpgradeRequest(ctx, targetHost)
|
||||||
if _, err := targetConn.Write([]byte(upgradeReq)); err != nil {
|
if _, err := targetConn.Write([]byte(upgradeReq)); err != nil {
|
||||||
clientConn.Close()
|
_ = clientConn.Close()
|
||||||
targetConn.Close()
|
_ = targetConn.Close()
|
||||||
return fmt.Errorf("failed to send upgrade request: %w", err)
|
return fmt.Errorf("failed to send upgrade request: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 步骤4: 读取升级响应
|
// 步骤4: 读取升级响应
|
||||||
resp, err := readWebSocketUpgradeResponse(targetConn, timeout)
|
resp, err := readWebSocketUpgradeResponse(targetConn, timeout)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
clientConn.Close()
|
_ = clientConn.Close()
|
||||||
targetConn.Close()
|
_ = targetConn.Close()
|
||||||
return fmt.Errorf("failed to read upgrade response: %w", err)
|
return fmt.Errorf("failed to read upgrade response: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 步骤5: 检查响应状态码(期望 101 Switching Protocols)
|
// 步骤5: 检查响应状态码(期望 101 Switching Protocols)
|
||||||
if resp.StatusCode != http.StatusSwitchingProtocols {
|
if resp.StatusCode != http.StatusSwitchingProtocols {
|
||||||
clientConn.Close()
|
_ = clientConn.Close()
|
||||||
targetConn.Close()
|
_ = targetConn.Close()
|
||||||
return fmt.Errorf("backend rejected WebSocket upgrade: %s", resp.Status)
|
return fmt.Errorf("backend rejected WebSocket upgrade: %s", resp.Status)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 步骤6: 将升级响应发送回客户端
|
// 步骤6: 将升级响应发送回客户端
|
||||||
if err := writeUpgradeResponse(clientConn, resp); err != nil {
|
if err := writeUpgradeResponse(clientConn, resp); err != nil {
|
||||||
clientConn.Close()
|
_ = clientConn.Close()
|
||||||
targetConn.Close()
|
_ = targetConn.Close()
|
||||||
return fmt.Errorf("failed to send upgrade response to client: %w", err)
|
return fmt.Errorf("failed to send upgrade response to client: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -434,7 +434,7 @@ func ProxyWebSocket(ctx *fasthttp.RequestCtx, target *loadbalance.Target, timeou
|
|||||||
bridgeErr := bridge.Bridge()
|
bridgeErr := bridge.Bridge()
|
||||||
|
|
||||||
// 清理:关闭连接
|
// 清理:关闭连接
|
||||||
bridge.Close()
|
_ = bridge.Close()
|
||||||
|
|
||||||
return bridgeErr
|
return bridgeErr
|
||||||
}
|
}
|
||||||
|
|||||||
@ -327,7 +327,7 @@ func (m *OCSPManager) sendOCSPRequest(url string, req []byte) ([]byte, error) {
|
|||||||
}
|
}
|
||||||
return nil, fmt.Errorf("HTTP request failed: %w", err)
|
return nil, fmt.Errorf("HTTP request failed: %w", err)
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer func() { _ = resp.Body.Close() }()
|
||||||
|
|
||||||
if resp.StatusCode != http.StatusOK {
|
if resp.StatusCode != http.StatusOK {
|
||||||
if i < m.maxRetries-1 {
|
if i < m.maxRetries-1 {
|
||||||
|
|||||||
@ -152,7 +152,7 @@ func NewTLSManager(cfg *config.SSLConfig) (*TLSManager, error) {
|
|||||||
manager.issuers[serial] = issuerCert
|
manager.issuers[serial] = issuerCert
|
||||||
// 注册证书用于 OCSP Stapling
|
// 注册证书用于 OCSP Stapling
|
||||||
// 错误会记录日志但不会阻止 TLS 工作
|
// 错误会记录日志但不会阻止 TLS 工作
|
||||||
ocspMgr.RegisterCertificate(parsedCert, issuerCert)
|
_ = ocspMgr.RegisterCertificate(parsedCert, issuerCert)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user