【问题标题】:Yaws - socket_closed_remotely偏航 - socket_closed_remotely
【发布时间】:2017-06-29 11:06:21
【问题描述】:

你好厄兰格人 :)

这里只是另一个使用该语言的 Erlang 爱好者。我有一个非常简单的 YAWS 应用程序模块,在单个客户端访问时可以正常工作。但是,当我尝试生成多个并发客户端时,其中一些客户端开始接收错误(即使这些客户端的数量非常少,比如 10 个)。知道是什么原因造成的吗?

说明代码:

应用模块

out(Arg) ->
  io:format("got something!\n"),
  Method = extract_method(Arg),
  handle(Method, Arg).

客户

client(SenderPID) ->
case httpc:request(
  put,
  {
    "http://localhost:8080/storageunit",
    [],
    "application/x-www-form-urlencoded",
    ""
  }, [], []) of
    { error, Reason } -> io:format("Server responded with an error: ~p.\n", [Reason]);
    { ok, _ } -> ok
  end,
  SenderPID ! 'FINISHED'.

client_spawner(_SenderPID, 0) -> io:format("Done.\n");
client_spawner(SenderPID, Times) ->
  spawn(concurrent, client, [SenderPID]),
  client_spawner(SenderPID, Times - 1).

我遇到的错误:

服务器响应错误:socket_closed_remotely。

最后一条信息是:

  • 10 个并发客户端 - 平均 2 到 5 个错误
  • 100-100000 个并发客户端 - 平均 50% 的错误

我认为是我的处理代码导致了它,但在客户端收到 httpc 错误的情况下,服务器甚至没有响应“得到了一些东西!”。

我确定我错过了一些琐碎的事情,你能帮忙吗?

问候, 彼得

【问题讨论】:

  • 如果没有更多关于 handle/2 在服务器端所做的事情的详细信息,很难回答这个问题。我建议检查 Yaws 日志,看看那里是否有任何相关信息。此外,请确保您的 Yaws 侦听积压设置足够高,以适应您正在尝试的内容,并确保客户端和服务器的最大文件描述符数量设置适当。
  • 谢谢。看,问题是 handle/2 甚至没有被调用。我在 github 上的某个地方(一些 repo 中的一些旧问题)读到它可能是由 inets 使用的配置文件引起的。我打算稍微探索一下。
  • 是的,刚刚确认。即使我完全排除了等式中的句柄/2,我仍然遇到同样的问题。
  • Yaws 是否收到任何信息,或者这只是客户端问题?
  • 它看起来像一个客户端问题。 Yaws 什么也没得到。

标签: concurrency erlang yaws


【解决方案1】:

我的初始代码一定有问题。我从头开始重写了模块,它给了我预期的结果。代码如下:

-module(annoying_client).
-export([annoy/0, client/1, client_spawner/2]).

client(SenderPID) ->
  case httpc:request("http://www.google.com") of
    { error, Reason } -> io:format("Error. Reason: ~p\n", [Reason]);
    { ok, _ } -> io:format("ok\n")
  end,
  SenderPID ! 'FINISHED'.

client_spawner(_SenderPID, 0) -> io:format("Done.\n");
client_spawner(SenderPID, Times) ->
  spawn(?MODULE, client, [SenderPID]),
  client_spawner(SenderPID, Times - 1).

annoy() ->
  inets:start(),

  spawn(?MODULE, client_spawner, [self(), 100]),
  wait_for_all_jobs(1),

  inets:stop(),
  init:stop().

wait_for_all_jobs(NumberOfFinishedJobs) ->
  receive 'FINISHED' ->
    if
      NumberOfFinishedJobs < 100 ->
        wait_for_all_jobs(NumberOfFinishedJobs + 1);
      true ->
        io:format("All jobs finished.\n")
    end
  end.

两者都像魅力一样:

  • 谷歌
  • 当地香草偏航

GET 和 PUT。当我超过 2000 个并发请求的阈值时,问题就开始了,但我猜从本地和远程获得的数字来看,这是可以预料的。如果有 2000 个请求,我大致得到:

  • 请求 google.com 时出现 6 个错误
  • 请求本地偏航时出现 500 个错误

我遇到的错误:

Error. Reason: socket_closed_remotely

Error. Reason: {failed_connect,[{to_address,{"www.google.com",80}}, {inet,[inet],system_limit}]}

DoS 保护?配置不正确?无论如何,我对我目前的结果很满意。可能会尝试使用其他 Erlang Web 服务器来获得一些性能数据。

谢谢大家。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-06
    • 1970-01-01
    相关资源
    最近更新 更多