nimble install mummy
مرجع API
Mummy هو HTTP 1.1 متعدد الخيوط وخادم WebSocket مكتوب بالكامل في NIM.
العودة إلى الطرق القديمة للخيوط.
تمت كتابة المومياء خصيصًا لزيادة أداء أجهزة الخادم الخاصة بك دون المساس بسعادة المبرمج.
{.async.} . يتطلب المومياء --threads:on و --mm:orc أو --mm:arc .
يشير اسم المومياء إلى أشياء مصر التاريخية.
تعمل Mummy مع هذا النموذج الأساسي: التعامل مع جميع المقبس IO على مؤشر ترابط واحد وإرسال طلبات HTTP الواردة وأحداث WebSocket إلى مجموعة من مؤشرات الترابط العامل. ربما لن يحتاج معالجات HTTP الخاصة بك إلى التفكير في المواضيع على الإطلاق.
يحتوي هذا النموذج على العديد من الفوائد الرائعة وهو جاهز للاستفادة من زيادة عدد CORE CORP في الخادم المستمر (أعلنت AMD للتو عن 96 CORE 192 Thread Server CPU!).
لا مزيد من الحاجة إلى استخدام {.async.} ، Future[] ، await الخ والتعامل مع الوظائف ذات الألوان.
الحفاظ على نفس الإنتاجية الممتازة من المقبس غير المحظور IO.
لا يوجد قلق من أن أحد المكالمة أو المكالمة باهظة الثمن سيوقف الخادم بأكمله.
تقوم Async بتكتلات أشياء مفاجئة مثل دقة DNS وقراءات الملف والتي ستوقف كل طلبات الطلب.
أبسط لكتابة معالجات الطلب. حظر الخيط جيد تماما! هل تحتاج إلى إجراء استعلام Postgres؟ لا مشكلة ، فقط انتظر النتائج.
هناك ميزة كبيرة لكتابة رمز أبسط مقابل رمز سريع من الناحية النظرية ولكن ربما يكون معقدًا وعلوم العربات التي تجرها الدواب.
تصحيح أخطاء أبسط بكثير. آثار مكدس Async ضخمة ومربكة.
أسهل معالجة الأخطاء ، فقط try except كما تفعل عادة. الاستثناءات غير المطلقة في معالجات المومياء لا تخفض الخادم الخاص بك بالكامل.
يعالج المومياء الخيوط والإرسال حتى لا يحتاج معالجاتك إلى التفكير في المواضيع على الإطلاق.
يستفيد من النوى المتعددة والعمل المذهل لفريق NIM على ARC / ORC و NIM 2.0.
WebSockets رائعة ويمكن أن يكون لها مزايا كبيرة على أكثر نماذج API التقليدية مثل الراحة ونكهات مختلفة من RPC.
لسوء الحظ ، فإن معظم خوادم HTTP تتظاهر بأن websockets غير موجودة.
هذا يعني أن المطورين بحاجة إلى اختراق الدعم من خلال تبعيات إضافية ، واختطاف الاتصالات ، إلخ ، ونادراً ما يضيف كل شيء إلى شيء رائع حقًا.
لا أرى أي سبب يمنع WebSockets بشكل جيد بشكل استثنائي خارج الصندوق ، مما يوفر للمطورين الكثير من عدم اليقين والوقت في البحث عن أي من الطرق الممكنة لإسقاط دعم WebSocket في خادم HTTP هو "الأفضل".
كل شيء يأتي مع المقايضات. تركز المومياء على أن تكون خادم API استثنائي. فكر في REST ، JSON ، RPC ، WebSockets ، HTML من القوالب إلخ.
الملكية هذه المشتركة المشتركة هي أنها جميعها ضوء الذاكرة نسبيا. معظم الأشياء ، وهو أمر رائع ، ولكن إذا كنت ستقدم على وجه التحديد الكثير من الملفات الكبيرة جدًا أو تتوقع تحميلات ملفات كبيرة ، فربما لا تكون المومياء هي الخيار الأفضل ما لم يكن لدى الخادم ذاكرة الوصول العشوائي للتعامل مع الملفات الكبيرة.
لماذا المومياء ليست كبيرة للملفات الكبيرة؟ وذلك لأن عمليات إرسال المومياء تلقيت طلبات في الذاكرة بالكامل إلى موضوعات العمال وترسل استجابات في الذاكرة. هذا رائع لكل شيء باستثناء الملفات الكبيرة جدًا.
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 التي لديها ثغرات الأداء السهلة.
إعطاء الأولوية لما سيمكنك من كتابة وصيانة معالجات الأداء والموثوقة.
أعتقد أن مومياء توضح كل الأولويات الثلاث:
يعطي مومياء الأولوية الكفاءة في تلقي الطلبات الواردة وإرسالها وإرسال الردود الصادرة. هذا يعني أشياء مثل تجنب نسخ الذاكرة غير الضرورية ، مما يضمن أن وحدة المعالجة المركزية تقضي كل وقتها في معالجاتك.
نظرًا لأن المومياء تستخدم IO المضاعفة تمامًا مثل Async ، فإن المومياء ليست عرضة للهجمات مثل منخفضة وقناعة الخوادم المتعددة التقليدية المعرضة لها. بالإضافة إلى ذلك ، في حين أن عملية حظر واحدة أو وحدة المعالجة المركزية الثقيلة يمكن أن تعطل خادم غير متزامن كامل ، فإن هذه ليست مشكلة بالنسبة للمومياء.
طلب معالجات المومياء هي مجرد رمز NIM المضمن. لديهم واجهة برمجة تطبيقات طلب مباشر في الاستجابة. الحفاظ على الأمور بسيطة أمر رائع للصيانة والموثوقية والأداء.
تم إجراء القياس على خادم Ubuntu 22.04 مع وحدة المعالجة المركزية 4 Core / 8.
خوادم الاختبارات/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 ضد قراءة مقبس المومياء وعمليات التحليل لضمان عدم تعطل المومياء أو يسيئون التصرف على البيانات السيئة من مآخذ التوصيل. يمكنك تشغيل Fuzzer في أي وقت عن طريق تشغيل nim c -r tests/fuzz_recv.nim .