nimble install mummy
Referensi API
Mummy adalah server HTTP 1.1 dan Websocket multi-threaded yang ditulis sepenuhnya di NIM.
Kembali ke cara -cara kuno benang.
Mummy telah ditulis secara khusus untuk memaksimalkan kinerja perangkat keras server Anda tanpa mengurangi kebahagiaan programmer.
{.async.} . Mummy Membutuhkan --threads:on dan --mm:orc atau --mm:arc .
Nama mumi mengacu pada hal -hal historis Mesir.
Mummy beroperasi dengan model dasar ini: Tangani semua soket IO pada satu utas dan pengiriman permintaan HTTP yang masuk dan acara WebSocket ke kumpulan utas pekerja. Penangan HTTP Anda mungkin bahkan tidak perlu memikirkan utas sama sekali.
Model ini memiliki banyak manfaat besar dan siap untuk memanfaatkan peningkatan jumlah inti server yang berkelanjutan (AMD baru saja mengumumkan CPU server utas 96 Core 192!).
Tidak perlu lagi menggunakan {.async.} , Future[] , await dll dan berurusan dengan fungsi yang memiliki warna.
Pertahankan throughput yang sama dari soket nonblocking multiplexed IO.
Tidak ada kekhawatiran bahwa satu pemblokiran atau panggilan mahal akan menghentikan seluruh server Anda.
Async Blok pada hal -hal mengejutkan seperti resolusi DNS dan file baca yang akan menghentikan semua penanganan permintaan.
Lebih sederhana untuk menulis penangan permintaan. Memblokir utasnya benar -benar baik -baik saja! Perlu membuat kueri Postgres? Tidak masalah, tunggu saja hasilnya.
Ada keuntungan besar untuk menulis kode yang lebih sederhana vs secara teoritis cepat tetapi mungkin kode buggy yang berbelit -belit dan buggy.
Debugging yang jauh lebih sederhana. Jejak tumpukan async sangat besar dan membingungkan.
Penanganan kesalahan yang lebih mudah, try except seperti yang biasa Anda lakukan. Pengecualian yang Tanpa Bersih pada Penangan Mumi juga tidak menurunkan seluruh server Anda.
Mummy menangani threading dan pengiriman sehingga penangan Anda mungkin tidak perlu memikirkan utas sama sekali.
Mengambil keuntungan dari banyak inti dan pekerjaan luar biasa dari tim NIM di ARC / ORC dan NIM 2.0.
Websockets luar biasa dan dapat memiliki keunggulan besar dibandingkan paradigma API yang lebih tradisional seperti istirahat dan berbagai rasa RPC.
Sayangnya, sebagian besar server HTTP berpura -pura tidak ada.
Ini berarti pengembang perlu meretas dukungan melalui ketergantungan tambahan, membajak koneksi dll dan semuanya jarang bertambah menjadi sesuatu yang sangat hebat.
Saya tidak melihat alasan mengapa Websockets tidak boleh bekerja dengan sangat baik di luar kotak, menyimpan banyak pengembang ketidakpastian dan waktu meneliti mana dari cara yang mungkin untuk mengayunkan dukungan websocket di server HTTP adalah "terbaik".
Semuanya datang dengan trade-off. Mummy fokus menjadi server API yang luar biasa. Pikirkan istirahat, json, rpc, websockets, html dari templat dll.
Properti yang sama-sama dibagikan ini adalah semuanya relatif cahaya memori. Sebagian besar hal adalah, yang hebat, tetapi jika Anda secara khusus akan menyajikan banyak file yang sangat besar atau mengharapkan unggahan file besar, mumi mungkin bukan pilihan terbaik kecuali server Anda memiliki RAM untuk menangani file besar.
Mengapa mumi tidak bagus untuk file besar? Ini karena pengiriman mumi sepenuhnya menerima permintaan dalam memori ke utas pekerja dan mengirimkan tanggapan dalam memori. Ini bagus untuk semuanya kecuali file yang sangat besar.
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 ))Lihat contoh/ folder untuk lebih banyak kode sampel, termasuk contoh server obrolan WebSocket.
nim c --threads:on --mm:orc -r examples/basic_websockets.nim
Benchmarking Server HTTP agak seperti mencolok sepatu lari.
Tentu saja, ada beberapa sepatu yang mengerikan untuk dijalankan (tumit, bakiak, dll), tetapi begitu Anda berada dalam sepasang sepatu yang masuk akal, pelari yang akan menjadi masalah, bukan sepatu.
Dalam analogi ini, pelari adalah apa yang sebenarnya dilakukan penangan Anda dan sepatu adalah pilihan server HTTP.
Dengan mengingat hal itu, saya menyarankan tiga prioritas:
Pastikan pilihan server HTTP Anda tidak menghambat kinerja yang tidak perlu.
Hindari server HTTP yang memiliki kerentanan kinerja yang mudah.
Prioritaskan apa yang akan memungkinkan Anda untuk menulis dan memelihara penangan yang berkinerja dan andal.
Saya percaya Mummy membersihkan ketiga prioritas:
Mummy memprioritaskan efisiensi dalam menerima dan mengirimkan permintaan yang masuk dan mengirimkan tanggapan keluar. Ini berarti hal -hal seperti menghindari penyalinan memori yang tidak perlu, memastikan CPU menghabiskan seluruh waktunya di penangan Anda.
Karena Mummy menggunakan IO multiplexed seperti async, mumi tidak rentan terhadap serangan seperti rendah dan lambat yang secara tradisional server multi-threaded rentan. Selain itu, sementara satu pemblokiran atau operasi berat CPU dapat menghentikan seluruh server async, ini bukan masalah bagi mumi.
Penangan permintaan dengan mumi hanyalah kode NIM inline yang jelas. Mereka memiliki API permintaan-dalam-respons-out. Menjaga hal -hal sederhana sangat bagus untuk pemeliharaan, keandalan, dan kinerja.
Benchmarking dilakukan pada server Ubuntu 22.04 dengan CPU utas 4 Core / 8.
Server Tes/WRK_ yang sedang dalam upaya pembandingan untuk mensimulasikan permintaan yang membutuhkan ~ 10ms untuk menyelesaikannya.
Semua tolok ukur diuji oleh:
wrk -t10 -c100 -d10s http://localhost:8080
Perintah yang tepat untuk setiap server adalah:
nim c --mm:orc --threads:on -d:release -r tests/wrk_mummy.nim
Permintaan/detik: 9.547.56
nim c --mm:orc --threads:off -d:release -r tests/wrk_asynchttpserver.nim
Permintaan/detik: 7.979.67
nim c --mm:orc --threads:on -d:release -r tests/wrk_httpbeast.nim
Permintaan/detik: 9.862.00
nim c --mm:orc --threads:off -d:release -r tests/wrk_jester.nim
Permintaan/detik: 9.692.81
nim c --mm:orc --threads:off -d:release -r tests/wrk_prologue.nim
Permintaan/detik: 9.749.22
node tests/wrk_node.js
Permintaan/detik: 8.544.60
go run tests/wrk_go.go
Permintaan/detik: 9.171.55
Fuzzer telah dijalankan terhadap pembacaan soket Mummy dan kode penguraian untuk memastikan mumi tidak macet atau melakukan kesalahan pada data yang buruk dari soket. Anda dapat menjalankan fuzzer kapan saja dengan menjalankan nim c -r tests/fuzz_recv.nim .