为什么我的 Hello World go 服务器被 ApacheBench 搞砸了? [英] Why is my Hello World go server getting crushed by ApacheBench?

查看:35
本文介绍了为什么我的 Hello World go 服务器被 ApacheBench 搞砸了?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

package main

import (
    "io"
    "net/http"
)

func hello(w http.ResponseWriter, r *http.Request) {
    io.WriteString(w, "Hello world!
")
}

func main() {
    http.HandleFunc("/", hello)
    http.ListenAndServe(":8000", nil)
}

我有几个非常基本的 HTTP 服务器,它们都出现了这个问题.

I've got a couple of incredibly basic HTTP servers, and all of them are exhibiting this problem.

$ ab -c 1000 -n 10000 http://127.0.0.1:8000/
This is ApacheBench, Version 2.3 <$Revision: 1604373 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 127.0.0.1 (be patient)
Completed 1000 requests
Completed 2000 requests
Completed 3000 requests
Completed 4000 requests
Completed 5000 requests
apr_socket_recv: Connection refused (61)
Total of 5112 requests completed

使用较小的并发值,事情仍然会失败.对我来说,问题似乎通常出现在 5k-6k 左右:

With a smaller concurrency value, things still fall over. For me, the issue seems to show up around the 5k-6k mark usually:

$ ab -c 10 -n 10000 http://127.0.0.1:8000/
This is ApacheBench, Version 2.3 <$Revision: 1604373 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 127.0.0.1 (be patient)
Completed 1000 requests
Completed 2000 requests
Completed 3000 requests
Completed 4000 requests
Completed 5000 requests
Completed 6000 requests
apr_socket_recv: Operation timed out (60)
Total of 6277 requests completed

事实上,你可以完全放弃并发,但问题仍然(有时)发生:

And in fact, you can drop concurrency entirely and the problem still (sometimes) happens:

$ ab -c 1 -n 10000 http://127.0.0.1:8000/
This is ApacheBench, Version 2.3 <$Revision: 1604373 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 127.0.0.1 (be patient)
Completed 1000 requests
Completed 2000 requests
Completed 3000 requests
Completed 4000 requests
Completed 5000 requests
Completed 6000 requests
apr_socket_recv: Operation timed out (60)
Total of 6278 requests completed

我不禁想知道我是否在某个地方遇到了某种操作系统限制?我该怎么说?我将如何缓解?

I can't help but wonder if I'm hitting some kind of operating system limit somewhere? How would I tell? And how would I mitigate?

推荐答案

简而言之,你的端口用完了.

In short, you're running out of ports.

osx 上的默认临时端口范围是 49152-65535,只有 16,383 个端口.由于每个 ab 请求都是 http/1.0(在第一个示例中没有 keepalive),因此每个新请求都需要另一个端口.

The default ephemeral port range on osx is 49152-65535, which is only 16,383 ports. Since each ab request is http/1.0 (without keepalive in your first examples), each new request takes another port.

当每个端口被使用时,它会被放入一个队列中,等待 tcp最大段生命周期",在 osx 上配置为 15 秒.因此,如果您在 15 秒内使用超过 16,383 个端口,您实际上会在进一步连接时受到操作系统的限制.根据哪个进程首先用完端口,您将收到来自服务器的连接错误,或者从 ab 挂起.

As each port is used, it get's put into a queue where it waits for the tcp "Maximum Segment Lifetime", which is configured to be 15 seconds on osx. So if you use more than 16,383 ports in 15 seconds, you're effectively going to get throttled by the OS on further connections. Depending on which process runs out of ports first, you will get connection errors from the server, or hangs from ab.

您可以通过使用具有 http/1.1 能力的负载生成器(如 wrk)或使用 keepalive (-k) 选项来缓解这种情况ab,以便根据工具的并发设置重用连接.

You can mitigate this by using an http/1.1 capable load generator like wrk, or using the keepalive (-k) option for ab, so that connections are reused based on the tool's concurrency settings.

现在,您进行基准测试的服务器代码做的很少,负载生成器的负担与服务器本身一样多,本地操作系统和网络堆栈可能做出了很好的贡献.如果您想对 http 服务器进行基准测试,最好从不在同一台机器上运行的多个客户端做一些有意义的工作.

Now, the server code you're benchmarking does so little, that the load generator is being taxed just as much as the sever itself, with the local os and network stack likely making a good contribution. If you want to benchmark an http server, it's better to do some meaningful work from multiple clients not running on the same machine.

这篇关于为什么我的 Hello World go 服务器被 ApacheBench 搞砸了?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆