Skip to content

コネクションプールとプロキシ

コネクションプール設定

コネクションプールは HTTP クライアントのパフォーマンスの重要な要素です。HTTPC は ConnectionConfig でコネクションプールを管理します。

go
cfg := httpc.DefaultConfig()

// コネクションプールパラメータ
cfg.Connection.MaxIdleConns = 100         // グローバル最大アイドル接続数
cfg.Connection.MaxConnsPerHost = 20       // ホストあたりの最大接続数
cfg.Timeouts.IdleConn = 120 * time.Second // アイドル接続維持時間

パラメータの説明

パラメータデフォルト説明
MaxIdleConns50グローバル最大アイドル接続数
MaxConnsPerHost10ホストあたりの最大接続数(アクティブ + アイドル含む)
IdleConn90sアイドル接続タイムアウト。超過するとクローズ
Dial10s接続確立タイムアウト
TLSHandshake10sTLS ハンドシェイクライムアウト
ResponseHeader0無効(Request タイムアウトを使用)

シナリオ別推奨

シナリオMaxIdleConnsMaxConnsPerHostIdleConn
高並列 API10020120s
通常サービス501090s
低頻度リクエスト10230s
マイクロサービス内部501060s

TIP

MaxConnsPerHost はアクティブ接続とアイドル接続の両方を含みます。この制限を超える新しいリクエストは接続の解放を待ってキューに入ります。

プロキシ

HTTPC は 4 つのプロキシモードをサポートし、優先度に従って自動的に選択されます。すべてのプロキシ設定は ConnectionConfig で構成します。

手動プロキシ

ProxyURL で固定プロキシを指定します(最高優先度):

go
cfg := httpc.DefaultConfig()
cfg.Connection.ProxyURL = "http://proxy.example.com:8080"

client, _ := httpc.New(cfg)

認証付きプロキシ:

go
cfg.Connection.ProxyURL = "http://user:[email protected]:8080"

TIP

Config.String() メソッドはプロキシ URL のユーザー名とパスワードを自動的にマスクします。

SOCKS5 プロキシ

go
cfg := httpc.DefaultConfig()
cfg.Connection.ProxyURL = "socks5://proxy.example.com:1080"

システムプロキシの自動検出

OS のプロキシ設定を自動的に検出します:

go
cfg := httpc.DefaultConfig()
cfg.Connection.EnableSystemProxy = true
プラットフォーム検出ソース
Windowsレジストリ Internet Settings
macOSシステム環境設定ネットワークプロキシ
Linux環境変数 HTTP_PROXY / HTTPS_PROXY

プロキシプール

複数のプロキシ IP にリクエストを分散する必要がある場合(スクレイピング、負荷分散、IP ローテーション)、プロキシプールは自動回転、パッシブサーキットブレーキング、ステータスコードベースの切り替えを提供します — 外部コンポーネント不要。

基本的な使い方

go
cfg := httpc.DefaultConfig()
cfg.Connection.ProxyPool = []string{
    "http://proxy1:8080",
    "http://proxy2:8080",
    "http://proxy3:8080",
}
cfg.Connection.ProxyPoolStrategy = httpc.ProxyStrategyRoundRobin // デフォルト

client, err := httpc.New(cfg)

各リクエストはプールからプロキシを自動的に選択します。httphttpssocks5socks5h プロトコルをサポートします。

フィールドデフォルト説明
ProxyPool[]stringnilプロキシ URL のリスト
ProxyPoolStrategyProxyStrategyRoundRobin選択戦略
ProxyFailureThresholdint3(0 でフォールバック)連続失敗サーキットブレーク閾値
ProxyCooldowntime.Duration30s(0 でフォールバック)サーキットブレークプロキシのクールダウン
ProxyRotateOnStatus[]intnilプロキシ回転をトリガーするステータスコード

選択戦略

戦略定数説明
ラウンドロビンProxyStrategyRoundRobin順番に循環選択、リトライ時に自動的に次のプロキシに移動
ランダムProxyStrategyRandom正常なプロキシから均一にランダム選択

ラウンドロビン(デフォルト)はリトライ時に自動的に異なるプロキシ IP を選択します — 各リトライがカーソルを進め、自然に次のプロキシに移動します。

パッシブサーキットブレーキング

プロキシプールはパッシブヘルスチェックを内蔵しています。接続レベルの失敗(dial/TLS)のみがサーキットブレークをトリガーし、HTTP ステータスコードはトリガーしません:

text
プロキシ接続失敗

失敗カウント +1

連続失敗 ≥ ProxyFailureThreshold → サーキットオープン(回転から除外)

ProxyCooldown 待機 → ハーフオープンプローブ(回転に復元)

成功 → カウントリセット、サーキットクローズ
初回失敗 → サーキット再オープン
go
cfg.Connection.ProxyFailureThreshold = 5           // より寛容に、一時的な問題を許容
cfg.Connection.ProxyCooldown = 60 * time.Second    // より長いクールダウン

すべてのプロキシがサーキットブレークされた場合、クールダウンが最も短い(復元に最も近い)プロキシがフォールバックとして返され、即座に失敗することはありません。

ステータスコード回転

Cloudflare/WAF などの IP ブロックシナリオで — 特定のステータスコード返却時に自動的に異なるプロキシでリトライします:

go
cfg := httpc.DefaultConfig()
cfg.Connection.ProxyPool = []string{
    "http://proxy1:8080",
    "http://proxy2:8080",
    "http://proxy3:8080",
}
cfg.Connection.ProxyRotateOnStatus = []int{403}  // 403 受信時にプロキシ回転
cfg.Retry.MaxRetries = 3                          // リトライ有効化必須

client, err := httpc.New(cfg)

ステータスコード回転 ≠ サーキットブレーキング

ProxyRotateOnStatus でトリガーされた回転はプロキシをサーキットブレークしません — IP ブロックはターゲット固有であることが多いです(サイト A でブロックされたプロキシがサイト B では正常に動作する場合があります)。サーキットブレーキングは接続レベルの失敗のみでトリガーされます。Retry.MaxRetries > 0 が必要です。

ProxyRotateOnStatus が設定され、プールに複数のプロキシがある場合、リトライ予算が自動的に len(ProxyPool) - 1 に引き上げられます(MaxRetries 上限 10 で制限)、すべてのプロキシが試行される機会を保証します。

プロキシ優先度

複数のプロキシモードを同時に構成した場合、優先度に従って適用されます:

優先度設定動作
1(最高)ProxyURL常に指定されたプロキシを使用(単一プロキシモード)
2ProxyPoolプロキシプールで回転
3EnableSystemProxyシステムプロキシを自動検出
4(最低)なし直接接続

TIP

ProxyURLProxyPool を両方設定した場合、ProxyURL が有効になります。プロキシプールを使用するには、ProxyURL を空にしてください。

内蔵セキュリティ

プロキシ関連機能は以下のセキュリティ詳細を自動的に処理します — 手動構成不要:

  • SSRF免除: プロキシホストアドレスが自動的に SSRF 免除リストに追加され、プライベート IP チェックでブロックされません
  • 重複排除: 同一 host:port のエントリが自動的にマージされ、回転バイアスと重複カウントを防ぎます
  • URL 検証: すべてのプロキシ URL がセキュリティ検証されます(CRLF インジェクション防止、プロトコルホワイトリスト)

完全なフィールド説明は 設定 API — プロキシプール を参照してください。

DNS-over-HTTPS

DoH を有効にして DNS 解決遅延を削減し、DNS ハイジャックを防止:

go
cfg := httpc.DefaultConfig()
cfg.Connection.EnableDoH = true
cfg.Connection.DoHCacheTTL = 5 * time.Minute

デフォルトの DoH プロバイダー(優先度順):

プロバイダーアドレス説明
Cloudflare1.1.1.1/dns-query最速、プライバシー重視
Googledns.google/resolveグローバルカバレッジ
AliDNSdns.alidns.com/resolve中国地域最適化

TIP

DoH を有効にすると、DNS 解決結果が DoHCacheTTL の間キャッシュされます。すべての DoH プロバイダーが利用できない場合、システム DNS にフォールバックします。

HTTP/2

デフォルトで HTTP/2 が有効です(TLS が必要):

go
cfg := httpc.DefaultConfig()
cfg.Connection.EnableHTTP2 = false // HTTP/2 を無効化

HTTP/2 の特徴:

  • 多重化:単一接続で複数の並列リクエストを処理
  • ヘッダー圧縮:繰り返しヘッダーの転送を削減
  • サーバープッシュ

オブジェクトプール再利用

HTTPC は内部でエンジンのレスポンスオブジェクトと文字列ビルダーを sync.Pool で再利用し、GC 負荷を軽減します。Result 自体はリクエストごとに新規作成され、GC が自動的に回収します。

go
result, err := client.Get(url)
if err != nil {
    return err
}
// Result はリクエストごとに新規作成、GC が自動回収、手動解放不要

高並列シナリオでは、内部オブジェクトプールの再利用により GC 負荷を大幅に軽減できます。

並列リクエストパターン

go
func fetchAll(ctx context.Context, urls []string) ([]*httpc.Result, error) {
    results := make([]*httpc.Result, len(urls))
    errs := make([]error, len(urls))

    var wg sync.WaitGroup
    for i, url := range urls {
        wg.Add(1)
        go func(idx int, u string) {
            defer wg.Done()
            result, err := client.Request(ctx, "GET", u)
            results[idx] = result
            errs[idx] = err
        }(i, url)
    }
    wg.Wait()

    for _, err := range errs {
        if err != nil {
            return nil, err
        }
    }
    return results, nil
}

よくある問題

問題原因解決策
大量の TIME_WAITアイドル接続タイムアウトが短すぎるIdleConn タイムアウトを増加
接続拒否ホストあたりの接続数が不足MaxConnsPerHost を増加
リクエストがキューで待機コネクションプールが小さすぎるMaxIdleConns を増加
プロキシが動作しないProxyURLProxyPool を同時設定ProxyURL を空にし、ProxyPool のみ使用
プロキシが頻繁にサーキットブレークProxyFailureThreshold が低すぎる閾値または ProxyCooldown を増加

完全なパフォーマンスアンチパターンと最適化の提案は パフォーマンス最適化 をご覧ください。

次のステップ