nimble install mummy
API 참조
Mummy는 다중 스레드 HTTP 1.1이며 NIM에 완전히 작성된 WebSocket 서버입니다.
고대의 실의 길로의 복귀.
미라는 프로그래머의 행복을 손상시키지 않고 서버 하드웨어의 성능을 극대화하기 위해 특별히 작성되었습니다.
{.async.} 가격이없는 다중 소켓 io. 미라는 --threads:on 및 --mm:orc 또는 --mm:arc 필요로합니다.
미라 이름은 역사적인 이집트 물건을 말합니다.
Mummy는이 기본 모델로 작동합니다. 하나의 스레드에서 모든 소켓 IO를 처리하고 HTTP 요청 및 WebSocket 이벤트가 작업자 스레드 풀에 디스패치합니다. HTTP 핸들러는 아마도 스레드에 대해 전혀 생각할 필요조차 없습니다.
이 모델에는 많은 큰 이점이 있으며 지속적인 서버 코어 수 증가를 활용할 준비가되었습니다 (AMD는 96 Core 192 스레드 서버 CPU를 발표했습니다!).
더 이상 {.async.} , Future[] , await 등을 사용할 필요가 없습니다.
다중 비 블로킹 소켓 IO의 동일한 탁월한 처리량을 유지하십시오.
하나의 차단 또는 고가의 통화가 전체 서버를 중단한다는 걱정은 없습니다.
DNS 해상도 및 파일 읽기와 같은 놀라운 것들에 대한 비동기 블록은 모든 요청 처리를 중단합니다.
요청 처리기를 작성하는 것이 더 간단합니다. 스레드를 차단하는 것은 완전히 괜찮습니다! Postgres 쿼리를 만들어야합니까? 문제 없습니다. 결과를 기다리십시오.
더 간단한 코드와 이론적으로 빠르지 만 복잡하고 버그가 많은 코드를 작성하는 데 상당한 이점이 있습니다.
훨씬 간단한 디버깅. 비동기 스택 추적은 크고 혼란 스럽습니다.
더 쉬운 오류 처리는 평소처럼 try except . 미라 핸들러의가 잡히지 않은 예외도 서버 전체를 무너 뜨리지 않습니다.
미라는 스레딩 및 파견을 처리하여 핸들러가 스레드에 대해 전혀 생각할 필요가 없을 수 있습니다.
ARC / ORC 및 NIM 2.0에서 여러 코어와 NIM 팀의 놀라운 작업을 활용합니다.
Websockets는 훌륭하고 REST 및 다양한 RPC와 같은 전통적인 API 패러다임에 비해 상당한 이점을 가질 수 있습니다.
불행히도, 대부분의 HTTP 서버는 WebSockets가 존재하지 않는 척합니다.
이는 개발자가 추가 종속성, 납치 연결 등을 통해 지원을 해킹해야하며 모두 정말 큰 무언가를 더하는 경우가 거의 없습니다.
WebSockets가 상자 밖에서 예외적으로 잘 작동하지 않아야하는 이유는 없습니다. 개발자는 HTTP 서버에 대한 WebSocket 지원을 웨지 할 수있는 가능한 방법 중 많은 불확실성과 시간을 절약 할 수 있습니다.
모든 것은 트레이드 오프와 함께 제공됩니다. 미라는 뛰어난 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 서버는 벤치마킹 운동화와 비슷합니다.
확실히, 달리는 끔찍한 신발 (발 뒤꿈치, 막힘 등)이 있지만, 일단 합리적인 신발을 신으면 신발이 아니라 중요한 주자입니다.
이 비유에서, 러너는 핸들러가 실제로하는 일이며 신발은 HTTP 서버 선택입니다.
이를 염두에두고 세 가지 우선 순위를 제안합니다.
HTTP 서버 선택이 불필요하게 성능을 방해하지 않도록하십시오.
성능 취약점이 쉬운 HTTP 서버를 피하십시오.
수행자 및 신뢰할 수있는 핸들러를 작성하고 유지할 수있는 항목을 우선시하십시오.
나는 미라가 세 가지 우선 순위를 모두 해결한다고 생각합니다.
미라는 들어오는 요청을 받고 파견하고 나가는 응답을 보내는 효율성을 우선시합니다. 이는 불필요한 메모리 복사를 피하고 CPU가 핸들러에 모든 시간을 보내도록하는 것과 같은 것을 의미합니다.
미라는 비동기처럼 다중화 된 IO를 사용하기 때문에 미라는 전통적으로 다중 스레드 서버가 취약한 낮은 슬로우와 같은 공격에 취약하지 않습니다. 또한 단일 차단 또는 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 실행하여 언제든지 퍼즐을 실행할 수 있습니다.