惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

P
Proofpoint News Feed
博客园_首页
WordPress大学
WordPress大学
大猫的无限游戏
大猫的无限游戏
有赞技术团队
有赞技术团队
阮一峰的网络日志
阮一峰的网络日志
Hugging Face - Blog
Hugging Face - Blog
博客园 - 【当耐特】
酷 壳 – CoolShell
酷 壳 – CoolShell
Y
Y Combinator Blog
Vercel News
Vercel News
The GitHub Blog
The GitHub Blog
T
The Blog of Author Tim Ferriss
云风的 BLOG
云风的 BLOG
博客园 - 司徒正美
Engineering at Meta
Engineering at Meta
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
J
Java Code Geeks
Stack Overflow Blog
Stack Overflow Blog
N
Netflix TechBlog - Medium
Martin Fowler
Martin Fowler
宝玉的分享
宝玉的分享
G
Google Developers Blog
Last Week in AI
Last Week in AI

Hacker News

GitHub - SeanFDZ/macmind: Single-layer transformer in HyperTalk for the classic Macintosh Show HN: Agent-cache – Multi-tier LLM/tool/session caching for Valkey and Redis Bonsai 1-bit WebGPU - a Hugging Face Space by webml-community Moving a large-scale metrics pipeline from StatsD to OpenTelemetry / Prometheus GitHub - Nightmare-Eclipse/RedSun: The Red Sun vulnerability repository GitHub - SethPyle376/hiraeth: Local AWS emulator focused on fast integration testing, with SQS support, SQLite-backed state, and a debug-friendly web UI. GitHub - macOS26/Agent: Any AI, replaces Claude Code, Cursor, OpenClaw. Over 18 LLM providers (Claude, OpenAI, Gemini, Ollama, Zai, HF, Qwen) wired into a native Mac app that writes code, builds Xcode projects, bumps versions, manages git, automates Safari, use AppleScript, JS or Accessibility, extend Agent! w/ MCP Servers, run tasks from your iPhone via Messages. YouTube now lets you turn off Shorts I Made a Terminal Pager Burgers | マクドナルド公式 Commands — HackerNews CLI documentation ChatGPT for Excel PiCore - Raspberry Pi Port of Tiny Core Linux Live Nation illegally monopolized ticketing market, jury finds Google Broke Its Promise to Me. Now ICE Has My Data. Founding Engineer at Adaptional | Y Combinator CRISPR takes important step toward silencing Down syndrome’s extra chromosome GitHub - saffron-health/libretto: The AI toolkit for building reliable browser automations US v. Heppner (S.D.N.Y. 2026) no attorney-client privilege for AI chats [pdf] Retrofitting JIT Compilers into C Interpreters IPv6 – Google The Accursèd Alphabetical Clock Cybersecurity Looks Like Proof of Work Now Fragments: April 14 Cal.com Goes Closed Source: Why AI Security Is Forcing Our Decision | Cal.com - Scheduling Software for Online Bookings Laravel raised money and now injects ads directly into your agent When moving fast, talking is the first thing to break Too much Discussion of the XOR swap trick – Heather Cafe Introduction to Spherical Harmonics for Graphics Programmers The Grand Line
Configuring a Go HTTP Server for Unencrypted HTTP/2 (h2c)
Dan McGee · 2026-05-18 · via Hacker News

In our application, we use long-lived server-sent event streams (SSE). These are set up to have a really long timeout and lifetime - 15 minutes in our setup. However, Google Cloud Run has a known issue in that client disconnects are not propagated to Cloud Run when using HTTP/1.1 to communicate with the backend service. Thus, I started looking into using HTTP/2 for services.

Cloud Run terminates TLS at the frontend, but can forward traffic as either HTTP/1.1 or HTTP/2 cleartext (h2c) traffic. Normally, HTTP/2 always uses TLS, but HTTP clients and servers can often be configured to use a cleartext version of the protocol. Cloud Run also makes you select the protocol to be used. This is basically the “HTTP/2 with Prior Knowledge” setup noted in RFC 9113, section 3.3.

Configuring a Go server for HTTP/2 cleartext

Our first cut of h2c support predated the Go 1.24 changes I will go into more detail below. Most posts and guides on the internet will point you toward the old outdated approach, but I’ve included it below so it is easier to see the before and after, and migrate your own code if you need to.

Before Go 1.24 (old approach)

To use h2c, you had to use the golang.org/x/net/http package, and go through a convoluted setup.

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

handler := ...
// the existing `handler` must be wrapped, attached to server, then configured
h2s := &http2.Server{}
handler = h2c.NewHandler(handler, h2s)
srv := &http.Server{
	Addr:              fmt.Sprintf("%s:%d", "", 9888),
	Handler:           handler,
	ReadHeaderTimeout: 5 * time.Second,
	ReadTimeout:       10 * time.Second,
	WriteTimeout:      35 * time.Second,
	// https://cloud.google.com/load-balancing/docs/https/request-distribution#timeout-bes
	IdleTimeout: 620 * time.Second,
}
err = http2.ConfigureServer(srv, h2s)
if err != nil {
    ...
}

Go 1.24+ (new approach)

With Go 1.24, no x/net/http2/h2c wrapper is needed anymore, and the setup is a lot more readable. You can configure protocols directly on http.Server.

Reference: Go 1.24 net/http release notes.

handler := ...
srv := &http.Server{
	Addr:              fmt.Sprintf("%s:%d", "", 9888),
	Handler:           handler,
	ReadHeaderTimeout: 5 * time.Second,
	ReadTimeout:       10 * time.Second,
	WriteTimeout:      35 * time.Second,
	// https://cloud.google.com/load-balancing/docs/https/request-distribution#timeout-bes
	IdleTimeout: 620 * time.Second,
}
srv.Protocols = new(http.Protocols)
srv.Protocols.SetHTTP1(true)
srv.Protocols.SetUnencryptedHTTP2(true)

Testing locally before deployment

Testing is pretty simple. This command will fail if HTTP/2 cleartext isn’t set up properly.

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

Terraform Cloud Run configuration

Once your Go service can speak HTTP/2 cleartext, it needs to be configured in Cloud Run appropriately. If you’re doing it via the Cloud Run console, follow the HTTP/2 for services documentation. We’re doing it via terraform - this snippet below gives a general idea of the configuration.

# Many settings have been omitted that are not relevant to this post.
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
      }
    }

    # Default is 80; with idle SSE connections, we can easily scale higher.
    max_instance_request_concurrency = 200
    # Default is 300s, but with SSE, we want to allow long-lived connections.
    timeout = "900s"
  }

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

No real changes were needed at the load balancer level, since HTTPS is used to communicate with Serverless NEGs, and it seems like it properly upgrades the connection to HTTP/2 during that negotiation. Also, the default timeouts for serverless backends is 60 minutes, not 30 seconds like some other backends.