nimble install mummy
Ссылка на API
Mummy-это многопоточный HTTP 1.1 и сервер WebSocket, написанный полностью в NIM.
Возвращение к древним путям нитей.
Мама была написана специально, чтобы максимизировать производительность вашего серверного оборудования без ущерба для счастья программиста.
{.async.} Цена. Мама требует --threads:on и --mm:orc или --mm:arc .
Имя мумии относится к историческому Египетскому материалу.
Mummy работает с этой базовой моделью: обрабатывайте все в io в одном потоке и отправляйте входящие HTTP -запросы и события WebSocket в пул рабочих потоков. Ваши обработчики HTTP, вероятно, вообще не должны думать о потоках.
Эта модель имеет много больших преимуществ и готова воспользоваться преимуществами продолжения увеличения количества серверов (AMD только что объявил о 96 CORE -CORE 192 CPU SERVER!).
Больше не нужно использовать {.async.} , Future[] , await и т. Д. И справляться с функциями, имеющими цвета.
Поддерживайте такую же превосходную пропускную способность мультиплексированного неблокирующего в io.
Не беспокойтесь о том, что один блокирующий или дорогой вызов остановит весь ваш сервер.
Асинхронные блоки на удивительных вещах, таких как разрешение DNS и чтения файлов, которые будут задержать всю обработку запросов.
Проще написать обработчики запросов. Блокировать нить совершенно нормально! Нужно задать запрос Postgres? Нет проблем, просто подождите результатов.
Существует существенное преимущество в написании более простого кода против теоретически быстрого, но, возможно, запутанного и гликового кода.
Гораздо более простой отладка. Асинхронные трассировки стека огромны и сбивают с толку.
Простая обработка ошибок, просто try except того, как вы обычно делаете. Неучившиеся исключения в мамочных обработчиках также не сбивают весь ваш сервер.
Мама обрабатывает резьбу и отправку, поэтому вашим обработчикам, возможно, вообще не нужно думать о потоках.
Использует несколько ядер и удивительную работу команды NIM на ARC / ORC и NIM 2.0.
Веб -питания замечательны и могут иметь существенные преимущества по сравнению с более традиционными парадигмами API, такими как отдых и различные вкусы RPC.
К сожалению, большинство HTTP -серверов притворяются веб -кокеты.
Это означает, что разработчикам необходимо взламывать поддержку через дополнительные зависимости, угон соединения и т. Д., И все это редко превращается в нечто действительно великое.
Я не вижу причин, по которым веб -токеты не должны работать исключительно хорошо прямо из коробки, экономя разработчиков много неопределенности и изучение того, какой из возможных способов поддержки WebSocket на HTTP -сервере является «лучшим».
Все идет с компромиссами. Мамия сосредоточена на том, чтобы быть исключительным сервером API. Думайте Rest, JSON, RPC, WebSockets, HTML из шаблонов и т. Д.
Свойство, которое общее,-это все относительно воспоминания. Большинство вещей, и это здорово, но если вы специально собираетесь обслуживать множество очень больших файлов или ожидать больших загрузки файлов, Mummy, вероятно, не лучший выбор, если у вашего сервера нет оперативной памяти для обработки больших файлов.
Почему мама не подходит для больших файлов? Это связано с тем, что отправка мамы, полностью полученные в память, в рабочие потоки и отправляет ответы в памяти. Это отлично подходит для всего, кроме очень больших файлов.
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 может задержать весь асинхровый сервер, это не проблема для мамы.
Запросные обработчики с помощью мамы-это просто старый встроенный код NIM. У них есть прямая API-API запроса в ответ. Поддерживать простые вещи отлично подходит для технического обслуживания, надежности и производительности.
Бенчмаркинг был выполнен на сервере Ubuntu 22.04 с 4 -яй -процессором потока.
Серверы тестов/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
Фузор был запущен против чтения и анализа мамы, чтобы убедиться, что мама не сбои или иным образом плохо себя ведут по плохим данным из сокетов. Вы можете запустить Fuzzer в любое время, запустив nim c -r tests/fuzz_recv.nim .