2

最近,我开始在 erlang & Yaws 中开发 REST api。我不明白 yaws 和我的模块如何处理多个请求。

我确实有 api 模块收集所有请求:

appmods = </, api>

和我的测试模块:

-module(api).
out(_Arg) ->
    io:format("my pid  ~p ~n", [self()]),
    loop(200000000),
    [{status, 200}, {header, {"Vary", "Accept"}},
     {content, "application/json", ""}].

在这一点上,我的理解是 yaws 只生成我的 api 模块的一个实例并将所有请求发送到那里。因此,在任何给定时间只能处理一个请求。

有没有办法产生更多的 api 模块进程并在它们之间传播请求?

或者我应该为每种类型的 API 请求做更多的 appmods 吗?

或者我对偏航如何工作的理解是根本错误的?

感谢帮助。

4

1 回答 1

1

Yaws 在内部保留了一个接受器进程池。在这些进程上处理请求。Yaws 不会为每个 appmod 生成一个新进程,并将对给定 appmod 的所有请求定向到其进程。相反,一个接受器处理一个新连接,读取该连接上的请求并分派它们,然后发送响应。一旦连接关闭,要么是由于客户端关闭它,要么是由于存在“Connection: close” HTTP 标头,是由于 HTTP 1.0 请求(默认情况下需要在每次请求/响应后关闭连接),或者由于客户端不活动导致服务器关闭它,接受器进程返回池。

上面评论中链接的输出的 JPEG 图像显示处理所有请求的相同 pid 可能是由于您的客户端保持连接打开并在同一连接上发送每个新请求,导致处理所有这些请求的同一服务器进程。如果您改为尝试像Apache Bench(也称为“ab”)这样的客户端,它默认为 HTTP 1.0,因此每个请求都有一个新连接,您将看到处理每个请求的不同进程。

顺便说一下,对于 appmod 需要注意的一点是,如果您使用执行尾递归循环的状态保持进程来实现它们,gen_server例如循环进程的pid。换句话说,该请求最初将在如前所述的 Yaws 接受器进程中处理,但gen_server一旦 appmod 调用它,它就会跨入该进程。这种对单个进程的请求序列化与 Yaws 无关,而是与 appmod 的实现方式有关——您可能想阅读我发表的一篇关于此的文章以了解更多详细信息。简而言之,除非您的应用程序可以接受这样的请求序列化,否则不要以这种方式编写 appmod。

于 2013-03-16T12:33:23.690 回答