为什么这个 “hello world” 的 Golang HTTP 示例在 macOS 上变慢了?

huangapple go评论85阅读模式
英文:

why does this "hello world" golang http example slow down on osx

问题

我正在为你翻译以下内容:

我正在对我的小型Web应用程序进行基准测试,并注意到在运行Apache Bench进行数千个请求后,出现了显着的减速。

ab -n 20000 http://localhost:8080

前几千个请求很快,然后速度越来越慢。慢得惊人。前一千个请求可能只需要一秒钟,而第18000到20000个请求需要多达10秒钟。

因此,我试图找出慢的部分,但在某个点上没有任何可以排除的内容,最后只能对一个类似于“hello world”风格的HTTP服务器示例进行基准测试。令我惊讶的是,同样的减速问题也出现了。

package main

import "net/http"

func main() {
    mux := http.NewServeMux()

    mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        w.WriteHeader(200)
    })
    http.ListenAndServe(":8080", mux)
}

同样的小例子在Linux系统上始终运行得很快。这并不是一个大问题,因为我不打算在OSX上将该应用程序投入生产使用 为什么这个 “hello world” 的 Golang HTTP 示例在 macOS 上变慢了? 但我很好奇是什么原因导致了OSX上的严重减速。

英文:

I was benchmarking my little web application and noticed some significant slowdown when I was running apache bench against it after a couple of thousand requests.

ab -n 20000 http://localhost:8080

The first few thousand requests are fast, then it gets slower and slower. Dramatically slower. While the first thousand take maybe a second, requests 18000-20000 take up to 10 seconds.

So I was trying to find the slow parts and at some point didn't have anything to exclude anymore until I ended up with benchmarking a "hello world" style http server example. To my surprise, the same slowdown occurred.

package main

import "net/http"

func main() {
	mux := http.NewServeMux()

	mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		w.WriteHeader(200)
	})
	http.ListenAndServe(":8080", mux)
}

The same little example runs consistently fast on a linux box. It's not really a big thing because I don't plan to run the app on osx in production 为什么这个 “hello world” 的 Golang HTTP 示例在 macOS 上变慢了? But I'm curious what's causing the terrible slowdown on osx anyways

答案1

得分: 5

将我的评论转化为某种回答的形式:

我不确定Linux和OSX之间的具体区别,但是你的服务器代码完全正常,没有泄漏任何信息。(我目前没有OSX机器来深入研究)。

我怀疑你正在使用的客户端(ab)不会重用连接,并且由于两个操作系统之间的配置和行为差异,你可能会向网络堆栈发送即将关闭的连接或类似的内容。

在你的ab脚本中简单地使用KeepAlive - ab -k -c 100 -n 20000 http://localhost:8080 - 如评论中所述,这样可以解决问题。还值得尝试其他工具,如JMeter、siege等,或者只需编写一个简单的基于Go的客户端。Go在http库中默认支持连接重用。

英文:

Phrasing my comments as an answer of sorts:

I'm not sure what's the specific difference between Linux and OSX, but your server code is perfectly fine and not leaking anything. (I don't have an OSX machine to dig deeper at the moment).

My suspicion is that the client you're using (ab) doesn't reuse connections, and due to configuration and behavior differences between the two OSes, you're flooding the network stack with about-to-be closed connections or something along these lines.

Simply use KeepAlive in your ab script - ab -k -c 100 -n 20000 http://localhost:8080 - and as noted in the comments this fixed it. It's also worth trying other tools like JMeter, siege, etc - or just writing a simple Go based client for this. Go has connection reuse in the http library by default.

huangapple
  • 本文由 发表于 2015年2月9日 17:41:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/28406680.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定