一、TCP层:高性能服务器的基石

Go的net包封装了BSD Socket API,提供了优雅的并发模型。所有HTTP服务本质上都是TCP服务器。理解TCP层参数调优,是构建高性能Go服务的关键第一步。

1.1 TCP连接建立与backlog

package main

import (
	"fmt"
	"net"
	"net/http"
	"runtime"
	"time"
)

// TCP连接建立的三个队列(理解backlog的关键):

/*
  客户端                    服务器内核                     应用层(listen fd)
    |                          |                              |
    |-- SYN (seq=x) --------->|                              |
    |   (客户端进入SYN_SENT)   |-- 进入半连接队列(1) ---------> listen fd
    |<-- SYN+ACK (seq=y,ack=x+1)--                             |
    |-- ACK (ack=y+1) -------->|                              |
    |                          |-- 移到全连接队列(2) ---------> listen fd
    |                          |                              |---[    ][    ][    ]
    |<------------------------- accept()拿走 ------------------|   ↑     ↑     ↑

  Linux 2.2之前:backlog控制两个队列的总和
  Linux 2.2之后:分别控制
    - 半连接队列: /proc/sys/net/ipv4/tcp_max_syn_backlog
    - 全连接队列: min(backlog, /proc/sys/net/core/somaxconn)
  Go默认backlog = 0 → 使用默认值128
*/

// 高性能HTTP服务器配置
func newHighPerfServer() *http.Server {
	return &http.Server{
		Addr:              ":8080",
		ReadTimeout:       30 * time.Second,
		ReadHeaderTimeout: 10 * time.Second, // 防Slow Loris攻击
		WriteTimeout:     30 * time.Second,
		IdleTimeout:      120 * time.Second,
		MaxHeaderBytes:   1 << 20,
	}
}

// TCP keepalive配置
func configureKeepAlive(conn net.Conn) error {
	if tcpConn, ok := conn.(*net.TCPConn); ok {
		return tcpConn.SetKeepAlive(true)
	}
	return nil
}
backlog实践经验:在Kubernetes环境中,somaxconn默认只有128。推荐生产环境设置:sysctl -w net.core.somaxconn=65535。如果需要精确控制Go服务的backlog,建议使用net.Listen配合系统调用,或在nginx层做代理。

1.2 连接池与复用

package netpool

import (
	"net"
	"sync"
	"time"
)

type ConnPool struct {
	addr    string
	pool    chan net.Conn
	mu      sync.Mutex
	active  int
	maxOpen int
	maxIdle int
}

type PoolConfig struct {
	MaxOpen int
	MaxIdle int
}

func NewConnPool(addr string, cfg PoolConfig) *ConnPool {
	return &ConnPool{
		addr:    addr,
		pool:    make(chan net.Conn, cfg.MaxIdle),
		maxOpen: cfg.MaxOpen,
		maxIdle: cfg.MaxIdle,
	}
}

func (p *ConnPool) Get() (net.Conn, error) {
	select {
	case conn := <-p.pool:
		return conn, nil
	default:
	}

	p.mu.Lock()
	if p.active >= p.maxOpen {
		p.mu.Unlock()
		conn, err := <-p.pool
		return conn, err
	}
	p.active++
	p.mu.Unlock()

	return net.DialTimeout("tcp", p.addr, 5*time.Second)
}

func (p *ConnPool) Put(conn net.Conn) {
	if conn == nil {
		p.mu.Lock()
		p.active--
		p.mu.Unlock()
		return
	}
	select {
	case p.pool <- conn:
		return
	default:
		p.mu.Lock()
		p.active--
		p.mu.Unlock()
		conn.Close()
	}
}

二、HTTP/2:现代Web性能的核心

HTTP/2通过多路复用、头部压缩、服务器推送等特性,彻底改变了Web性能。Go的net/http包从Go 1.6开始完整支持HTTP/2,是目前最成熟的HTTP/2实现之一。

2.1 HTTP/2核心特性与Go实现

package main

import (
	"crypto/tls"
	"fmt"
	"golang.org/x/net/http2"
	"net/http"
)

// HTTP/2必须通过HTTPS运行(ALPN协商)
// Go自动为HTTPS Server启用HTTP/2(无需额外配置)

func newHTTP2Server() *http.Server {
	return &http.Server{
		Addr: ":8443",
		TLSConfig: &tls.Config{
			MinVersion: tls.VersionTLS12,
			CurvePreferences: []tls.CurveID{
				tls.CurveP256,
				tls.X25519,
			},
			CipherSuites: []uint16{
				tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
				tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
				tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
				tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
			},
		},
	}
}

// HTTP/2服务器配置(使用http2包精细控制)
func newHTTP2ServerWithConfig() *http.Server {
	srv := &http.Server{
		Addr: ":8443",
	}

	// 显式配置HTTP/2(对于h2c明文HTTP/2必须)
	http2srv := &http2.Server{
		MaxConcurrentStreams: 250,   // 单连接最大并发流(默认250)
		MaxReadFrameSize:     1 << 20, // 最大帧大小(默认16KB)
		IdleTimeout:          5 * 60e9, // 空闲超时(纳秒)
		MaxUploadBufferPerConnection: 1 << 20,
		MaxUploadBufferPerStream:    1 << 18,
	}

	http2 ConfigureServer(srv, http2srv)
	return srv
}

// 手动配置HTTP/2 ClientTransport
func newHTTP2Client() *http.Client {
	return &http.Client{
		Transport: &http2.Transport{
			// 禁用 CONNECT 请求(用于代理)
			AllowHTTP: false,
			// 为每个主机名建立独立连接池
			// (同主机多请求复用同一个TCP连接上的多个流)
			PingIdleTimeout: 30 * 1e9,
		},
	}
}

// HTTP/2 vs HTTP/1.1性能对比(关键指标)
/*
  ┌──────────────────┬──────────────────┬──────────────────┐
  │     特性         │     HTTP/1.1     │     HTTP/2       │
  ├──────────────────┼──────────────────┼──────────────────┤
  │ 多路复用         │     无(pipelining不可靠)│ ✓ (stream) │
  │ 头部压缩         │     无           │ ✓ (HPACK)        │
  │ 服务器推送       │     无           │ ✓ (PUSH_PROMISE) │
  │ 流控制           │     无           │ ✓                 │
  │ 单连接多请求     │     需开多连接   │ ✓                 │
  │ 首部阻塞         │     HOLB问题     │ ✓ (帧级别优化)   │
  │ 握手延迟         │     1 RTT        │ ✓ (ALPN协商)     │
  └──────────────────┴──────────────────┴──────────────────┘

  HPACK头部压缩原理:
  - 静态表:61个预定义头部字段(如:method: GET)
  - 动态表:记录当前连接中出现过的头部值
  - 霍夫曼编码:高频字符使用更短编码
  - 效果:重复头部(如cookie、authorization)只传索引
*/

2.2 gRPC中的HTTP/2应用

package main

import (
	"context"
	"log"
	"net"
	"time"

	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials/insecure"
	"google.golang.org/grpc/encoding/gzip"
	"google.golang.org/grpc/keepalive"
)

// gRPC建立在HTTP/2之上,充分利用了HTTP/2的所有特性
// Protobuf序列化比JSON更紧凑,解析更快

func newGRPCServer() *grpc.Server {
	kaep := keepalive.EnforcementPolicy{
		MinTime:             5 * time.Minute,
		PermitWithoutStream: true,
	}
	kasp := keepalive.ServerParameters{
		MaxConnectionIdle:     10 * time.Minute,
		MaxConnectionAge:      2 * time.Hour,
		MaxConnectionAgeGrace: 1 * time.Minute,
		Time:                  1 * time.Hour,
		Timeout:               20 * time.Second,
	}

	// gRPC server配置
	srv := grpc.NewServer(
		grpc.KeepaliveEnforcementPolicy(kaep),
		grpc.KeepaliveParams(kasp),
		grpc.NumStreamWorkers(32), // 并发处理流的数量
	)

	return srv
}

// gRPC客户端连接池(高并发场景必需)
type GRPCPool struct {
	addrs   []string
	conns   []*grpc.ClientConn
	idx     int
	lb      RoundRobin
}

type RoundRobin struct {
	mu  sync.Mutex
	idx int
	n   int
}

func (r *RoundRobin) Next() int {
	r.mu.Lock()
	v := r.idx
	r.idx = (r.idx + 1) % r.n
	r.mu.Unlock()
	return v
}

func DialGRPCPool(addrs []string) (*GRPCPool, error) {
	pool := &GRPCPool{addrs: addrs, n: len(addrs)}
	for _, addr := range addrs {
		conn, err := grpc.Dial(addr,
			grpc.WithTransportCredentials(insecure.NewCredentials()),
			grpc.WithDefaultServiceConfig(`{"loadBalancingPolicy":"round_robin"}`),
			grpc.WithCompression(gzip.Name),
		)
		if err != nil {
			return nil, err
		}
		pool.conns = append(pool.conns, conn)
	}
	return pool, nil
}

import "sync"
HTTP/2 gRPC实战经验:在生产环境中,gRPC的HTTP/2优势在微服务间通信中体现得最明显——单连接多流避免了连接建立开销,HPACK大幅压缩重复header,Protobuf序列化比JSON快5-10倍且体积更小。建议:内部服务通信全部迁移到gRPC,对外API使用HTTP/2+JSON(兼容性考虑)。

三、ReverseProxy:构建高性能代理

Go的net/http/httputil.ReverseProxy是构建API网关、负载均衡器的核心工具。它设计精巧,支持流式转发、请求修改、负载均衡等场景。

3.1 ReverseProxy核心用法

package proxy

import (
	"fmt"
	"net/http"
	"net/http/httputil"
	"net/url"
	"strings"
	"time"
)

// 基础反向代理
func NewReverseProxy(target string) *httputil.ReverseProxy {
	targetURL, _ := url.Parse(target)

	director := func(req *http.Request) {
		req.URL.Scheme = targetURL.Scheme
		req.URL.Host = targetURL.Host
		req.Host = targetURL.Host

		// 修改请求路径(去除前缀)
		req.URL.Path = strings.TrimPrefix(req.URL.Path, "/api")
	}

	return &httputil.ReverseProxy{
		Director:       director,
		Transport:      &http.Transport{MaxIdleConns: 1000},
		FlushInterval:  200 * time.Millisecond, // 流式响应刷新间隔
		ModifyResponse:  nil,                    // 可修改响应
		ErrorHandler:   errorHandler,           // 自定义错误处理
	}
}

func errorHandler(w http.ResponseWriter, r *http.Request, err error) {
	// 优雅降级:后端服务不可用时返回友好错误
	w.WriteHeader(http.StatusBadGateway)
	fmt.Fprintf(w, `{"code":502,"message":"upstream error"}`)
}

// 带负载均衡的反向代理
type LoadBalancer struct {
	backends []*url.URL
	index    int
	mu       sync.Mutex
}

func (lb *LoadBalancer) Next() *url.URL {
	lb.mu.Lock()
	defer lb.mu.Unlock()
	backend := lb.backends[lb.index]
	lb.index = (lb.index + 1) % len(lb.backends)
	return backend
}

func (lb *LoadBalancer) NewProxy() *httputil.ReverseProxy {
	director := func(req *http.Request) {
		backend := lb.Next()
		req.URL.Scheme = backend.Scheme
		req.URL.Host = backend.Host
		req.Host = backend.Host
	}
	return &httputil.ReverseProxy{Director: director}
}

// 带健康检查的负载均衡
type HealthChecker struct {
	backends map[string]*BackendInfo
	mu       sync.RWMutex
}

type BackendInfo struct {
	URL       *url.URL
	Healthy   bool
	FailCount int
	Latency   time.Duration
}

func (hc *HealthChecker) Check() {
	hc.mu.Lock()
	defer hc.mu.Unlock()
	for _, b := range hc.backends {
		start := time.Now()
		resp, err := http.Head(b.URL.String())
		latency := time.Since(start)

		if err != nil || resp.StatusCode >= 500 {
			b.FailCount++
			if b.FailCount >= 3 {
				b.Healthy = false
			}
		} else {
			b.FailCount = 0
			b.Healthy = true
			b.Latency = latency
		}
	}
}

import "sync"

3.2 Zero-Copy优化

package zcopy

import (
	"io"
	"net"
	"net/http"
	"os"
	"strings"
)

// 传统方式:ReadAll + Write → 两次内存拷贝
func copyTraditional(w http.ResponseWriter, r *http.Request) {
	// 读取全部内容到内存(一次分配+拷贝)
	body, _ := io.ReadAll(r.Body)
	// 写回(又一次拷贝)
	w.Write(body)
}

// Zero-Copy方式:bytes.Buffer + io.Copy → 内核空间拷贝
// 最佳实践:静态文件使用http.ServeFile(使用sendfile系统调用)
func serveFileZeroCopy(w http.ResponseWriter, r *http.Request, path string) {
	http.ServeFile(w, r, path)
	// 内部使用os.Open + io.Copy
	// io.Copy在Linux上使用sendfile(2)系统调用
	// → 数据从磁盘缓存直接→socket,不经过用户态
}

// 高性能静态文件服务器配置
func newStaticFileServer() http.Handler {
	return http.FileServer(http.Dir("/var/www/static"))
}

// 管道式代理(最小化内存拷贝)
// httputil.ReverseProxy内部使用io.Copy实现零额外拷贝的流转发
func newStreamingProxy(target string) *httputil.ReverseProxy {
	targetURL, _ := url.Parse(target)
	return &httputil.ReverseProxy{
		Director: func(req *http.Request) {
			req.URL.Scheme = targetURL.Scheme
			req.URL.Host = targetURL.Host
		},
		// BufferPool减少buffer分配(Go 1.6+)
		BufferPool: newBufferPool(),
		// FlushInterval: -1 禁用自动flush(提高大文件传输性能)
		FlushInterval: -1,
	}
}

import (
	"net/url"
	"sync"
)

type bufferPool struct {
	pool sync.Pool
}

func newBufferPool() *bufferPool {
	return &bufferPool{
		pool: sync.Pool{
			New: func() interface{} {
				b := make([]byte, 32*1024) // 32KB buffer
				return &b
			},
		},
	}
}

// Linux sendfile系统调用路径(了解即可):
/*
  用户态: Go io.Copy
    ↓
  内核态: tcp_sendmsg (inet_sendmsg)
    ↓
  虚拟文件层: do_sendfile → vfs_read → ext4/xfs_read_page
    ↓
  磁盘/SSD → DMA → 内存
    ↓
  网卡驱动 → DMA描述符
    ↓
  网络线缆

  Zero-Copy关键:步骤4-6中,数据不经过用户态CPU,由DMA直接搬运
  对比传统IO: 磁盘→内核页缓存→用户态buffer→内核socket buffer→网卡
             (需要CPU参与中间每一步)
*/

// Unix Domain Socket代理(极高性能进程间通信)
func newUDSProxy(socketPath string) *httputil.ReverseProxy {
	return &httputil.ReverseProxy{
		Director: func(req *http.Request) {
			req.URL.Scheme = "http"
			req.URL.Host = "localhost" // 被UDS覆盖
		},
		Transport: &http.Transport{
			DialContext: func(ctx interface{}, addr string) (net.Conn, error) {
				var d net.Dialer
				return d.DialContext(ctx, "unix", socketPath)
			},
		},
	}
}
ReverseProxy调优注意事项:默认的ReverseProxy会修改请求Host头(从Director中设置),如果目标服务依赖X-Forwarded-For等头信息,需要显式转发原始头。proxy.Headers()方法(Go 1.11+)可以精细控制哪些头被转发。流式响应场景下,FlushInterval设置要权衡——太短影响性能,太长导致SSE/长轮询延迟。

四、rate.Limiter:精细化流量控制

高并发系统必须具备流量控制能力。Go标准库的golang.org/x/time/rate是生产级的令牌桶实现,支持单速率和双速率限流。

4.1 令牌桶算法与rate.Limiter

package ratelimit

import (
	"context"
	"fmt"
	"net/http"
	"time"

	"golang.org/x/time/rate"
)

// 令牌桶核心概念:
/*
  令牌桶 = 一个固定大小的桶,以固定速率r放入令牌
  每个请求消耗1个令牌,桶满时拒绝
  桶容量b = 突发大小(burst)

  ┌─────────────────────────────────────────────────────┐
  │  QPS = r(每秒r个请求)                              │
  │  Burst = b(可一次性处理b个并发请求)                │
  │                                                     │
  │  例如: limiter := NewLimiter(rate.Every(100ms), 10) │
  │  → 每100ms补充1个令牌,最多持有10个令牌              │
  └─────────────────────────────────────────────────────┘
*/

// 单节点限流器
type RateLimiter struct {
	limiter  *rate.Limiter
	burst    int
}

func NewRateLimiter(qps float64, burst int) *RateLimiter {
	return &RateLimiter{
		limiter: rate.NewLimiter(rate.Limit(qps), burst),
		burst:   burst,
	}
}

func (rl *RateLimiter) Allow() bool {
	return rl.limiter.Allow()
}

func (rl *RateLimiter) Wait(ctx context.Context) error {
	return rl.limiter.Wait(ctx)
}

// WaitN:一次消耗N个令牌(用于批处理场景)
func (rl *RateLimiter) WaitN(ctx context.Context, n int) error {
	return rl.limiter.WaitN(ctx, n)
}

// HTTP中间件:全局限流
func (rl *RateLimiter) Middleware(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if err := rl.Wait(r.Context()); err != nil {
			http.Error(w, "rate limit exceeded", http.StatusTooManyRequests)
			return
		}
		next.ServeHTTP(w, r)
	})
}

// 分布式限流:Redis + Lua(多节点共享限流)
/*
  Redis令牌桶实现(Lua保证原子性):

  local key = KEYS[1]
  local rate = tonumber(ARGV[1])  -- 每秒补充速率
  local capacity = tonumber(ARGV[2]) -- 桶容量
  local now = tonumber(ARGV[3])  -- 当前时间戳(毫秒)

  local fill_time = capacity / rate
  local ttl = math.floor(fill_time * 2)

  local last = tonumber(redis.call("HGET", key, "last") or now)
  local tokens = tonumber(redis.call("HGET", key, "tokens") or capacity)

  local delta = math.max(0, now - last)
  local filled = delta * rate / 1000
  tokens = math.min(capacity, tokens + filled)

  local allowed = 0
  if tokens >= 1 then
    tokens = tokens - 1
    allowed = 1
  end

  redis.call("HSET", key, "last", now)
  redis.call("HSET", key, "tokens", tokens)
  redis.call("EXPIRE", key, ttl)

  return allowed
*/

// 分层限流策略(推荐生产使用)
type TieredRateLimiter struct {
	global    *rate.Limiter  // 全局限流(保护后端)
	perIP     map[string]*rate.Limiter
	perIPMu   sync.Mutex
	perIPRate rate.Limit
}

func NewTieredLimiter(qps, perIPQps float64, burst int) *TieredRateLimiter {
	return &TieredRateLimiter{
		global:    rate.NewLimiter(rate.Limit(qps), burst),
		perIP:     make(map[string]*rate.Limiter),
		perIPRate: rate.Limit(perIPQps),
	}
}

func (t *TieredRateLimiter) Allow(ip string) bool {
	// 第一层:全局限流
	if !t.global.Allow() {
		return false
	}
	// 第二层:IP维限流(防止单IP打爆)
	t.perIPMu.Lock()
	limiter, exists := t.perIP[ip]
	if !exists {
		limiter = rate.NewLimiter(t.perIPRate, 10)
		t.perIP[ip] = limiter
	}
	t.perIPMu.Unlock()
	return limiter.Allow()
}

import "sync"

4.2 双速率限流:允许突发但限制平均

package ratelimit

import (
	"context"
	"fmt"

	"golang.org/x/time/rate"
)

// 双速率限流(Token Bucket + Leaky Bucket的混合)
// 也称为"允许突发但限制平均速率"

type BurstLimiter struct {
	limiter *rate.Limiter
}

func NewBurstLimiter(qps float64, burst int) *BurstLimiter {
	return &BurstLimiter{
		limiter: rate.NewLimiter(rate.Limit(qps), burst),
	}
}

// Reserve:预约令牌,返回等待时间
// 比Allow更精确,适用于需要知道等待多久的场景
func (rl *BurstLimiter) Reserve(ctx context.Context, n int) (wait time.Duration, allowed bool) {
	r := rl.limiter.ReserveN(time.Now(), n)
	if !r.OK() {
		return 0, false
	}
	wait = r.Delay()
	return wait, true
}

// 限流指标(用于监控和告警)
type RateLimitStats struct {
	allowed  int64
	rejected int64
}

func (s *RateLimitStats) Record(allowed bool) {
	if allowed {
		s.allowed++
	} else {
		s.rejected++
	}
}

func (s *RateLimitStats) RejectRate() float64 {
	total := s.allowed + s.rejected
	if total == 0 {
		return 0
	}
	return float64(s.rejected) / float64(total)
}

// 限流重试策略:使用retry-after头告知客户端
func RateLimitHandler(w http.ResponseWriter, r *http.Request, limiter *rate.Limiter) error {
	ctx := r.Context()
	if err := limiter.Wait(ctx); err != nil {
		retryAfter := 1 // 秒
		w.Header().Set("Retry-After", fmt.Sprintf("%d", retryAfter))
		http.Error(w, "rate limit exceeded", http.StatusTooManyRequests)
		return err
	}
	return nil
}

import "time"
限流策略选择:对于API网关,令牌桶(rate.Limiter)是最佳选择——允许短暂突发以应对流量尖刺,同时保证长期平均速率不超过阈值。对于消息队列消费者,漏桶更合适——以恒定速率消费,防止压垮下游。对于爬虫/外部调用,滑动窗口(Redis sorted set实现)提供最公平的限流体验。

五、完整高性能HTTP服务示例

综合以上所有技术,构建一个生产级高性能HTTP服务器。

package main

import (
	"context"
	"crypto/tls"
	"fmt"
	"log"
	"net/http"
	"net/http/httputil"
	"net/url"
	"os"
	"os/signal"
	"runtime"
	"syscall"
	"time"

	"golang.org/x/net/http2"
	"golang.org/x/time/rate"
)

// 生产级高性能服务器
type HighPerfServer struct {
	httpSrv   *http.Server
	httpsSrv  *http.Server
	proxy     *httputil.ReverseProxy
	rateLimit *rate.Limiter
}

func NewHighPerfServer() *HighPerfServer {
	// 后端服务地址
	backend, _ := url.Parse("http://127.0.0.1:8081")

	proxy := &httputil.ReverseProxy{
		Director: func(req *http.Request) {
			req.URL.Scheme = backend.Scheme
			req.URL.Host = backend.Host
			req.Header.Set("X-Forwarded-Host", req.Host)
			req.Header.Set("X-Real-IP", getClientIP(req))
		},
		BufferPool: newBufferPool(),
		Transport: &http.Transport{
			MaxConnsPerHost:     100,
			MaxIdleConns:        200,
			MaxIdleConnsPerHost: 10,
			IdleConnTimeout:     90 * time.Second,
			TLSHandshakeTimeout: 10 * time.Second,
		},
		FlushInterval: 200 * time.Millisecond,
		ErrorHandler: func(w http.ResponseWriter, r *http.Request, err error) {
			http.Error(w, "Bad Gateway", http.StatusBadGateway)
		},
	}

	return &HighPerfServer{
		proxy:     proxy,
		rateLimit: rate.NewLimiter(10000, 1000), // 10k QPS, burst 1000
	}
}

func getClientIP(r *http.Request) string {
	if fwd := r.Header.Get("X-Real-IP"); fwd != "" {
		return fwd
	}
	return r.RemoteAddr[:len(r.RemoteAddr)-len(":xxxx")]
}

type bufferPool struct{ pool chan []byte }

func newBufferPool() *bufferPool {
	pool := &bufferPool{make(chan []byte, 100)}
	for i := 0; i < 100; i++ {
		pool.pool <- make([]byte, 32*1024)
	}
	return pool
}

func (p *bufferPool) Get(size int) []byte {
	select {
	case b := <-p.pool:
		if cap(b) >= size {
			return b[:size]
		}
		return make([]byte, size)
	default:
		return make([]byte, size)
	}
}

func (p *bufferPool) Put(b []byte) {
	select {
	case p.pool <- b:
	default:
	}
}

func (s *HighPerfServer) Serve() error {
	runtime.GOMAXPROCS(runtime.NumCPU())

	// HTTP/1.1 + HTTP/2混合服务器
	s.httpSrv = &http.Server{
		Addr:              ":8080",
		Handler:          s.routes(),
		ReadTimeout:      30 * time.Second,
		ReadHeaderTimeout: 10 * time.Second,
		WriteTimeout:     60 * time.Second,
		IdleTimeout:      120 * time.Second,
		MaxHeaderBytes:   1 << 20,
	}

	// HTTPS/HTTP2服务器(同一端口,ALPN协商)
	tlsConfig := &tls.Config{
		MinVersion: tls.VersionTLS12,
		CurvePreferences: []tls.CurveID{
			tls.CurveP256, tls.X25519,
		},
		GetConfigForClient: func(hello *tls.ClientHelloInfo) (*tls.Config, error) {
			// HTTP/2的ALPN协商在这里生效
			return tlsConfig, nil
		},
	}

	s.httpsSrv = &http.Server{
		Addr:      ":8443",
		TLSConfig: tlsConfig,
		Handler:   s.routes(),
	}

	// 配置HTTP/2
	http2.ConfigureServer(s.httpsSrv, &http2.Server{
		MaxConcurrentStreams: 250,
		IdleTimeout:          5 * time.Minute,
	})

	// 启动服务器
	go func() {
		log.Printf("HTTP  server: http://:8080")
		log.Printf("HTTPS server: https://:8443")
	}()

	// 优雅关闭
	quit := make(chan os.Signal, 1)
	signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)

	go func() {
		if err := s.httpSrv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
			log.Fatalf("HTTP server error: %v", err)
		}
	}()

	go func() {
		if err := s.httpsSrv.ListenAndServeTLS("cert.pem", "key.pem"); err != nil && err != http.ErrServerClosed {
			log.Fatalf("HTTPS server error: %v", err)
		}
	}()

	<-quit
	log.Println("Shutting down...")

	ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
	defer cancel()

	s.httpSrv.Shutdown(ctx)
	s.httpsSrv.Shutdown(ctx)
	return nil
}

func (s *HighPerfServer) routes() http.Handler {
	mux := http.NewServeMux()

	// 限流端点
	mux.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) {
		if !s.rateLimit.Allow() {
			http.Error(w, "Rate limit", http.StatusTooManyRequests)
			return
		}
		fmt.Fprintln(w, "OK")
	})

	// 反向代理
	mux.HandleFunc("/api/", func(w http.ResponseWriter, r *http.Request) {
		if !s.rateLimit.Allow() {
			http.Error(w, "Rate limit", http.StatusTooManyRequests)
			return
		}
		s.proxy.ServeHTTP(w, r)
	})

	return mux
}

import "crypto/tls"
性能优化checklist:HTTP服务器优化顺序——(1)先用压测工具wrk/hey确认瓶颈;(2)关注CPU还是IO;(3)CPU-bound加GOMAXPROCS、减少GC压力;(4)IO-bound加连接池、使用HTTP/2、启用keep-alive;(5)瓶颈在后端→优化代理层+限流;(6)瓶颈在Go→检查sync.Pool是否正确使用。切忌:未测量的优化是徒劳的。