Go 1.24 サーバーでの HTTP/2 クリアテキストを使用

2026/05/20 1:40

Go 1.24 サーバーでの HTTP/2 クリアテキストを使用

RSS: https://news.ycombinator.com/rss

要約

Japanese Translation:

Google Cloud Run は、HTTP/1.1 を使用して Server-Sent Event (SSE) ストリームを扱う際に困難に直面し、フロントエンドで TLS が終端されるため、 prematurely な接続切断を頻発させます。最も効果的な解決策は、RFC 9113 セクション 3.3 に従い「HTTP/2 with Prior Knowledge」を実装することです。

コード変更:

  • Go 1.24 の前: ハンドラーを
    h2c.NewHandler
    でラップし、特定のタイムアウトを設定する必要がありました(例:
    IdleTimeout: 620s
    )。
  • Go 1.24+: ネイティブサポートにより
    h2c
    ラッパーを使用する必要がなくなります。開発者は現在、
    srv.Protocols = new(http.Protocols)
    を直接使用してプロトコルを設定できます(
    SetHTTP1(true)
    で HTTP/1、
    SetUnencryptedHTTP2(true)
    で非暗号化の HTTP/2 を有効に)。これにより、SSE ストリームを最大 900s に対応させるために 30 分のリクエストタイムアウトを設定することが可能です。

インフラストラクチャ (Terraform): これらの長寿命な接続をサポートするために、Cloud Run サービスの設定を更新してください:

invoker_iam_disabled = true
を設定し、
INGRESS_TRAFFIC_INTERNAL_LOAD_BALANCER
を使用し、特に
request_timeout
を "900s" に増強(デフォルトは 300s)してください。Serverless NEG はデフォルトで後端のタイムアウトが 60 分であり、標準的な 30 秒の制限はここでは適用されません。負荷分散装置の変更は不要であり、LB はネゴシエーション時に HTTP/2 アップグレードを処理します。ローカルでのテストは
curl -i --http2-prior-knowledge
を使用して検証できます。

本文

HTTP/2 クリアテキスト (h2c) を導入して SSE ストリームの安定性を確保する

アプリケーションは、15 分間の生存期間を有する長時間継続的なサーバーサイドイベント(SSE)ストリームを利用しています。しかし、バックエンドとの通信に

HTTP/1.1
を使用している場合、Google Cloud Run ではクライアントからの切断イベントがサービス側に正しく伝播しないという既知の課題が存在します。

この事情を踏まえ、**HTTP/2 クリアテキスト(h2c)**の導入を検討・実装することになりました。

技術的背景と概要

Cloud Run はフロントエンド側で TLS を終端させる仕様ですが、内部トラフィックは以下のいずれかで転送可能です。

  • HTTP/1.1
  • HTTP/2 クリアテキスト (h2c)

通常、HTTP/2 は TLS と組み合わせて使用されますが、Go の

http.Server
ではプロトコルのクリアテキストバージョンを使用するように構成可能(「事前知識に基づいた HTTP/2」)です。Cloud Run においては、この特定のプロトコルを選択する必要があるため、実質的には RFC 9113 セクション 3.3 に記載される設定を実現します。


Go サーバー側の設定方法

Go 1.24 以前:旧手法(移行参考)

Go 1.24 以前では、h2c のサポートには

golang.org/x/net/http2
パッケージを使用した複雑なセットアップが必須でした。現在は古く过时していますが、参考資料として記載します。

コード例

import (
	"fmt"
	"net/http"
	"time"
	"golang.org/x/net/http2"
	"golang.org/x/net/http2/h2c"
)

// handler := ... // 既存のハンドラーを作成

// 1. HTTP/2 サーバーの設定を作成
h2s := &http2.Server{}

// 2. ハンドラーを h2c.NewHandler でラップ
handler = h2c.NewHandler(handler, h2s)

// 3. http.Server の設定
srv := &http.Server{
	Addr:              fmt.Sprintf("%s:%d", "0.0.0.0", 9888),
	Handler:           handler,
	ReadHeaderTimeout: 5 * time.Second,
	ReadTimeout:       10 * time.Second,
	WriteTimeout:      35 * time.Second,
	IdleTimeout:       620 * time.Second, // 長時間継続する SSE コネクションのために最適化
}

// 4. サーバー上で事前知識に基づいた HTTP/2 を有効化
err := http2.ConfigureServer(srv, h2s)
if err != nil {
	// エラー処理を行う
}

Go 1.24+:新手法(推奨)

Go 1.24 では、

x/net/http2/h2c
ラッパーパッケージが不要となり、プロトコル設定を
http.Server
のストラクチャに直接行うことができます。コードがよりクリーンで読みやすくなっています。

コード例

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

// handler := ... // 既存のハンドラーを作成

srv := &http.Server{
	Addr:              fmt.Sprintf("%s:%d", "0.0.0.0", 9888),
	Handler:           handler,
	ReadHeaderTimeout: 5 * time.Second,
	ReadTimeout:       10 * time.Second,
	WriteTimeout:      35 * time.Second,
	IdleTimeout:       620 * time.Second,
}

// http.Server に直接プロトコルを設定
srv.Protocols = &http.Protocols{}
srv.Protocols.SetHTTP1(true)
srv.Protocols.SetUnencryptedHTTP2(true) // HTTP/2 クリアテキスト(h2c)を有効化

ローカル環境での検証

セットアップが正しく構築されていることを確認するため、HTTP/2 クリアテキストが適切に設定されていない場合にこのコマンドが失敗することを事前に検証しておくことが重要です。

curl -i --http2-prior-knowledge http://localhost:9888

Cloud Run のデプロイ設定 (Terraform)

Go サーバー側で対応した後、Cloud Run 側においても同様の設定を行う必要があります。以下の Terraform スニペットは、本題以外の冗長な設定を省略したものです。

resource "google_cloud_run_v2_service" "api" {
  name                 = "api"
  location             = var.primary_region
  invoker_iam_disabled = true
  ingress              = "INGRESS_TRAFFIC_INTERNAL_LOAD_BALANCER"

  template {
    containers {
      # ... コンテナの定義内容 ...
      
      ports {
        name           = "h2c"
        container_port = 9888
      }
    }

    # デフォルトは 80;高い並行性を考慮して増量。
    max_instance_request_concurrency = 200
    
    # デフォルトは 300s;長時間継続する SSE コネクションに対応するために延長。
    timeout = "900s"
  }

  lifecycle {
    ignore_changes = [client, client_version, template[0].revision]
  }
}

まとめ

今回の改修により、以下のメリットが得られます。

  • ロードバランサーレベルでの大規模な変更は不要
    • Serverless NEGs との通信に HTTPS を使用しており、接続時に自動的に HTTP/2 にアップグレードする機能を持っているためです。
  • サーバーレス型バックエンド向けのデフォルトタイムアウトが有利
    • デフォルトタイムアウトは60 分と設定されており、従来の 30 秒とは異なります。
    • この長めのタイムアウトは、15 分間の SSE コネクションにとって有益な条件となります。

同じ日のほかのニュース

一覧に戻る →

2026/05/25 3:56

オーストラリアの週 4 日制研究データで生産性が向上したと示唆されました

## 日本語訳: *Nature* の『Humanities and Social Sciences Communications』に発表された新研究によると、4 日勤務週間の試行を継続しているオーストラリア企業のうち 15 社のうち 14 社が「100:80:100 モデル」(完全な給与、80% の労働時間、全出力)を採用していたことが示されています。デイキン大学のジョン・ホプキンス教授を筆頭に、2023 年初頭から 2024 年秋にかけて行われたインタビューでは、不動産管理、出版、ヘルスケア技術、法律、ソフトウェア開発など幅広い業界を対象としました。どの企業でも生産性は低下しておらず、6 つの企業で向上し、9 つの企業が出力を維持していました。1 社は大きな内部変化により試行から退出し、もう 1 つはすでに 8 年間のパイロットプログラムを実施済みでした。バーンアウトが主な要因となったのは 6 社で、これらは単なる収益だけでなく、離職率、欠勤日、病休日、メンタルヘルス休暇をモニタリングしました。これは、2025 年の『Beyond Blue』調査でも示されているように、オーストラリアの労働者の半数がバーンアウトを経験しており、特に若年層と親御さんにおいて顕著であることと整合しています。国際的には、200 社以上の英国企業と 45 社のドイツ企業(主に中小企業)が給与カットなしでこのモデルを採用しています。導入方法は業界のリズムや業種によって異なります:顧客接点を持つ組織は休暇日を分散させる傾向があり一方、医療、緊急サービス、物流、ホスピタリティなどの分野は構造的なスケジュール調整の課題に直面します。企業は不要な会議を削減し、タスクを自動化し、低価値な仕事を排除することでワークフローを合理化しています。批判者は、一部の短期的な利益が新奇効果によるものかもしれないと注意喚起しています。今後を見据え、AI は反復的なタスクを自動化して労働者が時間を取り戻すよう助け、単に日常の業務量を増やすのではなく、将来の成功はウェルビーイングと離職防止を追跡することによって実現されると考えられています。全体としての変化は、効率性と並んで人間のウェルビーイングを最優先とする持続可能なパターンの方向へと向かっています。

2026/05/21 9:15

LAN-LOK:南极向け DOS サボタージュゲーム「34 年間も消失した」作

## Japanese Translation: AlphaPixel は、Mark Chappell および Shane Maloney という研究者により Palmer Station で作成された稀な 1991 年の南极観測ステーション用コンピューターゲーム「LAN-LOK」を成功裏に蘇らせた。本プロジェクトは、同ステーションで初めてのピアツーピア LAN(PalmerLAN/GrapeVine)の設置後に開発が行われた「Evil Al サボタージレース」というタイトルであり、30 年以上も知られていなかったところ、創業者である Chris Hanson が 2025 年に未開封のコピーを発見した。Hanson はその後にゲームの対抗役(悪の AI「Evil Al」)の実在のモデルとなった人物である Al Oxton(「ajo」氏)と連絡を取り、メールを通じて作成の詳細を確認させた。 このプロジェクトは、この廃棄された 16 ビットプログラムを現代的な遊べば良い体験へと変え、現在 Archive.org でアクセスでき、AlphaPixel 経由でダウンロード可能となっている。 gameplay は、プレイヤーがディレクトリを削除したりディスクをフォーマットしたりするなどのサボタージュ行為を行い、AI が制御する「Evil Al」と対戦しながら、特定のターゲット(例:重要な"Hobbs"ノード)への攻撃と勝利に必要なスコア要件を満たすことを目指す 5 分のレースである。長期的な存続性を確保するため、AlphaPixel は Ghidra や Reko といったリバースエンジニアリングツールを用いてレガシーコードのデコンパイルを行い、16 ビットシステムと 64 ビットシステム間の互換性問題を解決するとともに、SDL フレームワークを使用してグラフィックおよび入力処理を更新している。また AI ツールの活用も行う可能性がある。この取り組みは単に南极からユニークなデジタルアーティファクトを救い出しただけでなく、AlphaPixel の広範なレガシーデータの復元に関する専門性を示しており、8 ビットデバイスから現代の RISC-V プロセッサに至るまでのさまざまなアーキテクチャにおいて、エミュレーションされたゲームからフォレンジック動画の回復まで幅広く対応できることを証明している。

2026/05/25 3:39

Jujutsu で Git Rigour Fatigue を克服する

## Japanese Translation: 著者は、コードレビューを「種類別(例:赤で変更内容、青で UI)」に分類し、履歴を確定させる前に視覚的なワークフローを採用するためのステブのジュジュツチュートリアルへの相談を推奨しています。このアプローチは、デバッグによる修正とリファクタリングを単一のブランチ内で混在させるという一般的な誤り(コミットが以前の作業を上書きすることで頻発するコンフリクト)を回避します。標準ツールである `jj absorb`(ファイルの所有者との相性が悪いため課題が多い)や厳格なシーケンシング手法とは異なり、この手法では中間ステップごとにコンパイルしなくてもよい、当初はごちゃまぜの「全コミット」を受け入れることで一時的なデバッグ状態を許容します。ターゲット対象となるクイッシュコマンドを最終段階に留め、特定の変更カテゴリを色分けされた独自のコミットに分離することにより、Git のシーケンシングや複雑な分割の堅牢性を伴わずとも清潔で視覚的な履歴を実現できます。この戦略は、開発中の各個々のコミットがコンパイル可能であるという保証を犠牲にしますが、厳格なステップバイステップのコンパイル要件よりも、明確な視覚的なソートと管理可能なレビュー単位を重視するチームにとって、軽量で柔軟な代替手段を提供します。

Go 1.24 サーバーでの HTTP/2 クリアテキストを使用 | そっか~ニュース