3 ms·
> Meanwhile, my preferred language, Go, has a high-quality, memory-safe HTTPS server in the standard library that is well suited for direct exposure on the Inte
by derefr 5y ago
> Meanwhile, my preferred language, Go, has a high-quality, memory-safe HTTPS server in the standard library that is well suited for direct exposure on the Internet.
I know people do use Golang's http.Server for production use-cases. Does Google, though? Are services of Google customers ever actually directly talking to this Golang stack, without at least a minimal L7 WAF (as e.g. a default Nginx config does) in between?
I ask because there are a number of weird connection latency, slowness, and "stuttering" problems I've experienced with services which I know do directly expose Golang servers — e.g. Docker Registry instances including Docker Hub; Minio instances; go-ethereum nodes; etc. — that I've never experienced with any Google service, or with any known non-Golang service.
My hypothesis is that this is due to Golang's http.Server not having any upper limit on simultaneous connections (because just in CPU and memory terms, the Golang runtime can handle almost arbitrarily many), such that eventually the bottleneck actually becomes per-connection throughput, with clients becoming starved for space in the machine's network ring buffer; and because this is such an unusual bottleneck to have (usually it's only a thing with CDNs) — and because it causes no problems for the server, esp. if things like readiness checks are done through a separate internal NIC — the people running these servers don't even notice it's happening, and so lag far behind in horizontally scaling servers to spread out the demand for throughput.
Or, to put that another way: the Golang http.Server isn't observable — exposing server-internal metrics — in the way that actual web servers like Nginx, or even web-app server frameworks like Jetty, are; and so it's very hard to know when things are silently going wrong for users, esp. in cases where the developers of a piece of software aren't themselves running it at scale and so never think to manually add observability for metrics that only become relevant at scale (which authors of generic web server software are usually aware of, but authors of application software usually aren't.) This leads me to think that, if Google themselves are using Golang services for anything at scale, and yet not rushing to implement such metrics into http.Server, then they must be observing these services in a very different way than we mere mortals do. Maybe calculating per-flow packet-wise QoS at the edge in their fancy LANai switches using historical statistical fingerprints of predictable flow patterns, or something.
- finnh 5y agoSeems like eBPF could be useful here as well, to get some external insight into per-connection counts and behavior.
- tedunangst 5y agoI wrote a web server that uses go http but not http.serve for this reason. I wanted more control over accept and close. Nice thing is the http library is decently composed, so you can take all the parts you want and build up.
- merb 5y agoyou can use opentelemetry to get traces and metrics for golang net/http, but since I'm not using it I have no idea what metrics are already supported. btw. google does use golang services at scale (I'm not a googler) but they probably do it like they do it with appengine and only limit a certain amount of req/s per service
- derefr 5y ago> you can use opentelemetry to get traces and metrics for golang net/http Yes, but not server-internal metrics, as IIRC the telemetry provider plugs into http.Server as a middleware. It only exposes the kinds of metrics you could calculate yourself in a handler; it doesn’t expose any of the “good stuff” (e.g. work queues, accept(2) latency, etc.)