Jan*_*ard 4 erlang performance proxy networking tcp
出于学习目的,我在 Erlang 中编写了一个简单的 TCP 代理。它可以工作,但是当我使用 ab (Apache Bench) 发出许多并发请求时,我遇到了奇怪的性能下降。让我感到疑惑的不是性能下降本身,而是下降的规模。后端是 nginx 作为 Web 服务器。我的代理位于 ab 和 nginx 之间。
这是我的代理的代码。
-module(proxy).
-export([start/3]).
start(InPort, OutHost, OutPort) ->
{ok, Listen} = gen_tcp:listen(InPort, [binary, {packet, 0}, {active, once}]),
spawn(fun() -> connect(Listen, OutHost, OutPort) end).
connect(Listen, OutHost, OutPort) ->
{ok, Client} = gen_tcp:accept(Listen),
spawn(fun() -> connect(Listen, OutHost, OutPort) end),
{ok, Server} = gen_tcp:connect(OutHost, OutPort, [binary, {packet, 0}, {active, once}]),
loop(Client, Server).
loop(Client, Server) ->
receive
{tcp, Client, Data} ->
gen_tcp:send(Server, Data),
inet:setopts(Client, [{active, once}]),
loop(Client, Server);
{tcp, Server, Data} ->
gen_tcp:send(Client, Data),
inet:setopts(Server, [{active, once}]),
loop(Client, Server);
{tcp_closed, _} ->
ok
end.
Run Code Online (Sandbox Code Playgroud)
在我的代理上发出 64 个连续请求,我得到了非常好的结果。
ab -n 64 127.0.0.1:80/
Concurrency Level: 1
Time taken for tests: 0.097 seconds
Complete requests: 64
Failed requests: 0
Write errors: 0
Total transferred: 23168 bytes
HTML transferred: 9664 bytes
Requests per second: 659.79 [#/sec] (mean)
Time per request: 1.516 [ms] (mean)
Time per request: 1.516 [ms] (mean, across all concurrent requests)
Transfer rate: 233.25 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.3 0 1
Processing: 1 1 0.5 1 2
Waiting: 0 1 0.4 1 2
Total: 1 1 0.5 1 2
Percentage of the requests served within a certain time (ms)
50% 1
66% 2
75% 2
80% 2
90% 2
95% 2
98% 2
99% 2
100% 2 (longest request)
Run Code Online (Sandbox Code Playgroud)
它只是比直接对 nginx 使用 Apache Bench 慢一点。
但是在代理上发出 64 个并发请求,性能下降得非常疯狂
ab -n 64 -c 64 127.0.0.1:80/
Concurrency Level: 64
Time taken for tests: 2.011 seconds
Complete requests: 64
Failed requests: 0
Write errors: 0
Total transferred: 23168 bytes
HTML transferred: 9664 bytes
Requests per second: 31.82 [#/sec] (mean)
Time per request: 2011.000 [ms] (mean)
Time per request: 31.422 [ms] (mean, across all concurrent requests)
Transfer rate: 11.25 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 31 121.7 0 501
Processing: 3 1135 714.4 1001 2006
Waiting: 3 1134 714.3 1000 2005
Total: 3 1167 707.8 1001 2006
Percentage of the requests served within a certain time (ms)
50% 1001
66% 1502
75% 2003
80% 2004
90% 2005
95% 2005
98% 2005
99% 2006
100% 2006 (longest request)
Run Code Online (Sandbox Code Playgroud)
什么/哪里有问题?我预计性能会降低,但为什么会这么高?看看每秒的请求数!
我是否使用 +A 给 erl 很多线程似乎并不重要。我什至尝试过 SMP,但结果几乎相同。
我的设置:Windows 7 64、Intel QuadCore、8GB RAM。我在使用 128 个并发请求的 Ubuntu 上得到了类似的结果。
编辑:包括新的见解。请求的总数无关紧要。这只是并发请求的计数。
这部分connect/3是连续的:
connect(Listen, OutHost, OutPort) ->
{ok, Client} = gen_tcp:accept(Listen),
spawn(fun() -> connect(Listen, OutHost, OutPort) end),
Run Code Online (Sandbox Code Playgroud)
在新生成的进程gen_tcp:accept/1准备就绪之前,您无法接受新连接。它可能涉及您的代码的瓶颈。在这种情况下,您可以尝试使用“接受者”池来提高性能。我还会尝试添加 catch all 子句loop/2 receive以避免偶然出现邮箱填充。
还有你的erl参数是什么?是否有+A 线程和+K true参与?
| 归档时间: |
|
| 查看次数: |
2117 次 |
| 最近记录: |