目次

    Goエンジニアなら押さえておきたいネットワークの基礎知識|HTTPからTCP/IPまで
    GoネットワークTCP/IPHTTPDNS標準ライブラリ
    202507-09
    Goとネットワークの階層モデルを示す図:HTTP、TCP/UDP、IP、DNSの関係性を可視化

    Goエンジニアなら押さえておきたいネットワークの基礎知識|HTTPからTCP/IPまで

    導入:あなたのhttp.Get()の裏側、説明できますか?

    私たちは毎日net/httpパッケージを使っています。しかしhttp.Get("https://example.com")の一行が実行された瞬間、内部では一体何が起きているのでしょうか?

    この一行の背後では、DNS,TCP,TLS,HTTPといった複数のネットワーク層にまたがる複雑な処理が実行されています。この記事では、Goエンジニアが知るべきネットワークの基本階層を、Goの標準ライブラリと関連付けながら探訪していきます。


    Goと学ぶネットワークの階層モデル

    ① アプリケーション層:net/httpの世界

    役割: 私たちが直接やり取りするプロトコル(HTTP,DNSなど)の層。「何を」「どのような形式で」やり取りするかを定義します。

    Goとの関連: net/httpパッケージがこの層の複雑さを抽象化しています。

    ② トランスポート層:netパッケージとTCP/UDP

    役割: アプリケーション間の、実際のデータ転送を担う層。データの「届け方」を定義します。

    • TCP 信頼性重視の「電話」のようなプロトコル。HTTPなどで使われます。
    • UDP 速度重視の「ハガキ」のようなプロトコル。DNSなどで使われます(ただし512バイト超やDoT/DoHではTCP/HTTPSも利用)。

    Goとの関連: netパッケージが、これらのプロトコルを直接扱うためのインターフェースを提供しています。net/httpは内部でTCPを利用しています。

    go
    1// import "net"
    2
    3// TCPサーバーの例
    4listener, err := net.Listen("tcp", ":8080")
    5if err != nil {
    6    // エラーハンドリング
    7}
    8
    9// TCPクライアントの例
    10conn, err := net.Dial("tcp", "example.com:80")
    11if err != nil {
    12    // エラーハンドリング
    13}

    TCPの最適化例:http.Transport

    Go ネットワークプログラミングでは、デフォルトのhttp.Transportが内部でコネクションプールを実装しています。大量のリクエストを高速に捌くサービスでは、以下のようなチューニングが効果的です。

    go
    1tr := &http.Transport{
    2    MaxIdleConns:        100,
    3    MaxIdleConnsPerHost: 10,
    4    IdleConnTimeout:     90 * time.Second,
    5    DialContext: (&net.Dialer{
    6        Timeout:   30 * time.Second,
    7        KeepAlive: 30 * time.Second,
    8        // DualStackは Go 1.17以降非推奨(デフォルトで有効)
    9    }).DialContext,
    10    TLSHandshakeTimeout:   10 * time.Second,
    11    ExpectContinueTimeout: 1 * time.Second,
    12}
    13client := &http.Client{Transport: tr}

    Go 1.21以降のHappy Eyeballs事情

    net.DialerはデフォルトでIPv4/IPv6両方へ並列接続(Happy Eyeballs v2)を実施します。従来のDualStackフラグは非推奨になったため、特別な制御が必要な場合は'tcp4'/'tcp6'のネットワーク指定をご検討ください。

    ③ インターネット層:IPアドレス

    役割: 個々のコンピュータを識別し、最終的な宛先までデータを届けるための「住所」の役割を担う層。

    Goとの関連: Goのnet.IP型やnet.ParseIP()といった関数により、IPアドレスを安全に扱えます。

    IPv4/IPv6 dual-stackの実装例

    現代のGo TCP/IP入門では、IPv4とIPv6の併用が重要です。

    go
    1// IPv4/IPv6両対応のサーバー
    2listener, err := net.Listen("tcp", ":8080") // IPv4/IPv6両方でリッスン
    3if err != nil {
    4    log.Fatal(err)
    5}
    6
    7// 特定のIPバージョンを指定する場合
    8listener4, err := net.Listen("tcp4", ":8080") // IPv4のみ
    9listener6, err := net.Listen("tcp6", ":8080") // IPv6のみ

    実運用では、IPv6が利用できない環境での適切なフォールバック処理が重要になります。

    ④ 名前解決の仕組み:DNS

    役割: google.comのようなドメイン名を、IPアドレスに変換する、インターネットの「電話帳」です。

    Goとの関連: net.LookupHost()などの関数で、Goから直接DNSの名前解決を行えます。

    モダンなDNS事情

    現代のGo ネットワークプログラミングでは、以下のDNS技術も重要です:

    • DoH (DNS over HTTPS): プライバシー保護のためHTTPS経由でDNS問い合わせ(※クライアントまたはOSが対応している場合のみ利用可能)
    • DoT (DNS over TLS): TLS暗号化によるDNS通信(※クライアントまたはOSが対応している場合のみ利用可能)
    • EDNS0: 拡張DNS機能でより大きなレスポンスサイズに対応
    go
    1// DNSキャッシュを意識したルックアップ
    2resolver := &net.Resolver{
    3    PreferGo: true,
    4    Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
    5        d := net.Dialer{
    6            Timeout: time.Millisecond * 200,
    7        }
    8        return d.DialContext(ctx, network, "8.8.8.8:53")
    9    },
    10}
    11
    12ips, err := resolver.LookupHost(context.Background(), "example.com")
    13if err != nil {
    14    // エラーハンドリング
    15}

    全てが繋がる時:1つのリクエストの流れ

    http.Get("https://example.com")が実行される際の処理の流れを、シーケンス図で可視化します。

    HTTPリクエストの処理フロー図(テキスト説明)

    この図は、Goクライアントがhttp.Get()を実行する際の6つのステップを示しています:

    1. GoクライアントがDNSサーバーにドメイン名の解決を要求
    2. DNSサーバーがIPアドレスを返却
    3. GoクライアントがWebサーバーとTCP接続を確立
    4. TLSハンドシェイクによる暗号化通信の開始
    5. HTTP GETリクエストの送信
    6. Webサーバーからのレスポンス受信とTCP接続の処理
    mermaid
    1sequenceDiagram
    2    participant Client as Goクライアント
    3    participant DNS as DNSサーバー
    4    participant Server as Webサーバー
    5    
    6    Client->>DNS: 1. example.comのIPアドレス問い合わせ
    7    DNS-->>Client: IPアドレス返却
    8    Client->>Server: 2. TCP接続確立 (3-way handshake)
    9    Client->>Server: 3. TLSハンドシェイク
    10    Client->>Server: 4. HTTP GETリクエスト送信
    11    Server-->>Client: 5. HTTPレスポンス返却
    12    Client->>Server: 6. TCP接続クローズ (Keep-Alive時は再利用)

    詳細な処理ステップ:

    1. [DNS] example.comのIPアドレスを問い合わせる
    2. [TCP] 取得したIPアドレスの443番ポート(HTTPS)に対して、TCPコネクションを確立する
    3. [TLS] TCP上で、暗号化通信のためのTLSハンドシェイクを行う
    4. [HTTP] 暗号化されたTCPコネクション上で、HTTPのGETリクエストを送信する
    5. サーバーからHTTPレスポンスが返ってくる
    6. TCPコネクションを閉じる(Keep-Aliveが有効な場合は再利用される)

    Goでパフォーマンスを上げる3つの設定

    1. コネクションプールの最適化

    go
    1transport := &http.Transport{
    2    MaxIdleConns:        100,  // 全体のアイドル接続数
    3    MaxIdleConnsPerHost: 10,   // ホスト毎のアイドル接続数
    4    IdleConnTimeout:     90 * time.Second,
    5    // 注意:HTTP/2では設定項目が異なります
    6}

    注意: HTTP/2接続では、コネクションプールの動作が異なります。HTTP/2は単一接続で多重化を行うため、MaxIdleConnsPerHostの効果が限定的になる場合があります。

    2. タイムアウトの適切な設定

    go
    1client := &http.Client{
    2    Timeout: 30 * time.Second, // リクエスト全体のタイムアウト
    3    Transport: &http.Transport{
    4        DialContext: (&net.Dialer{
    5            Timeout: 5 * time.Second, // TCP接続タイムアウト
    6        }).DialContext,
    7        TLSHandshakeTimeout:   10 * time.Second, // TLSハンドシェイクタイムアウト
    8        ResponseHeaderTimeout: 10 * time.Second, // レスポンスヘッダータイムアウト
    9    },
    10}

    3. DNS解決の最適化

    go
    1// カスタムDialerでDNSキャッシュを活用
    2dialer := &net.Dialer{
    3    Timeout:   5 * time.Second,
    4    KeepAlive: 30 * time.Second,
    5    // DualStackは非推奨(Go 1.17以降デフォルトで有効)
    6}

    まとめ:なぜ基礎知識が「武器」になるのか

    普段使っているnet/httpパッケージが、DNS、TCP/IPといった技術の層の上に成り立っていることを理解することは、単なる知識の蓄積ではありません。

    このGo ネットワーク基礎知識を持つことで、パフォーマンス問題のボトルネックがどこにあるのか、より深いレベルでのトラブルシューティングが可能になります。これが、単なるライブラリの利用者から、システムの挙動を本質的に理解するエンジニアへと成長するための鍵です。

    今すぐ試せる実践ToDo

    1. 自分のアプリケーションのhttp.Transport設定を見直す
    2. DNS解決時間をtimeパッケージで計測してみる
    3. IPv6環境でのアプリケーション動作を確認する

    私たちGoForceはGo言語のスキルだけでなく、その土台となるコンピュータサイエンスの基礎知識を深く理解しているプロフェッショナルなエンジニアを高く評価しています。あなたのその「基礎体力」と「問題解決能力」は、クライアントが直面する最も困難な課題を解決する上で、大きな力となります。ぜひ一度、私たちにご相談ください。


    会員登録はこちら

    最適なGo案件を今すぐチェック!

    会員登録

    生年月日 *

    /

    /

    Go経験年数 *

    /

    利用規約プライバシーポリシーに同意してお申し込みください。