为什么Google Go的http服务器包不能同时处理超过5个请求?

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

Google Go: Why does the http server package not serve more than 5 simultaneous requests?

问题

我正在尝试使用Google的Go语言编写一个小型的HTTP服务器,以便以后进行扩展。我正在使用Windows上的Go(MinGw编译版本)。

在这种语言中,这是相当容易的,因为它已经有了必要的包:

  1. package main
  2. import (
  3. "http"
  4. "io"
  5. "os"
  6. "fmt"
  7. "strconv"
  8. )
  9. func FileTest(w http.ResponseWriter, req *http.Request) {
  10. w.Header().Add("Content-Type", "image/jpeg")
  11. w.Header().Add("Content-Disposition", "inline; filename=image.jpg")
  12. inName := "d:\\googlego\\somepic.jpg"
  13. inFile, inErr := os.OpenFile(inName, os.O_RDONLY, 0666)
  14. if inErr == nil {
  15. inBufLen := 16
  16. inBuf := make([]byte, inBufLen)
  17. _, inErr := inFile.Read(inBuf)
  18. for inErr == nil {
  19. w.Write(inBuf)
  20. _, inErr = inFile.Read(inBuf)
  21. }
  22. }
  23. inErr = inFile.Close()
  24. }
  25. func MainPage(w http.ResponseWriter, req *http.Request) {
  26. io.WriteString(w, "Hi, download here: <a href=\"/FileTest\">HERE</a>")
  27. }
  28. func main() {
  29. fmt.Print("Port: ")
  30. var hi int
  31. fmt.Scanf("%d", &hi)
  32. http.HandleFunc("/FileTest", FileTest)
  33. http.HandleFunc("/", MainPage)
  34. err := http.ListenAndServe("0.0.0.0:" + strconv.Itoa(hi), nil)
  35. if err != nil {
  36. fmt.Print(err)
  37. fmt.Print((hi))
  38. }
  39. }

这将启动一个服务器,提供一个主页和一个从图像下载。两者都工作得非常好,我从ab(Apache基准测试工具)中得到了非常好的结果,最多可以同时处理6个线程:

  1. > ab -n 10000 -c 6 http://localhost:8080/
  2. Concurrency Level: 6
  3. Time taken for tests: 1.678096 seconds
  4. Complete requests: 10000
  5. Percentage of the requests served within a certain time (ms)
  6. 50% 1
  7. 66% 1
  8. 75% 1
  9. 80% 1
  10. 90% 2
  11. 95% 2
  12. 98% 2
  13. 99% 2
  14. 100% 3 (longest request)

当并发级别设置得更高时,情况如下:

  1. > ab -n 1000 -c 7 http://localhost:8080/
  2. Concurrency Level: 7
  3. Time taken for tests: 10.239586 seconds
  4. Complete requests: 1000
  5. Percentage of the requests served within a certain time (ms)
  6. 50% 1
  7. 66% 2
  8. 75% 2
  9. 80% 3
  10. 90% 499
  11. 95% 505
  12. 98% 507
  13. 99% 507
  14. 100% 510 (longest request)

请注意,这次我只进行了1,000个请求,但时间几乎增加了6倍。

这两个基准测试甚至还没有请求文件。

我对Go还不是很了解,但似乎Go运行时没有创建足够的操作系统线程来放置goroutine,或者类似的情况?

编辑:我下载了2011年10月7日的新版本r60.2。

现在情况变得更糟了:

  1. > ab -c 7 -n 1000 http://localhost:8080/
  2. Concurrency Level: 7
  3. Time taken for tests: 12.622722 seconds
  4. Complete requests: 1000
  5. Percentage of the requests served within a certain time (ms)
  6. 50% 1
  7. 66% 1
  8. 75% 2
  9. 80% 2
  10. 90% 496
  11. 95% 503
  12. 98% 506
  13. 99% 506
  14. 100% 507 (longest request)
英文:

I'm trying to code a small http server for later extension in Google's Go language. I am using Go on Windows (MinGw compiled version).

This is quite easy in this language since it already has the necessary package:

  1. package main
  2. import (
  3. &quot;http&quot;
  4. &quot;io&quot;
  5. &quot;os&quot;
  6. &quot;fmt&quot;
  7. &quot;strconv&quot;
  8. )
  9. func FileTest(w http.ResponseWriter, req *http.Request) {
  10. w.Header().Add(&quot;Content-Type&quot;, &quot;image/jpeg&quot;)
  11. w.Header().Add(&quot;Content-Disposition&quot;, &quot;inline; filename=image.jpg&quot;)
  12. inName := &quot;d:\\googlego\\somepic.jpg&quot;;
  13. inFile, inErr := os.OpenFile(inName, os.O_RDONLY, 0666);
  14. if inErr == nil {
  15. inBufLen := 16;
  16. inBuf := make([]byte, inBufLen);
  17. _, inErr := inFile.Read(inBuf);
  18. for inErr == nil {
  19. w.Write(inBuf)
  20. _, inErr = inFile.Read(inBuf);
  21. }
  22. }
  23. inErr = inFile.Close();
  24. }
  25. func MainPage(w http.ResponseWriter, req *http.Request) {
  26. io.WriteString(w, &quot;Hi, download here: &lt;a href=\&quot;/FileTest\&quot;&gt;HERE&lt;/a&gt;&quot;)
  27. }
  28. func main() {
  29. fmt.Print(&quot;Port: &quot;)
  30. var hi int
  31. fmt.Scanf(&quot;%d&quot;, &amp;hi)
  32. http.HandleFunc(&quot;/FileTest&quot;, FileTest)
  33. http.HandleFunc(&quot;/&quot;, MainPage)
  34. err := http.ListenAndServe(&quot;0.0.0.0:&quot; + strconv.Itoa(hi), nil)
  35. if err != nil {
  36. fmt.Print(err)
  37. fmt.Print((hi))
  38. }
  39. }

This starts a server that serves a main page and a download from an image. Both work very well and I get very good results from ab (Apache benchmark) up to 6 concurrent threads:

  1. &gt; ab -n 10000 -c 6 http://localhost:8080/
  2. Concurrency Level: 6
  3. Time taken for tests: 1.678096 seconds
  4. Complete requests: 10000
  5. Percentage of the requests served within a certain time (ms)
  6. 50% 1
  7. 66% 1
  8. 75% 1
  9. 80% 1
  10. 90% 2
  11. 95% 2
  12. 98% 2
  13. 99% 2
  14. 100% 3 (longest request)

When the concurrency level is set higher, this happens:

  1. &gt;ab -n 1000 -c 7 http://localhost:8080/
  2. Concurrency Level: 7
  3. Time taken for tests: 10.239586 seconds
  4. Complete requests: 1000
  5. Percentage of the requests served within a certain time (ms)
  6. 50% 1
  7. 66% 2
  8. 75% 2
  9. 80% 3
  10. 90% 499
  11. 95% 505
  12. 98% 507
  13. 99% 507
  14. 100% 510 (longest request)

Note that I only made 1'000 requests this time and it still took almost 6 times as much time.

Both benchmarks don't even request the file yet.

I don't know a lot about Go yet, but it seems that the Go runtime doesn't create enough OS threads to put the goroutines on, or something like that?

EDIT: I downloaded the new r60.2 from 07.10.2011.

Now it went even worse:

  1. &gt;ab -c 7 -n 1000 http://localhost:8080/
  2. Concurrency Level: 7
  3. Time taken for tests: 12.622722 seconds
  4. Complete requests: 1000
  5. Percentage of the requests served within a certain time (ms)
  6. 50% 1
  7. 66% 1
  8. 75% 2
  9. 80% 2
  10. 90% 496
  11. 95% 503
  12. 98% 506
  13. 99% 506
  14. 100% 507 (longest request)

答案1

得分: 4

截至今天(2011年9月),Go语言在Windows平台上的移植仍在进行中。它在一些重要的方面,包括稳定性和性能(尽管每天都在改进),落后于其他支持的平台(如Linux等)。我建议您在64位Linux平台上进行测试,看看它与Windows平台有何不同,然后也许您可以开始分析在Windows下出了什么问题。

英文:

As of today (Sep 2011) the Windows port of Go is a work-in-progress. It lags behind the other supported platforms (Linux, etc.) in some important measures including stability and performance (though it is improving every day). I would suggest that you try your test on a 64-bit Linux platform, and see how it differs, then maybe you can start deconstructing what's going wrong under Windows.

答案2

得分: 2

我刚刚在Go 64位的tip上尝试了这个基准测试,并得到了以下结果(在Core 2 Duo 2GHz,Windows 7 x64上):

  1. C:\Program Files (x86)\Apache Software Foundation\Apache2.2\bin&gt;ab -c 7 -n 1000 http://localhost:8080/
  2. 并发级别:7
  3. 测试所用时间:0.458
  4. 完成请求数:1000
  5. 在特定时间内完成请求的百分比(毫秒)
  6. 50% 3
  7. 66% 3
  8. 75% 3
  9. 80% 3
  10. 90% 4
  11. 95% 5
  12. 98% 7
  13. 99% 8
  14. 100% 9(最长的请求)
英文:

I just tried this benchmark with Go 64-bit at tip, and got the following results (on a Core 2 Duo 2GHz, Windows 7 x64):

  1. C:\Program Files (x86)\Apache Software Foundation\Apache2.2\bin&gt;ab -c 7 -n 1000 http://localhost:8080/
  2. Concurrency Level: 7
  3. Time taken for tests: 0.458 seconds
  4. Complete requests: 1000
  5. Percentage of the requests served within a certain time (ms)
  6. 50% 3
  7. 66% 3
  8. 75% 3
  9. 80% 3
  10. 90% 4
  11. 95% 5
  12. 98% 7
  13. 99% 8
  14. 100% 9 (longest request)

huangapple
  • 本文由 发表于 2011年9月28日 02:20:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/7573850.html
匿名

发表评论

匿名网友

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

确定