0

我有一个 erlang 项目,它向我的应用程序发出大量并发 SOAP 请求。目前,它受到可用节点数量的限制,但我想对其进行调整,以便每个节点一次可以发送多个消息。

我已经解决了这个问题,但我不知道如何从运行 SOAP 请求的进程中获取响应。

这是我试图用来执行多个线程的函数:

batch(Url, Message, BatchSize) ->
    inets:start(),

    Threads = for(1, BatchSize, fun() -> spawn(fun() -> attack_thread() end) end),
    lists:map(fun(Pid) -> Pid ! {Url, Message, self()} end, Threads).

这个函数由启动压力测试器的人调用,它在我们网络中的每个节点上调用。它会持续调用,直到所有请求数量的 SOAP 请求都已发送并计时。

这是通过批处理方法发送消息的攻击线程:

attack_thread() ->
 receive
    {Url, Message, FromPID} ->
        {TimeTaken, {ok, {{_, 200, _}, _, _}}} = timer:tc(httpc, request, [post, {Url, [{"connection", "close"}, {"charset", "utf-8"}], "text/xml", Message}, [], []]),
        TimeTaken/1000/1000.
 end

如您所见,我希望它返回 SOAP 请求所用的秒数。但是,erlang 的消息传递 ( Pid ! Message) 不会返回任何有用的信息。

我怎样才能得到结果?

4

1 回答 1

1

您的每个attack_thread()线程都可以简单地在运行该batch/3函数的进程的邮箱中投递一条消息:

 FromPid ! {time_taken, self(), TimeTaken / 1000 / 1000}.

但随后您需要收集结果:

 batch(Url, Message, BatchSize) ->
  inets:start(),

  Pids = [spawn_link(fun attack_thread/0) || _ <- lists:seq(1, BatchSize],
  [Pid ! {Url, Message, self()} || Pid <- Pids],
  collect(Pids).

 collect([]) -> [];
 collect(Pids) ->
   receive
     {time_taken, P, Time} ->
       [Time | collect(Pids -- [P])]
   end.

其他一些评论:你可能想要 spawn_link/1 这里。如果有什么东西在途中死掉,你希望整个东西都死掉。另外,一定要稍微调整一下 inets httpc 以使其更有效。您可能还想查看 basho_bench 或 tsung。

最后,您可以直接使用闭包,而不是传递 url 和消息:

 attack_thread(Url, Message, From) -> ...

所以你的产卵是:

 Self = self(),
 Pids = [spawn_link(fun() -> attack_thread(Url, Message, Self) end) || _ <- ...]

它避免在一开始就传递消息。

于 2012-05-14T17:21:57.140 回答