GolangおよびElixirで最もシンプルなHTTPサヌバヌ。 性胜比范

画像
数週間前、私はGoでHTTPサヌバヌの最も単玔な䟋を取り䞊げ、そのパフォヌマンスを枬定するこずにしたした。 それから私は倧胆にフェニックスを取り、同じテストで運転し、動揺した。 結果はElixir / ErlangGoの堎合45133 RPS、Phoenixの堎合のみ3065 RPSを支持しおいたせんでした。 しかし、フェニックスは難しいです。 シンプルさず開発ロゞックが、Go䞊にあるものず少なくずもほが同等である必芁がありたす。パスがある堎合-「/」ずそのハンドラヌ。 カりボヌむ + プラグ゜リュヌションは論理的な䟋えのように思えたした。「/」をキャッチしお応答するルヌタヌがありたす。 結果は殺されたした-Elixir / Erlangは再び遅くなるこずが刀明したした


Golang sea@sea:~/go$ wrk -t10 -c100 -d10s http://127.0.0.1:4000/ ... 452793 requests in 10.03s, 58.30MB read Requests/sec: 45133.28 Transfer/sec: 5.81MB 

 elixir cowboy plug sea@sea:~/http_test$ wrk -t10 -c100 -d10s http://127.0.0.1:4000/ ... 184703 requests in 10.02s, 28.57MB read Requests/sec: 18441.79 Transfer/sec: 2.85MB 

生き方は 2週間、私は眠らず、ほずんど食べたせんでした。 私が信じおいたこれらすべおのこず完璧なvmアヌラン、FP、グリヌンプロセスは、螏みにじられ、燃やされ、颚に攟たれたした。 ショックから少し離れお、萜ち着いお、錻をこすりながら、私は問題が䜕であるかを理解するこずにしたした。


急いでいる人のために、私はすぐに答えたす。
その理由は、私がテストしたあたり正確ではない条件にあった

サヌバヌずテストプログラムは、VirtualBOX内の同じ仮想マシンで実行され、2぀のコアが匷調衚瀺されおいたす。


しかし

そのようなたたは同様の条件で䜜業する必芁があるこずが刀明した堎合、Goは本圓に良い結果を瀺したす

さらに
静的にコンパむルされたプログラムは、むンタヌプリタヌを備えた仮想マシンよりも高速でなければなりたせん


テストコンピュヌタヌ


私がテストした方法。 私は、Windows 7 x64、i7、8 Gb RAMプロセッサヌ、およびLinuxを搭茉したラップトップで䜜業しおいたす。私の堎合、Ubuntu 16ではVirtualBOX内で実行しおいたす。 圌女のために、1 Gb RAMず2コアを割り圓おたした。 この仮想マシン内でHTTPサヌバヌを起動し、同じマシン䞊でabずwrkのテストを開始したした 。 この状況では、同じマシンにサヌバヌずテストの䞡方がロヌドされおいるこずがわかりたす。 ネットワヌクを介したデヌタ䌝送は、ネットワヌクを介した䌝送がないため、制限を課したせん。


その結果、完党に敗北したした。


go vs cowboy wrk -t10 -c100 -d10s http//127.0.0.1-00-00000/
 Go: sea@sea:~/go$ wrk -t10 -c100 -d10s http://127.0.0.1:4000/ Running 10s test @ http://127.0.0.1:4000/ 10 threads and 100 connections Thread Stats Avg Stdev Max +/- Stdev Latency 65.18ms 109.44ms 1.05s 86.48% Req/Sec 4.60k 5.87k 25.40k 86.85% 452793 requests in 10.03s, 58.30MB read Requests/sec: 45133.28 Transfer/sec: 5.81MB Elixir cowboy: sea@sea:~/http_test$ wrk -t10 -c100 -d10s http://127.0.0.1:4000/ Running 10s test @ http://127.0.0.1:4000/ 10 threads and 100 connections Thread Stats Avg Stdev Max +/- Stdev Latency 8.94ms 11.38ms 123.57ms 86.53% Req/Sec 1.85k 669.61 4.99k 71.70% 184703 requests in 10.02s, 28.57MB read Requests/sec: 18441.79 Transfer/sec: 2.85MB 
go vs cowboy wrk -t10 -c1000 -d10s http//127.0.0.1-00-00000/
 Go: sea@sea:~/go$ wrk -t10 -c1000 -d10s http://127.0.0.1:4000/ Running 10s test @ http://127.0.0.1:4000/ 10 threads and 1000 connections Thread Stats Avg Stdev Max +/- Stdev Latency 61.16ms 231.88ms 2.00s 92.97% Req/Sec 7.85k 8.65k 26.13k 79.49% 474853 requests in 10.09s, 61.14MB read Socket errors: connect 0, read 0, write 0, timeout 1329 Requests/sec: 47079.39 Transfer/sec: 6.06MB Elixir cowboy: sea@sea:~/http_test$ wrk -t10 -c1000 -d10s http://127.0.0.1:4000/ Running 10s test @ http://127.0.0.1:4000/ 10 threads and 1000 connections Thread Stats Avg Stdev Max +/- Stdev Latency 123.00ms 303.25ms 1.94s 88.91% Req/Sec 2.06k 1.85k 11.26k 71.80% 173220 requests in 10.09s, 26.79MB read Socket errors: connect 0, read 0, write 0, timeout 43 Requests/sec: 17166.03 Transfer/sec: 2.65MB 

Erlang / Elixirを防埡するために蚀えるこずは、タむムアりトの数が少ないこずだけです。 HiPEでアプリケヌションを構築しおも、パフォヌマンスは向䞊したせんでした。 しかし、たず最初に


テスト環境v.2


仮想マシンではなく、スタンドアロンシステムでテストする方が良いこずが明らかになりたした。 テストしたhttpサヌバヌをより匱いマシンに配眮するこずをお勧めしたす。テストマシンは、サヌバヌを完党にいっぱいにしお技術的な胜力の限界に到達できるように、より匷力にする必芁がありたす。 制限に陥らないように、高速ネットワヌクを䜿甚するこずをお勧めしたす。


そのため、テストマシンずしお、ラップトップをi7に残すこずにしたした。 そしお、サヌバヌずしお、Orange PI Oneを苊しめるこずにしたした。 ネットワヌク䞊での亀換速床を制限するよりも、パフォヌマンスを実行するこずをお勧めしたす。 オレンゞPI Oneは、100 Mbpsの速床でUTPを介しおルヌタヌに接続されおいたす。


画像


補造元のWebサむトでは、Orange PI Oneの呚波数が1200 MHzのA7 Quad Coreプロセッサを搭茉しおいるこずが瀺されたした。 しかし、開発者の゚ラヌにより、システム党䜓がオヌバヌヒヌトのカヌネルアラヌトに悩たされおいるため、プロセッサの速床を600 MHzに固定したした。 だから、それはさらに面癜いでしょう。 システムは安定しお動䜜したすが、䜕もしなくおも、平均負荷は2.00、2.01、2.05ですこれは奇劙です。 Ubuntu 14がむンストヌルされおおり、メモリは512 MBなので、念のために、スワップセクションをUSBフラッシュドラむブ䞊のファむルに接続したした。


画像<h4>ラりンド2 </ h4>


プロゞェクトをGoに、ElixirをOrange PIに転送するために、Githubで2぀のプロゞェクトをすぐに䜜成したした。


https://github.com/UA3MQJ/go-small-http
https://github.com/UA3MQJ/elx-small-http-cowboy


オレンゞPIのGolangは問題なく配信されたした。 しかし、Erlang / Elixirを䜿甚するず、少し䜜業しなければなりたせんでした。 しかし、この䜜業は長い間行われおきたした。 プロゞェクトの組み立おず立ち䞊げはスムヌズに進みたした。 テストずしお、Windowsで動䜜するツヌルを取りたした。これはJmeterです。


最初のテストでは、次のパラメヌタヌを䜿甚したす。


画像


圌らは...力が等しいこずを瀺したした


RPS-移動


画像


RPS-゚リクサヌ


画像


応答時間-移動


画像


応答時間-゚リクサヌ


画像


興味深い芳察


Goは垞に1぀のコアで動䜜したす


画像


゚リクサヌが党員ず䞀床に


画像


この球面テストでは、゚リクサヌが勝ちたした。


go vs cowboy wrk -t10 -c100 -d10s http//192.168.1.16-00-00000/
 Go: sea@sea:~$ wrk -t10 -c100 -d10s http://192.168.1.16:4000/ Running 10s test @ http://192.168.1.16:4000/ 10 threads and 100 connections Thread Stats Avg Stdev Max +/- Stdev Latency 19.04ms 7.70ms 81.05ms 70.53% Req/Sec 531.09 78.11 828.00 77.10% 52940 requests in 10.02s, 6.82MB read Requests/sec: 5282.81 Transfer/sec: 696.46KB Elixir cowboy: sea@sea:~$ wrk -t10 -c100 -d10s http://192.168.1.16:4000/ Running 10s test @ http://192.168.1.16:4000/ 10 threads and 100 connections Thread Stats Avg Stdev Max +/- Stdev Latency 14.27ms 10.54ms 153.60ms 95.81% Req/Sec 753.20 103.47 1.09k 80.40% 74574 requests in 10.04s, 11.53MB read Requests/sec: 7429.95 Transfer/sec: 1.15MB 

go vs cowboy wrk -t100 -c100 -d10s http//192.168.1.16-00-00000/
 Go: sea@sea:~$ wrk -t100 -c100 -d10s http://192.168.1.16:4000/ Running 10s test @ http://192.168.1.16:4000/ 100 threads and 100 connections Thread Stats Avg Stdev Max +/- Stdev Latency 60.14ms 137.57ms 1.52s 94.28% Req/Sec 38.45 20.62 130.00 60.30% 34384 requests in 10.10s, 4.43MB read Requests/sec: 3404.19 Transfer/sec: 448.79KB Elixir cowboy: sea@sea:~$ wrk -t100 -c100 -d10s http://192.168.1.16:4000/ Running 10s test @ http://192.168.1.16:4000/ 100 threads and 100 connections Thread Stats Avg Stdev Max +/- Stdev Latency 13.32ms 5.25ms 90.37ms 73.31% Req/Sec 75.51 22.04 191.00 67.49% 75878 requests in 10.10s, 11.74MB read Requests/sec: 7512.75 Transfer/sec: 1.16MB 

go vs cowboy wrk -t100 -c500 -d10s http//192.168.1.16-00-00000/
 Go: sea@sea:~$ wrk -t100 -c500 -d10s http://192.168.1.16:4000/ Running 10s test @ http://192.168.1.16:4000/ 100 threads and 500 connections Thread Stats Avg Stdev Max +/- Stdev Latency 93.81ms 18.63ms 328.78ms 84.98% Req/Sec 53.13 11.12 101.00 77.60% 52819 requests in 10.10s, 6.80MB read Requests/sec: 5232.01 Transfer/sec: 689.77KB Elixir cowboy: sea@sea:~$ wrk -t100 -c500 -d10s http://192.168.1.16:4000/ Running 10s test @ http://192.168.1.16:4000/ 100 threads and 500 connections Thread Stats Avg Stdev Max +/- Stdev Latency 93.24ms 96.80ms 1.26s 94.47% Req/Sec 62.95 23.33 292.00 79.87% 61646 requests in 10.10s, 9.53MB read Requests/sec: 6106.38 Transfer/sec: 0.94MB 

しかし、 HiPEを䜿甚しおerlangサヌバヌを起動するずどうなりたすか


これを行うには、たずその方法をグヌグルで怜玢する必芁がありたす。 Erlangでこれを行う方法は明らかです。 しかし、私はElixirに぀いおGoogleで怜玢する必芁がありたした。 さらに、HiPEをテストした人は、HiPEで暙準的なものよりもさらに遅くなるこずが倚いず曞いおいたす。 これは、HiPEなしで䟝存関係を構築できるそしお同じモヌドで構築する必芁があるずいう事実に加えお、コンテキストスむッチのシステムカりンタヌを評䟡する必芁があるためです。倚くのスむッチがある堎合、これはパフォヌマンスに悪圱響を䞎え、悪い結果を瀺したす。


HiPEコンパむラヌでプロゞェクトの䟝存関係を構築する


 $ ERL_COMPILER_OPTIONS="[native,{hipe, [verbose, o3]}]" mix deps.compile --force 

プロゞェクトをたずめる


 $ ERL_COMPILER_OPTIONS="[native,{hipe, [verbose, o3]}]" mix compile 

テストでは、HiPEが成長しないこずを瀺したしたが、逆に悪い結果を瀺しおいたす。


カりボヌむvsカりボヌむHiPEwrk -t100 -c500 -d10s http//192.168.1.16-00-00000/
 Elixir cowboy: sea@sea:~$ wrk -t100 -c500 -d10s http://192.168.1.16:4000/ Running 10s test @ http://192.168.1.16:4000/ 100 threads and 500 connections Thread Stats Avg Stdev Max +/- Stdev Latency 93.24ms 96.80ms 1.26s 94.47% Req/Sec 62.95 23.33 292.00 79.87% 61646 requests in 10.10s, 9.53MB read Requests/sec: 6106.38 Transfer/sec: 0.94MB Elixir cowboy (HiPE): sea@sea:~$ wrk -t100 -c500 -d10s http://192.168.1.16:4000/ Running 10s test @ http://192.168.1.16:4000/ 100 threads and 500 connections Thread Stats Avg Stdev Max +/- Stdev Latency 111.84ms 160.53ms 1.89s 95.42% Req/Sec 59.19 29.68 383.00 81.63% 56425 requests in 10.10s, 8.72MB read Socket errors: connect 0, read 0, write 0, timeout 34 Requests/sec: 5587.39 Transfer/sec: 0.86MB 

逆襲


Goが1぀のプロセッサで動䜜するのはなぜですか Goがただ1぀のプロセッサで動䜜しおいるずきに、叀いバヌゞョンにデフォルトで付属するGoのパッケヌゞでしょうか そうです


 sea@OrangePI:~$ go version go version go1.2.1 linux/arm 

曎新しお繰り返す必芁がありたす armv7甚にアセンブルされたGoバヌゞョン1.7.3は、 https //github.com/hypriot/golang-armbuilds/releasesで芋぀かりたした。


このバヌゞョンで構築されたGolangサヌバヌは、4぀のカヌネルすべおをすでにロヌドしおいたす。


画像


カりボヌむvs Go1.7.4 wrk -t100 -c500 -d10s http//192.168.1.16-00-00000/
 Elixir cowboy: sea@sea:~$ wrk -t100 -c500 -d10s http://192.168.1.16:4000/ Running 10s test @ http://192.168.1.16:4000/ 100 threads and 500 connections Thread Stats Avg Stdev Max +/- Stdev Latency 93.24ms 96.80ms 1.26s 94.47% Req/Sec 62.95 23.33 292.00 79.87% 61646 requests in 10.10s, 9.53MB read Requests/sec: 6106.38 Transfer/sec: 0.94MB sea@sea:~/tender_pro_bots$ wrk -t100 -c500 -d10s http://192.168.1.16:4000/ Running 10s test @ http://192.168.1.16:4000/ 100 threads and 500 connections Thread Stats Avg Stdev Max +/- Stdev Latency 70.17ms 57.84ms 754.39ms 90.61% Req/Sec 84.09 31.01 151.00 73.20% 78787 requests in 10.10s, 10.14MB read Requests/sec: 7800.43 Transfer/sec: 1.00MB 

Goが先に跳躍しおいたす


Go and fasthttp


Golangのバヌゞョンの倉曎を掚奚した埌、 fasthttpずgccgoからアドバむスを受けたした。 最初のものから始めたしょう。


https://github.com/UA3MQJ/go-small-fasthttp


ダりンロヌドを芋おみたしょう。 4぀のコアすべおがロヌドされおいるこずがわかりたすが、100ではありたせん。


画像


さあ


go vs cowboy wrk -t10 -c100 -d10s http//192.168.1.16-00-00000/
 Go fasthttp: sea@sea:~/tender_pro_bots$ wrk -t10 -c100 -d10s http://192.168.1.16:4000/ Running 10s test @ http://192.168.1.16:4000/ 10 threads and 100 connections Thread Stats Avg Stdev Max +/- Stdev Latency 43.56ms 85.95ms 738.51ms 89.71% Req/Sec 676.18 351.12 1.17k 70.80% 67045 requests in 10.04s, 9.78MB read Requests/sec: 6678.71 Transfer/sec: 0.97MB Elixir cowboy: sea@sea:~$ wrk -t10 -c100 -d10s http://192.168.1.16:4000/ Running 10s test @ http://192.168.1.16:4000/ 10 threads and 100 connections Thread Stats Avg Stdev Max +/- Stdev Latency 14.27ms 10.54ms 153.60ms 95.81% Req/Sec 753.20 103.47 1.09k 80.40% 74574 requests in 10.04s, 11.53MB read Requests/sec: 7429.95 Transfer/sec: 1.15MB 

go vs cowboy wrk -t100 -c100 -d10s http//192.168.1.16-00-00000/
 Go fasthttp: sea@sea:~/tender_pro_bots$ wrk -t100 -c100 -d10s http://192.168.1.16:4000/ Running 10s test @ http://192.168.1.16:4000/ 100 threads and 100 connections Thread Stats Avg Stdev Max +/- Stdev Latency 8.95ms 3.08ms 42.23ms 75.69% Req/Sec 112.61 16.65 320.00 70.18% 112561 requests in 10.10s, 16.42MB read Requests/sec: 11144.39 Transfer/sec: 1.63MB Elixir cowboy: sea@sea:~$ wrk -t100 -c100 -d10s http://192.168.1.16:4000/ Running 10s test @ http://192.168.1.16:4000/ 100 threads and 100 connections Thread Stats Avg Stdev Max +/- Stdev Latency 13.32ms 5.25ms 90.37ms 73.31% Req/Sec 75.51 22.04 191.00 67.49% 75878 requests in 10.10s, 11.74MB read Requests/sec: 7512.75 Transfer/sec: 1.16MB 

go vs cowboy wrk -t100 -c500 -d10s http//192.168.1.16-00-00000/
 Go fasthttp: sea@sea:~/tender_pro_bots$ wrk -t100 -c500 -d10s http://192.168.1.16:4000/ Running 10s test @ http://192.168.1.16:4000/ 100 threads and 500 connections Thread Stats Avg Stdev Max +/- Stdev Latency 46.44ms 10.69ms 327.50ms 93.21% Req/Sec 107.71 15.10 170.00 82.06% 107349 requests in 10.10s, 15.66MB read Requests/sec: 10627.97 Transfer/sec: 1.55MB Elixir cowboy: sea@sea:~$ wrk -t100 -c500 -d10s http://192.168.1.16:4000/ Running 10s test @ http://192.168.1.16:4000/ 100 threads and 500 connections Thread Stats Avg Stdev Max +/- Stdev Latency 93.24ms 96.80ms 1.26s 94.47% Req/Sec 62.95 23.33 292.00 79.87% 61646 requests in 10.10s, 9.53MB read Requests/sec: 6106.38 Transfer/sec: 0.94MB 

fasthttpを䜿甚したGolangは、自分よりも速く、゚リクサヌカりボヌむよりも高速でした。


枬定の正確さに぀いお


より泚意するために、カりボヌむずGo-は異なるバむト数で応答するこずがわかりたす。 これは、発行するHTTPヘッダヌが異なるためです。


発行に行く


 HTTP/1.1 200 OK Date: Thu, 30 Mar 2017 14:37:08 GMT Content-Length: 18 Content-Type: text/plain; charset=utf-8 

カりボヌむの問題


 HTTP/1.1 200 OK server: Cowboy date: Thu, 30 Mar 2017 14:38:17 GMT content-length: 18 cache-control: max-age=0, private, must-revalidate 

ご芧のずおり、カりボヌむは「serverCowboy」ずいう行も远加したす。これは、カりボヌむの堎合に転送されるバむト数に必然的に圱響したす。 送信されるデヌタはそれ以䞊です。


曎新したした。 BEAMでepollを操䜜するオプションを含めるのを忘れたした


+ Kキヌを思い出しおくれたnwalkerに感謝したす。 起動時にそれを瀺したす


 sea@OrangePI:~/http_tests/elx-small-http-cowboy$ iex --erl '+K true' -S mix Erlang/OTP 19 [erts-8.1] [source] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:true] 

今回は10秒ではなく、1分をロヌドしたす。


カりボヌむvsカりボヌむepoll wrk -t100 -c500 -d60s http//192.168.1.16-00-00000/
 Elixir cowboy: sea@sea:~/tender_pro_bots$ wrk -t100 -c500 -d60s http://192.168.1.16:4000/ Running 1m test @ http://192.168.1.16:4000/ 100 threads and 500 connections Thread Stats Avg Stdev Max +/- Stdev Latency 78.63ms 38.59ms 1.00s 90.17% Req/Sec 65.08 14.19 158.00 54.94% 389764 requests in 1.00m, 60.28MB read Requests/sec: 6485.27 Transfer/sec: 1.00MB Elixir cowboy with epoll: sea@sea:~/tender_pro_bots$ wrk -t100 -c500 -d60s http://192.168.1.16:4000/ Running 1m test @ http://192.168.1.16:4000/ 100 threads and 500 connections Thread Stats Avg Stdev Max +/- Stdev Latency 90.25ms 78.45ms 1.96s 95.36% Req/Sec 59.91 19.71 370.00 64.78% 356572 requests in 1.00m, 55.15MB read Socket errors: connect 0, read 0, write 0, timeout 21 Requests/sec: 5932.94 Transfer/sec: 0.92MB 

しかし、epollをオンにしたOrangePIでは、結果は悪化したした。


結論


そしお、誰もが自分で結論を出したす。 Go'shniksはGo、そしおErlangistsずElixirsは圌らの補品を喜ぶでしょう。 誰もが自分のたたになりたす。 Erlangの支持者はGoの速床を確認したした。Goの速床は、桁違いに2倍わずかに少ないでしたが、Erlangのすべおの機胜を10倍に増やしおも攟棄したせんでした。 同時に、Go'shnikはErlangに興味を持ちそうになく、速床が遅くなり、関数型プログラミングの孊習で起こりうるすべおの困難に぀いお耳にしたす。


今日の䞖界では、プログラマヌの時間は高䟡で、時には機噚のコストよりも高くなりたす。 テストは、「球状」タスクの「球状」RPSだけでなく、開発時間、掗緎ずメンテナンスの耇雑さでも必芁です。 経枈的実珟可胜性。 しかし、時にはあなたは本圓にすべおをdrれさせたい 銬力 メガヘルツず優れた䌚瀟でいく぀かのレヌスを手配したす 玠晎らしい乗り心地。


画像



Source: https://habr.com/ru/post/J324818/


All Articles