1. 程式人生 > >系統技術非業餘研究 » 最快的Erlang http hello world 伺服器調優指南 (20Khttp短連結請求/S每桌面CPU)

系統技術非業餘研究 » 最快的Erlang http hello world 伺服器調優指南 (20Khttp短連結請求/S每桌面CPU)

erl的虛擬機器有2種方式 plain版本的和smp版本的。 smp版本由於鎖的開銷相比要比plain版本的慢很多。而32位機器由於記憶體訪問比64位的少,也會快出很多。所有我選擇在32位的linux系統下調優這個httpd伺服器。這個伺服器就是實現個簡單的功能,在browser下返回hello world。以下我們會先編譯我們的優化版本的虛擬機器,然後再分別測試R13B02的標準版本的和我們優化版的效能:

[email protected]:/build_opt_plain# uname -a
Linux nd-desktop 2.6.31-14-generic #3 SMP Sun Nov 1 23:03:10 CST 2009 i686 GNU/Linux

#準備開發環境
[email protected]
ktop:/# apt-get build-dep erlang #下載otp R13B02-1原始碼包 [email protected]:/# wget http://www.erlang.org/download/otp_src_R13B02-1.tar.gz #解開patch包 [email protected]:/# tar xzvf build_opt_plain.tar.gz #解開原始碼包 [email protected]:/# tar xzf otp_src_R13B02-1.tar.gz #打補丁
[email protected]
:/# cd otp_src_R13B02-1 [email protected]:/otp_src_R13B02-1# patch -p1 <../build_opt_plain/otp_src_R13B02-1_patch_by_yufeng patching file erts/emulator/beam/erl_binary.h patching file erts/emulator/beam/erl_process.c patching file erts/emulator/beam/sys.h patching file erts/emulator/drivers/common/inet_drv.c patching file erts/preloaded/src/Makefile patching file erts/preloaded/src/prim_inet.erl patching file lib/asn1/src/Makefile patching file lib/hipe/Makefile patching file lib/parsetools/src/Makefile
[email protected]
:/otp_src_R13B02-1# ../build_opt_plain/build.plain 。。。

如果編譯都沒有任何錯誤的話, 就大功告成了。

好 現在我們開始效能比較:

#先加大檔案控制代碼數

[email protected]:/otp_src_R13B02-1# cd ../build_opt_plain
[email protected]:/build_opt_plain# ulimit -n 99999

#標準釋出版本
[email protected]:/build_opt_plain# erlc ehttpd.erl
[email protected]:/build_opt_plain# taskset -c 1 erl +K true +h 99999  +P 99999 -smp enable +S 2:1 -s ehttpd
Erlang R13B03 (erts-5.7.4)  [smp:2:1] [rq:2] [async-threads:0] [hipe] [kernel-poll:true]

ehttpd ready with 2 schedulers on port 8888
Eshell V5.7.4  (abort with ^G)
1>

#在另外的一臺機器上發動ab測試

[[email protected] src]# ab -c 60 -n 100000 http://192.168.235.147:8888/
This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright 2006 The Apache Software Foundation, http://www.apache.org/

Benchmarking 192.168.235.147 (be patient)
Completed 10000 requests
Completed 20000 requests
Completed 30000 requests
Completed 40000 requests
Completed 50000 requests
Completed 60000 requests
Completed 70000 requests
Completed 80000 requests
Completed 90000 requests
Finished 100000 requests


Server Software:       
Server Hostname:        192.168.235.147
Server Port:            8888

Document Path:          /
Document Length:        12 bytes

Concurrency Level:      60
Time taken for tests:   8.925945 seconds
Complete requests:      100000
Failed requests:        0
Write errors:           0
Total transferred:      5100051 bytes
HTML transferred:       1200012 bytes
Requests per second:    11203.29 [#/sec] (mean)
Time per request:       5.356 [ms] (mean)
Time per request:       0.089 [ms] (mean, across all concurrent requests)
Transfer rate:          557.92 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    1  65.7      0    3001
Processing:     0    3   1.5      4       7
Waiting:        0    2   1.8      4       6
Total:          0    4  65.8      4    3007
WARNING: The median and mean for the waiting time are not within a normal deviation
        These results are probably not that reliable.

Percentage of the requests served within a certain time (ms)
  50%      4
  66%      4
  75%      4
  80%      4
  90%      5
  95%      5
  98%      5
  99%      5
100%   3007 (longest request)

標準smp版本1個CPU的結果是: 11203.29 [#/sec] (mean)

#啟用hipe的標準版本

[email protected]:/build_opt_plain# erlc +native +"{hipe, [o3]}" ehttpd.erl
[email protected]:/build_opt_plain# taskset -c 1 erl +K true +h 99999  +P 99999 -smp enable +S 2:1 -s ehttpd
Erlang R13B03 (erts-5.7.4)  [smp:2:1] [rq:2] [async-threads:0] [hipe] [kernel-poll:true]

ehttpd ready with 2 schedulers on port 8888
Eshell V5.7.4  (abort with ^G)
1>

標準smp hipe版本1個CPU結果是: 12390.32 [#/sec] (mean)

#我們的優化版本

[email protected]:/build_opt_plain#  ../otp_src_R13B02-1/bin/erlc  ehttpd.erl
[email protected]:/build_opt_plain# taskset -c 1   ../otp_src_R13B02-1/bin/erl +K true +h 99999  +P 99999   -s ehttpd
Erlang R13B02 (erts-5.7.3)  [rq:1] [hipe] [kernel-poll:true]

ehttpd ready with 1 schedulers on port 8888
Eshell V5.7.3  (abort with ^G)
1>

優化版本單個cpu: 19662.37 [#/sec] (mean)

#啟用hipe的優化版本

[email protected]:/build_opt_plain#  ../otp_src_R13B02-1/bin/erlc +native +"{hipe, [o3]}"  ehttpd.erl
[email protected]:/build_opt_plain# taskset -c 1   ../otp_src_R13B02-1/bin/erl +K true +h 99999  +P 99999   -s ehttpd
Erlang R13B02 (erts-5.7.3)  [rq:1] [hipe] [kernel-poll:true]

ehttpd ready with 1 schedulers on port 8888
Eshell V5.7.3  (abort with ^G)
1>

優化版本啟用hipe單個cpu:20090.83 [#/sec] (mean)

附上我們的最小的高效能的http echo 伺服器:

[email protected]:/build_opt_plain# cat ehttpd.erl
-module(ehttpd).
-compile(export_all).


start() ->
    start(8888).
start(Port) ->
    N = erlang:system_info(schedulers),
    listen(Port, N),
    io:format("ehttpd ready with ~b schedulers on port ~b~n", [N, Port]),

    register(?MODULE, self()),
    receive Any -> io:format("~p~n", [Any]) end.  %% to stop: ehttpd!stop.

listen(Port, N) ->
    Opts = [{active, false},
            binary,
            {backlog, 256},
            {packet, http_bin},
            {raw,6,9,<<1:32/native>>}, %defer accept
            %%{delay_send,true},
            %%{nodelay,true},
            {reuseaddr, true}],

    {ok, S} = gen_tcp:listen(Port, Opts),
    Spawn = fun(I) ->    
                    register(list_to_atom("acceptor_" ++ integer_to_list(I)),
                             spawn_opt(?MODULE, accept, [S, I], [link, {scheduler, I}]))
            end,
    lists:foreach(Spawn, lists:seq(1, N)).

accept(S, I) ->
    case gen_tcp:accept(S) of
        {ok, Socket} -> spawn_opt(?MODULE, loop, [Socket], [{scheduler, I}]);
        Error    -> erlang:error(Error)
    end,
    accept(S, I).

loop(S) ->
    case gen_tcp:recv(S, 0) of
        {ok, http_eoh} ->
            Response = <<"HTTP/1.1 200 OK\r\nContent-Length: 12\r\n\r\nhello world!">>,
            gen_tcp:send(S, Response),
            gen_tcp:close(S),
            ok;

        {ok, _Data} ->
            loop(S);

        Error ->
            Error
    end.

這個伺服器是最小的,單是在多處理器和單cpu上都有非常好的效能。

[email protected]:/build_opt_plain# cat /proc/cpuinfo
model name      : Pentium(R) Dual-Core  CPU      E5200  @ 2.50GHz

注:這個http伺服器基本上是在c的程式跑,erlang的程式碼執行的很少, 所以hipe的提升效果不是很明顯。對於複雜的業務,應該是有很大的幫助的。

附件裡是用到的指令碼和補丁。

我們可以得出結論:
hipe啟用要比不啟用快。
優化版本的和標準版本的 20090:11203, 效能提高了將近80% 還是非常可觀的。

Post Footer automatically generated by wp-posturl plugin for wordpress.

相關推薦

系統技術業餘研究 » Erlang http hello world 伺服器調指南 20Khttp連結請求/S桌面CPU)

erl的虛擬機器有2種方式 plain版本的和smp版本的。 smp版本由於鎖的開銷相比要比plain版本的慢很多。而32位機器由於記憶體訪問比64位的少,也會快出很多。所有我選擇在32位的linux系統下調優這個httpd伺服器。這個伺服器就是實現個簡單的功能,在browser下返回hello

系統技術業餘研究 » 2017升的的幾個資料庫無責任點評

ItPub寫的文章“2017 年度 DB-Engines 資料庫冠軍得主:PostgreSQL 封王!”, 點選 這裡 進一步閱讀 升的最快的幾個資料庫,我簡單的無責任點評: PG資料庫是很老的資料庫,不過這幾年冉冉升起,因為是學院派的,有很好的學術和智力的支援,一直以來在資料庫的體系結構,程式碼

系統技術業餘研究 » Erlang R15大的賣點Native Process

R15最激動人心的東西就是這個Native Process,請參看Rickard Green寫的Future Extensions to the Native Interface:看 這裡 我來blabla下。 做過Erlang規模程式的人都知道有個痛, Erlang的公平排程引起的痛。 舉個例子

系統技術業餘研究 » Erlang 17.5引入+hpds命令列控制程序預設字典大小

Erlang 17.5釋出引入控制程序預設字典大小的命令列引數: Erlang/OTP 17.5 has been released Written by Henrik, 01 Apr 2015 Some highlights of the release are: ERTS: Added co

系統技術業餘研究 » Erlang R16B03釋出,R17已發力

Erlang R16B03釋出了,通常03版本是bug fix版本,進入生產版本,官方的說明如下: OTP R16B03 is a service release with mostly a number of small corrections and user contributions. B

系統技術業餘研究 » Erlang R13B04 Installation

R13B04後erlang的原始碼編譯為了考慮移植性,就改變了編譯方式,以下是官方wiki上的安裝文件: 1. Cloning Here are the basic steps to build Erlang/OTP in the Git repository. Start by cloning:

系統技術業餘研究 » Erlang R15的記憶體delayed dealloc特性對訊息密集型程式的影響

在新的NUMA體系結構下,每個CPU都有自己的本地記憶體,如果要訪問其他CPU的記憶體,那算remote了,要走CPU之間的QPI通道,通常這樣速度會有40%的下降。 那麼對於多執行緒的程式來講,這個硬體的變化對軟體也有很大的影響。在多執行緒程式裡面,通常一個執行緒會為一個物件分配記憶體,然後把這

系統技術業餘研究 » Erlang R17新特性淺評

Erlang R17RC2 原始碼已經就緒, 參見 這裡 後續版本的釋出時間,官方的時間安排參見 這裡,摘抄如下: Preliminary dates for the upcoming release: Release: erts, emu,comp |Code stop

系統技術業餘研究 » Erlang R16支援帶顏色的控制檯

Erlang通過fix tty驅動的過濾,在R16版本支援帶顏色的控制檯,這個特性在我們做各種監控工具高亮非常有幫助,參見R16的Readme: Support ANSI in console Unix platforms will no longer filter control sequenc

系統技術業餘研究 » 未公開的erlang ports trace

erlang的trace機制非常強大, 在dbg, ttb模組的配合下, 可以非常清楚的瞭解系統的運作, 排錯, 和調優. 但是有個對於做網路程式重要的功能被忽視了, 沒有寫到文件. 那就是trace ports訊息. 我們的gen_tcp,file都是port實現的, 那麼瞭解這麼模組的運作其實

系統技術業餘研究 » 實驗Erlang語法對應的opcode 讓你對erlang理解更深

Erlang作為一門FP語言,和傳統的語言結構一樣, 有模組, 有函式, 有語句, 有判斷, 有迴圈, 還有特別的模式匹配。 那麼這些在底層是如何運作的。 我在底下給大家做個簡單的實驗,讓大家一窺內部的細節,讓大家寫碼的時候知道個大概。 erlang的VM作為register based的VM,

系統技術業餘研究 » erlang coredump問題

早上成立濤同學問道: : :)我們最近發生了幾次宕機。。節點無緣無故就沒有了。也沒有crash dump,也不知道任何線索。 我們知道erlang的VM在正常運作的時候,如果發現erlang程式的異常或者虛擬機器資源不夠如記憶體不夠的時候,會產生erl_crash.dump檔案,裡面把crash的

系統技術業餘研究 » Erlang open_port極度影響效能的因素

Erlang的port相當於系統的IO,打開了Erlang世界通往外界的通道,可以很方便的執行外部程式。 但是open_port的效能對整個系統來講非常的重要,我就帶領大家看看open_port影響效能的因素。 首先看下open_port的文件: {spawn, Command} Star

系統技術業餘研究 » Erlang節點重啟導致的incarnation問題

今天晚上mingchaoyan同學在線上問以下這個問題: 152489 =ERROR REPORT==== 2013-06-28 19:57:53 === 152490 Discarding message {send,<<19 bytes>>} from <0.8

系統技術業餘研究 » whatsapp深度使用Erlang有感

這麼多年過去了,社群還在討論erlang是不是小眾語言,各種懷疑的時候,whatsapp已經把erlang用到了極致。 whatsapp是什麼? 參見它的 官網 WhatsApp Messenger is a cross-platform mobile messaging app which a

系統技術業餘研究 » Erlang port巧用環境變數

Erlang與外面世界的互動主要通過port來進行的,特別是和外部程式的協作,通常是通過管道進行的。 基本上有2種方法可以呼叫外部程式: 1. os:cmd 2. erlang:open_port, 這二種方式各有利弊,先看文件: os:cmd的文件參見這裡 cmd(Command) ->

系統技術業餘研究 » Erlang新新增選項 +zerts_de_busy_limit 控制節點間通訊的資料量

erlang節點間通訊預設是通過tcp通道進行的, 而且每對節點間只有一個tcp連結,所有的rpc和內建的類似monitor這樣的訊息也都是通過這個通道進行的. 當資料量過大的時候, 系統就會發出 busy distribution port警告, 同時限制資料的吞吐. 這個值預設是128k. 現

系統技術業餘研究 » Erlang程式碼反編譯以及檢視彙編碼

Erlang的程式碼是先翻譯成abstract_code,再到目的碼的,如果有符號資訊很容易恢復原始碼,通常我們部署系統的時候需要把符號資訊去掉,reltool就可以幹這個事情! 我們演示下: $ cat server.erl -module(server). -compile(export

系統技術業餘研究 » Erlang Shell實用小技巧

Erlang Shell下有很多內建的命令,在平時互動的時候很好用,文件裡面都是一行帶過,大家可能沒什麼感覺。 我來重點講解和演示下: $ erl Erlang R14B04 (erts-5.8.5) [/source] [smp:2:2] [rq:2] [async-threads:0] [h

系統技術業餘研究 » ”Erlang supervisor 極其白痴的 Bug“的澄清

2008-05-26的時候, 著名的Trustno1發表了這篇文章 http://www.iteye.com/topic/197097 抱怨Erlang supervisor 極其白痴的一個bug. 今天 @淘李福 同學重新提起這個事情: 翻到一個老帖子: http://www.iteye.com