nimble install mummy
API參考
木乃伊是多線程的HTTP 1.1,並且完全用NIM寫成的WebSocket服務器。
返回古老的線程方式。
木乃伊是為了最大程度地提高服務器硬件性能而不會損害程序員幸福感。
{.async.}價格。木乃伊需要--threads:on and --mm:orc或--mm:arc 。
木乃伊的名字是指歷史悠久的埃及東西。
木乃伊使用此基本模型運行:處理一個線程上的所有套接字IO,並將傳入的HTTP請求和Websocket Events派遣到Worker線程池。您的HTTP處理程序甚至根本不需要考慮線程。
該模型具有許多巨大的好處,並準備好利用持續的服務器核心計數增加(AMD剛剛宣布了96 Core 192線程服務器CPU!)。
無需再使用{.async.} , Future[] , await等,並處理具有顏色的功能。
保持多路復用插座IO的出色吞吐量。
不必擔心一個封鎖或昂貴的電話會使您的整個服務器失速。
異步會阻止令人驚訝的DNS分辨率和文件讀數等令人驚訝的事情,這將使所有請求處理。
更簡單地編寫請求處理程序。阻止線程完全可以!需要進行郵政查詢嗎?沒問題,只需等待結果即可。
編寫更簡單的代碼與理論上快速但可能令人費解和故障代碼具有很大的優勢。
調試要簡單得多。異步堆棧痕跡巨大且令人困惑。
更輕鬆的錯誤處理,只需try except像通常這樣做。木乃伊處理程序中未接收的例外也不會降低整個服務器。
木乃伊可以處理螺紋和調度,因此您的處理程序可能根本不需要考慮線程。
利用多個內核以及NIM團隊在ARC / ORC和NIM 2.0上的驚人工作。
Websocket非常出色,可以比更傳統的API範式(如REST和RPC的各種口味)具有可觀的優勢。
不幸的是,大多數HTTP服務器都不存在Websockets。
這意味著開發人員需要通過其他依賴關係,劫持連接等來攻擊支持,這一切都很少加起來很棒。
我沒有看到為什麼Websocket不應該在開箱即用的地方出色地工作,從而為開發人員提供了很多不確定性和時間研究websocket支持在HTTP服務器上的可能方法是“最佳”。
一切都取決於權衡。木乃伊專注於成為傑出的API服務器。想想休息,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聊天服務器。
nim c --threads:on --mm:orc -r examples/basic_websockets.nim
基準測試HTTP服務器有點像是基準的跑步鞋。
當然,有一些可怕的鞋子可以穿(高跟鞋,木log等),但是一旦您穿著一雙合理的鞋子,跑步者就會很重要,而不是鞋子。
以此為類比,跑步者是您的處理程序實際在做的事情,鞋子是HTTP服務器的選擇。
考慮到這一點,我建議三個優先事項:
確保您的HTTP服務器選擇不會不必要地妨礙性能。
避免使用輕鬆性能漏洞的HTTP服務器。
優先考慮使您能夠編寫和維護性能和可靠的處理程序的內容。
我相信木乃伊清除了所有三個優先事項:
木乃伊優先考慮接收和派遣傳入請求並發送響應的效率。這意味著諸如避免不必要的內存複製之類的事情,確保CPU將所有時間都花在您的處理程序中。
因為木乃伊使用多重IO就像異步一樣,木乃伊不容易受到諸如傳統上多線程服務器容易受到攻擊之類的攻擊。此外,雖然單個阻止或CPU重型操作可以使整個異步服務器停滯不前,但對於木乃伊來說,這並不是問題。
帶有木乃伊的請求處理程序只是純老式的內聯代碼。他們有一個直接的請求響應API。保持簡單非常適合維護,可靠性和性能。
基準測試是在帶有4核 / 8線程CPU的Ubuntu 22.04服務器上進行的。
測試/WRK_服務器的基準測試試圖模擬需要約10毫秒的請求。
所有基準測試通過:
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隨時運行Fuzzer。