nimble install mummy
การอ้างอิง API
Mummy เป็น HTTP 1.1 และเซิร์ฟเวอร์ WebSocket ที่เขียนด้วย Multi-Threaded ทั้งหมดใน NIM
กลับไปสู่วิธีการโบราณของเธรด
มัมมี่ได้รับการเขียนเป็นพิเศษเพื่อเพิ่มประสิทธิภาพของฮาร์ดแวร์เซิร์ฟเวอร์ของคุณโดยไม่ลดทอนความสุขของโปรแกรมเมอร์
{.async.} มัมมี่ต้องการ --threads:on และ --mm:orc หรือ --mm:arc
ชื่อมัมมี่หมายถึงสิ่งที่อียิปต์ประวัติศาสตร์
มัมมี่ทำงานด้วยโมเดลพื้นฐานนี้: จัดการซ็อกเก็ตทั้งหมด iO ในเธรดเดียวและส่งคำขอ HTTP ที่เข้ามาและเหตุการณ์ websocket ไปยังกลุ่มของเธรดคนงาน ตัวจัดการ HTTP ของคุณอาจไม่จำเป็นต้องคิดเกี่ยวกับเธรดเลย
รุ่นนี้มีประโยชน์มากมายและพร้อมที่จะใช้ประโยชน์จากการเพิ่มจำนวนเซิร์ฟเวอร์ที่เพิ่มขึ้นอย่างต่อเนื่อง (AMD เพิ่งประกาศ CPU เซิร์ฟเวอร์เธรด 96 Core 192!)
ไม่จำเป็นต้องใช้ {.async.} , Future[] , await ฯลฯ และจัดการกับฟังก์ชั่นที่มีสี
รักษาปริมาณงานที่ยอดเยี่ยมเหมือนกันของซ็อกเก็ต nonblocking แบบมัลติเพล็กซ์ IO
ไม่ต้องกังวลว่าการปิดกั้นหรือการโทรที่มีราคาแพงจะหยุดเซิร์ฟเวอร์ทั้งหมดของคุณ
Async บล็อกในสิ่งที่น่าประหลาดใจเช่นความละเอียด DNS และการอ่านไฟล์ซึ่งจะทำให้การจัดการคำขอทั้งหมด
ง่ายกว่าในการเขียนตัวจัดการคำขอ การปิดกั้นด้ายนั้นดีมาก! ต้องทำการสืบค้น Postgres หรือไม่? ไม่มีปัญหาเพียงแค่รอผลลัพธ์
มีข้อได้เปรียบอย่างมากในการเขียนโค้ดที่ง่ายขึ้นเทียบกับทางทฤษฎีอย่างรวดเร็ว แต่อาจซับซ้อนและโค้ดบั๊กกี้
การดีบักที่ง่ายกว่ามาก การร่องรอยของ Async Stack นั้นมีขนาดใหญ่และสับสน
การจัดการข้อผิดพลาดง่ายขึ้นเพียงแค่ try except เหมือนปกติ ข้อยกเว้นที่ไม่ได้รับการยกเว้นในตัวจัดการแม่ยังไม่ได้ทำให้เซิร์ฟเวอร์ทั้งหมดของคุณแย่ลง
มัมมี่จัดการกับเกลียวและส่งเพื่อให้ตัวจัดการของคุณอาจไม่จำเป็นต้องคิดเกี่ยวกับเธรดเลย
ใช้ประโยชน์จากหลายคอร์และผลงานที่น่าทึ่งของทีม NIM บน ARC / ORC และ NIM 2.0
WebSockets นั้นยอดเยี่ยมและสามารถมีข้อได้เปรียบที่สำคัญกว่ากระบวนทัศน์ API แบบดั้งเดิมมากขึ้นเช่นการพักผ่อนและรสชาติที่หลากหลายของ RPC
น่าเสียดายที่เซิร์ฟเวอร์ HTTP ส่วนใหญ่แกล้งทำเป็น WebSockets ไม่มีอยู่จริง
ซึ่งหมายความว่านักพัฒนาจำเป็นต้องแฮ็คการสนับสนุนผ่านการพึ่งพาเพิ่มเติมการเชื่อมต่อการเชื่อมต่อ ฯลฯ และทุกอย่างไม่ค่อยเพิ่มขึ้นในสิ่งที่ยอดเยี่ยมจริงๆ
ฉันไม่เห็นเหตุผลว่าทำไม WebSockets ไม่ควรทำงานได้ดีเป็นพิเศษนอกกรอบช่วยให้นักพัฒนามีความไม่แน่นอนและเวลาในการค้นคว้าวิธีใดที่เป็นไปได้ในการสนับสนุน WebSocket ในเซิร์ฟเวอร์ HTTP นั้นดีที่สุด
ทุกอย่างมาพร้อมกับการแลกเปลี่ยน มัมมี่มุ่งเน้นไปที่การเป็นเซิร์ฟเวอร์ API ที่ยอดเยี่ยม คิดว่า REST, 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 แบบมัลติเพล็กซ์เช่นเดียวกับ Async มัมมี่จึงไม่เสี่ยงต่อการโจมตีเช่นต่ำและช้าซึ่งเซิร์ฟเวอร์แบบมัลติเธรดแบบดั้งเดิมนั้นมีความเสี่ยง นอกจากนี้ในขณะที่การปิดกั้นหรือการทำงานหนักของ CPU สามารถหยุดเซิร์ฟเวอร์ Async ทั้งหมดได้ แต่นี่ไม่ใช่ปัญหาสำหรับ Mummy
คำขอตัวจัดการที่มีมัมมี่เป็นเพียงรหัสอินไลน์แบบธรรมดา พวกเขามี API คำขอที่ตรงไปตรงมา การรักษาสิ่งต่าง ๆ ให้เรียบง่ายเหมาะสำหรับการบำรุงรักษาความน่าเชื่อถือและประสิทธิภาพ
การเปรียบเทียบทำบนเซิร์ฟเวอร์ Ubuntu 22.04 ด้วย CPU เธรด 4 Core / 8
เซิร์ฟเวอร์การทดสอบ/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
ฟัสเซอร์ถูกเรียกใช้กับการอ่านซ็อกเก็ตของมัมมี่และการแยกวิเคราะห์รหัสเพื่อให้แน่ใจว่ามัมมี่จะไม่ผิดพลาดหรือทำงานผิดพลาดในข้อมูลที่ไม่ดีจากซ็อกเก็ต คุณสามารถเรียกใช้ Fuzzer ได้ตลอดเวลาโดยเรียกใช้ nim c -r tests/fuzz_recv.nim