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。