nimble install mummy
APIリファレンス
Mummyは、Multi-Threaded HTTP 1.1とNIMで完全に記述されたWebSocketサーバーです。
スレッドの古代の方法に戻る。
ミイラは、プログラマの幸福を損なうことなく、サーバーハードウェアのパフォーマンスを最大化するために特別に書かれています。
{.async.}価格なしで多重化されたソケットio。ミイラが必要です--threads:onおよび--mm:orcまたは--mm:arc 。
ミイラの名前は歴史的なエジプトのものを指します。
ミイラはこの基本的なモデルで動作します。1つのスレッドですべてのソケットIOを処理し、受信HTTPリクエストとWebSocketイベントをワーカースレッドのプールにディスパッチします。 HTTPハンドラーは、おそらくスレッドについて考える必要さえありません。
このモデルには多くの大きな利点があり、継続的なサーバーコアカウントの増加を活用する準備ができています(AMDは96 Core 192スレッドサーバーCPUを発表しました!)。
{.async.} 、 Future[] 、 awaitなどを使用する必要はもうありません。
多重化されたノンブロッキングソケットIOの同じ優れたスループットを維持します。
1つのブロッキングまたは高価な通話がサーバー全体を失速させるという懸念はありません。
Asyncは、すべてのリクエスト処理を停止するDNS解像度やファイル読み取りなどの驚くべきことをブロックします。
リクエストハンドラーを簡単に書きます。スレッドをブロックするのはまったく問題ありません!ポストグレスクエリを作成する必要がありますか?問題ありません。結果を待ってください。
よりシンプルなコードと理論的に高速であるが、おそらく複雑でバギーコードを書くことには大きな利点があります。
はるかにシンプルなデバッグ。 Asyncスタックトレースは巨大で混乱しています。
エラー処理が簡単です。通常と同じようtry except 。ミイラハンドラーの猛攻撃の例外も、サーバー全体を倒しません。
ミイラはスレッドとディスパッチを処理するため、ハンドラーはスレッドについてまったく考える必要がないかもしれません。
ARC / ORCとNIM 2.0のNIMチームの複数のコアと驚くべき仕事を利用しています。
WebSocketsは素晴らしく、RESTやRPCのさまざまなフレーバーなど、従来のAPIパラダイムよりも大きな利点があります。
残念ながら、ほとんどのHTTPサーバーのふりWebSocketsは存在しません。
これは、開発者が追加の依存関係、接続のハイジャックなどを通じてサポートをハッキングする必要があることを意味します。
WebSocketsが箱から出して非常にうまく機能しない理由はないと思います。開発者に多くの不確実性と時間を節約し、WebSocketサポートをHTTPサーバーにくすくす方法のどれが「最適」であるかを調査します。
すべてにトレードオフが付いています。ミイラは、例外的なAPIサーバーであることに焦点を当てています。 Think Rest、JSON、RPC、WebSockets、HTMLからテンプレートなど。
これらの共通の共有のプロパティは、すべて比較的記憶の光です。ほとんどのことは素晴らしいことですが、特に非常に大きなファイルをたくさん提供したり、大きなファイルのアップロードを期待したりする場合、サーバーに大きなファイルを処理するRAMがない限り、ミイラはおそらく最良の選択ではありません。
なぜ大規模なファイルにはミイラが優れていないのですか?これは、ミイラディスパッチがワーカースレッドへのメモリ内リクエストを完全に受け取って、メモリ内の応答を送信するためです。これは、非常に大きなファイルを除くすべてに最適です。
import mummy, mummy / routers
proc indexHandler (request: Request ) =
var headers: HttpHeaders
headers[ " Content-Type " ] = " text/plain "
request. respond ( 200 , headers, " Hello, World! " )
var router: Router
router. get ( " / " , indexHandler)
let server = newServer (router)
echo " Serving on http://localhost:8080 "
server. serve ( Port ( 8080 )) nim c --threads:on --mm:orc -r examples/basic_router.nim
import mummy, mummy / routers
proc indexHandler (request: Request ) =
var headers: HttpHeaders
headers[ " Content-Type " ] = " text/html "
request. respond ( 200 , headers, """
<script>
var ws = new WebSocket("ws://localhost:8080/ws");
ws.onmessage = function (event) {
document.body.innerHTML = event.data;
};
</script>
""" )
proc upgradeHandler (request: Request ) =
let websocket = request. upgradeToWebSocket ()
websocket. send ( " Hello world from WebSocket! " )
proc websocketHandler (
websocket: WebSocket ,
event: WebSocketEvent ,
message: Message
) =
case event:
of OpenEvent :
discard
of MessageEvent :
echo message.kind, " : " , message.data
of ErrorEvent :
discard
of CloseEvent :
discard
var router: Router
router. get ( " / " , indexHandler)
router. get ( " /ws " , upgradeHandler)
let server = newServer (router, websocketHandler)
echo " Serving on http://localhost:8080 "
server. serve ( Port ( 8080 ))Websocket Chat Serverのサンプルを含む、より多くのサンプルコードについては、例/フォルダーを参照してください。
nim c --threads:on --mm:orc -r examples/basic_websockets.nim
HTTPサーバーのベンチマークは、ランニングシューズのベンチマークに似ています。
確かに、走るべきひどい靴(かかと、詰まりなど)がありますが、靴ではなく、合理的な靴を履いたら、それが問題になるのはランナーです。
この類推では、ランナーはあなたのハンドラーが実際に行っていることであり、靴はHTTPサーバーの選択です。
それを念頭に置いて、私は3つの優先順位を提案します。
HTTPサーバーの選択が不必要にパフォーマンスを妨げないようにしてください。
簡単なパフォーマンスの脆弱性を持つHTTPサーバーを避けてください。
パフォーマンスと信頼性の高いハンドラーを書き込み、維持できるものを優先します。
ミイラは3つの優先事項すべてをクリアすると思います。
ミイラは、着信要求の受信と発送の効率性を優先し、発信応答を送信します。これは、不必要なメモリのコピーを避け、CPUがハンドラーにすべての時間を費やすようにするなどのことを意味します。
MummyはAsyncのように多重化されたIOを使用するため、Mummyは、従来のマルチスレッドサーバーが脆弱である低斜面のような攻撃に対して脆弱ではありません。さらに、単一のブロッキングまたはCPUの重い操作は非同期サーバー全体を失速させる可能性がありますが、これはミイラにとっては問題ではありません。
ミイラのリクエストハンドラーは、昔ながらのインラインNIMコードです。彼らは、直接的なリクエストインスポンスアウトAPIを持っています。物事をシンプルに保つことは、メンテナンス、信頼性、パフォーマンスに最適です。
ベンチマークは、4コア / 8スレッドCPUを備えたUbuntu 22.04サーバーで行われました。
ベンチマークされているテスト/WRK_サーバーは、完了するまでに〜10msかかるリクエストをシミュレートしようとします。
すべてのベンチマークは次のようにテストされました。
wrk -t10 -c100 -d10s http://localhost:8080
各サーバーの正確なコマンドは次のとおりです。
nim c --mm:orc --threads:on -d:release -r tests/wrk_mummy.nim
リクエスト/秒:9,547.56
nim c --mm:orc --threads:off -d:release -r tests/wrk_asynchttpserver.nim
リクエスト/秒:7,979.67
nim c --mm:orc --threads:on -d:release -r tests/wrk_httpbeast.nim
リクエスト/秒:9,862.00
nim c --mm:orc --threads:off -d:release -r tests/wrk_jester.nim
リクエスト/秒:9,692.81
nim c --mm:orc --threads:off -d:release -r tests/wrk_prologue.nim
リクエスト/秒:9,749.22
node tests/wrk_node.js
リクエスト/秒:8,544.60
go run tests/wrk_go.go
リクエスト/秒:9,171.55
ファザーは、ミイラのソケットの読み取りと解析コードに対して実行され、ミイラがソケットからの悪いデータをクラッシュさせたり、不正に誤ったりしないようにしています。 nim c -r tests/fuzz_recv.nimを実行して、いつでもファッツァーを実行できます。