3

为了学习 Erlang,我正在尝试实现一个基于gen_tcp. 不幸的是,我的代码似乎触发了一些有线行为。为了演示这个问题,我附上了我的实现的最小化版本,它足以重现问题。无论 HTTP 请求是什么,它都只是提供静态 200 OK。

当我尝试ab对我的 Web 服务器(使用环回接口)运行(Apache HTTP 服务器基准测试)时,就会出现问题。没有任何并发​​请求(-c),一切都运行得很好。但是,如果我使用-c 8or -c 16,调用 togen_tcp:accept/1似乎在某些套接字上失败,因为我request: closed在 shell 中看到了许多行。

让整个故事更奇怪的是,我在不同的操作系统上看到了不同的行为:

  • OS X+Erlang/OTP 18:ab启动后几乎立即报告“对等方重置连接”。
  • Debian+Erlang R15B01:除了两个 HTTP 请求之外的所有请求似乎都通过了。但是ab,当我ab使用-n 5000. 同样,当我运行 15000 次测试时报告 14998。

似乎不是问题。老实说,我很迷茫,因此感谢任何帮助!:) 谢谢!

server(Port) ->
    Opt = [list, {active, false}, {reuseaddr, true}],
    case gen_tcp:listen(Port, Opt) of
        {ok, Listen} ->
            handler(Listen),
            gen_tcp:close(Listen),
            ok;
        {error, Error} ->
            io:format("init: ~w~n", [Error])
    end.

handler(Listen) ->
    case gen_tcp:accept(Listen) of
        {ok, Client} ->
            request(Client),
            handler(Listen);
        {error, Error} ->
            io:format("request: ~w~n", [Error])
    end.

request(Client) ->
    Recv = gen_tcp:recv(Client, 0),
    case Recv of
        {ok, _} ->
            Response = reply(),
            gen_tcp:send(Client, Response);
        {error, Error} ->
            io:format("request: ~w~n", [Error])
    end,
    gen_tcp:close(Client).


reply() ->
    "HTTP/1.0 200 OK\r\n" ++
    "Content-Length: 7\r\n\r\n"
    "static\n".
4

1 回答 1

4

当您增加发送的并发请求数时,ab -c N它将立即打开多个 TCP 套接字到服务器。

默认情况下,使用 gen_tcp:listen/2 打开的套接字将仅支持五个未完成的连接请求。使用 gen_tcp:listen/2 的 {backlog, N} 选项增加未完成的连接请求数。

我用 ab 在 OS X 上测试了你的代码,并看到这解决了“对等连接重置”的问题。

于 2015-09-11T02:09:36.677 回答