เมื่อตอนแรกที่ผมตัดสินใจย้ายสแต็กแบ็กเอนด์ของเราจาก Python ไปเป็น Rust มันไม่ได้เป็นเพียงแค่เรื่องของความอยากรู้ – แต่เกิดจากปัญหาจริงๆ ที่เกี่ยวกับประสิทธิภาพ ค่าใช้จ่ายในการดีพลอย และความเชื่อถือได้ภายใต้โหลดงาน ระบบนิเวศเว็บของ Python – โดยเฉพาะ FastAPI – นั้นสนุกในการทำงานด้วยเพื่อประสิทธิภาพการทำงานและการพัฒนาที่รวดเร็ว แต่เมื่อทราฟฟิกของเราเติบโตขึ้นและเพดานประสิทธิภาพชัดเจนขึ้น ผมอยากสำรวจว่า Rust จะเสนออะไรได้บ้าง
ในบทความนี้ผมจะแบ่งปันสิ่งที่ผมได้เรียนรู้ระหว่างทาง: ข้อดี ปัญหาต่างๆ และจุดที่แต่ละระบบนิเวศยังคงโดดเด่น

การเปรียบเทียบประสิทธิภาพ: Rust (Actix-Web) เทียบกับ Python (FastAPI)
ปริมาณงานดิบและความหน่วง
หนึ่งในสิ่งแรกที่ทำให้ผมตระหนักเมื่อทำการเบนช์มาร์กคือความแตกต่างของโปรไฟล์ประสิทธิภาพระหว่างเฟรมเวิร์กเว็บของ Rust และ Python
จากการเบนช์มาร์กอิสระหลายรายการ Actix-Web ของ Rust มีประสิทธิภาพเหนือกว่า FastAPI อย่างสม่ำเสมอในเรื่องคำขอต่อวินาทีและประสิทธิภาพหน่วยความจำ ในการเบนช์มาร์กของชุมชนหนึ่ง Actix-Web จัดการคำขอได้มากกว่าหลายพันคำขอต่อวินาทีด้วยความหน่วงที่ต่ำกว่าและการใช้หน่วยความจำที่ต่ำกว่ามากเมื่อเทียบกับ FastAPI
นี่สอดคล้องกับการสังเกตที่กว้างขึ้นว่า การนามธรรมที่ไม่มีต้นทุน ของ Rust และการขาดตัวรวบรวมขยะ ทำให้มันมีประสิทธิภาพเป็นพิเศษเมื่อให้บริการ HTTP ในระดับใหญ่
ผลกระทบในโลกจริง
จากประสบการณ์ของผม สิ่งนี้แปลเป็น:
- ปริมาณงานที่ยั่งยืนสูงกว่ามากในการทดสอบความเครียด
- ความแปรปรวนน้อยลงภายใต้โหลด
- การใช้หน่วยความจำในสภาวะไม่ทำงานที่ต่ำกว่าเมื่อเทียบกับโปรเซส Python
อย่างไรก็ตาม การเบนช์มาร์กบอกเพียงบางส่วนของเรื่องราว: ปัญหาคอขวดในโลกจริงมักจะถูกจำกัดโดยฐานข้อมูลหรือเครือข่าย สำหรับแอปพลิเคชันหลายตัว ประสิทธิภาพของ FastAPI นั้นเพียงพอ และการปรับแต่งการเข้าถึงฐานข้อมูลหรือการแคชให้ผลตอบแทนมากกว่าการเลือกภาษาเพียงอย่างเดียว
ความแตกต่างของ ORM: Diesel เทียบกับ SQLAlchemy
การเปลี่ยนกระบวนทัศน์ ORM เป็นหนึ่งในส่วนที่แตกต่างมากที่สุดในทางวัฒนธรรมของการย้ายข้อมูล
ระบบการย้ายข้อมูล
ใน Python เราใช้ SQLAlchemy กับการย้ายข้อมูล Alembic – วิธีการที่เปรียบเทียบโมเดลของคุณและสร้างสคริปต์การย้ายข้อมูลโดยอัตโนมัติ
ใน Rust เราย้ายไปใช้ Diesel ซึ่งมีจุดยืนที่แตกต่างกันมาก:
- การย้ายข้อมูลถูกเขียนด้วยมือเป็นไฟล์ SQL ที่ชัดเจน
- ไม่มีเครื่องมือเปรียบเทียบอัตโนมัติ
- คุณได้รับการควบคุมมากขึ้น – และความรับผิดชอบมากขึ้น
สิ่งนี้ทำให้หงุดหงิดในตอนแรก แต่ระเบียบวินัยในการเขียนการย้ายข้อมูลด้วยมือนำไปสู่การตรวจสอบที่ชัดเจนขึ้นและความประหลาดใจน้อยลงในโปรดักชัน
ความปลอดภัยของประเภทและการรับประกันเวลาคอมไพล์
นี่คือจุดที่ Diesel เปลี่ยนแปลงวิธีคิดของผมเกี่ยวกับโค้ดฐานข้อมูลจริงๆ: ความปลอดภัยของประเภทในเวลาคอมไพล์
Diesel สร้างประเภท Rust ตามสคีมาของคุณ ดังนั้นชื่อคอลัมน์ที่ไม่ตรงกันหรือโครงสร้างคิวรีที่ไม่ถูกต้องก็ไม่สามารถคอมไพล์ได้ แนวคิดต่างๆ เช่น check_for_backend และการต้องการการประกาศ table_name ที่ชัดเจน หมายความว่าบั๊กทั่วไปทั้งหมดหายไปก่อนที่คุณจะรันคิวรี
เมื่อเปรียบเทียบ SQLAlchemy จับข้อผิดพลาดหลายอย่างได้เฉพาะตอนรันไทม์เท่านั้น แม้ว่าจะเพิ่มความยืดหยุ่น แต่ก็หมายความว่าต้องพึ่งพาการทดสอบมากขึ้นเพื่อความถูกต้อง
การสร้างและดำเนินการคิวรี
ตัวสร้างคิวรีของ Diesel ใช้ระบบประเภทของ Rust และใช้โค้ดหลายบรรทัดมากกว่าเมื่อเทียบกับสไตล์การแสดงออกแบบไดนามิกของ SQLAlchemy – แต่การแลกเปลี่ยนคือคอมไพเลอร์พิสูจน์สิ่งต่างๆ ให้คุณมากมาย
หลังจากช่วงการปรับตัว ผมเริ่มชื่นชมว่าความชัดเจนของ Rust ช่วยอย่างไรเมื่อต้องนำทางตรรกะคิวรีที่ซับซ้อนระหว่างการรีแฟคเตอร์
การสนับสนุนการสร้าง OpenAPI อัตโนมัติ
หนึ่งในพื้นที่ที่ Python ยังคงรู้สึกนำหน้าแบบ out-of-the-box คือการสร้างสคีมา API
FastAPI สร้างเอกสาร OpenAPI โดยอัตโนมัติและมาพร้อมกับ UI เบราว์เซอร์เช่น ReDoc และ Swagger UI ที่ /docs และ /redoc ทำให้ง่ายมากสำหรับลูกค้าและเพื่อนร่วมทีมในการทำความเข้าใจและสำรวจ API ของคุณ
ระบบนิเวศของ Rust กำลังพัฒนาในที่นี่ เครื่องมือเช่น utoipa สามารถสร้างข้อมูลจำเพาะ OpenAPI สำหรับ Actix-Web แต่พวกเขารู้สึกด้วยตนเองและแยกส่วนมากกว่าเมื่อเทียบกับประสบการณ์ที่ไร้รอยต่อของ FastAPI มี crate ชุมชนเพื่อให้บริการ Swagger หรือ Redoc UI ด้วย แต่พวกเขาต้องการการตั้งค่าและคำอธิบายเพิ่มเติม
ผมคาดว่าช่องว่างนี้จะแคบลงต่อไป – มีความพยายามที่ดำเนินการอยู่ในชุมชน Rust เพื่อนำประสบการณ์เอกสาร API ที่ราบรื่นกว่าซึ่งแข่งขันกับ FastAPI
ขนาดการดีพลอย: การคอมไพล์เทียบกับการพึ่งพา
เวลาคอมไพล์ของ Rust
การคอมไพล์ของ Rust มีชื่อเสียงว่าช้ากว่าภาษาที่ตีความได้ ระหว่างการพัฒนา การรีบิลด์ – โดยเฉพาะกับ crate ขนาดใหญ่ – อาจรู้สึกเชื่องช้าเมื่อเทียบกับการรันสคริปต์ Python ใหม่
แต่ต้นทุนนี้คือเวลาพัฒนา ไม่ใช่เวลาโปรดักชัน เมื่อคอมไพล์แล้ว ไบนารี Rust จะ:
- คอมไพล์เต็มรูปแบบล่วงหน้า
- มีทุกอย่างในตัว (ไม่มี virtualenv โดยปกติไม่มีการพึ่งพาแบบไดนามิก)
- รอยเท้าที่เล็กมากในอิมเมจคอนเทนเนอร์
นั่นทำให้การดีพลอยง่ายและคาดเดาได้มากขึ้น
รอยเท้าการพึ่งพาของ Python
แอป Python มักนำกราฟการพึ่งพาขนาดใหญ่มาด้วย: FastAPI เอง uvicorn, pydantic (ตอนนี้เร็วขึ้นมากขอบคุณภายใน Rust) ไดรเวอร์ฐานข้อมูล ฯลฯ
สิ่งนี้เพิ่ม:
- ขนาดคอนเทนเนอร์
- ความซับซ้อนในการบิลด์
- พื้นที่สำหรับความขัดแย้งของการพึ่งพา
Cargo ของ Rust สร้างไบนารีหนึ่งตัวที่รวมทุกอย่างไว้ (โดยปกติ) ซึ่งทำให้เรื่องการดีพลอยง่ายขึ้นอย่างมาก
ความสามารถในการบำรุงรักษา
นี่คือพื้นที่ที่อาจมีการเติบโตส่วนบุคคลมากที่สุด
Rust ผลักดันคุณไปสู่ขอบเขตความเป็นเจ้าของที่ชัดเจน การจัดการข้อผิดพลาดที่ชัดเจน และการออกแบบที่ระมัดระวัง เมื่อคุณซึมซับข้อผิดพลาดการคอมไพล์ของ Rust แล้ว คอมไพเลอร์เองจะกลายเป็นราวกั้นที่แข็งแกร่งต่อการถดถอย
ในทางตรงกันข้าม ความเป็นไดนามิกของ Python สามารถรู้สึกง่ายดายระหว่างการพัฒนาในช่วงแรก – แต่ความยืดหยุ่นเดียวกันนั้นบางครั้งนำไปสู่บั๊กที่วินิจฉัยได้ยากกว่าในโปรดักชันเว้นแต่จะได้รับการสนับสนุนจากชุดทดสอบที่แข็งแกร่ง
โค้ดเบสของเรา Rust รู้สึกยืดหยุ่นมากขึ้นระหว่างการรีแฟคเตอร์ขนาดใหญ่ ส่วนใหญ่เป็นผลมาจากความเข้มงวดของคอมไพเลอร์
เอกสารและประสบการณ์นักพัฒนา
เอกสารอัตโนมัติของ FastAPI
การรวม FastAPI กับ OpenAPI พร้อมกับ ReDoc และ Swagger UI ทำให้การเข้าร่วมของนักพัฒนาใหม่ง่ายมาก มันเป็นหนึ่งในชิงชัยที่ใหญ่ที่สุดที่ผมได้เห็นในประสิทธิภาพการทำงานของทีม
การสร้างเอกสารของ Rust
เครื่องมือเอกสารในตัวของ Rust (cargo doc) นั้นยอดเยี่ยมสำหรับเอกสารระดับโค้ด มันสนับสนุนการเขียนเอกสารข้างๆ โค้ดของคุณ และ Rustdoc สร้างเอกสาร HTML ที่สะอาดและค้นหาได้
แม้ว่าจะไม่ได้แทนที่เอนด์พอยต์ /docs ที่ดีแบบ out of the box แต่ก็ปรับปรุงคุณภาพและการค้นพบเอกสารที่เน้นโค้ดได้อย่างมาก
บทสรุป
การเปลี่ยนจาก Python ไปเป็น Rust สำหรับการพัฒนาแบ็กเอนด์ไม่ได้เกี่ยวกับการชอบภาษาหนึ่งมากกว่าอีกภาษาหนึ่ง – มันเกี่ยวกับการจัดตำแหน่งให้สอดคล้องกับลำดับความสำคัญของโครงการของเรา
- Rust ให้ประสิทธิภาพ ความสามารถในการคาดเดา และความเชื่อถือได้ในทราฟฟิกโปรดักชัน
- Python ให้ความเร็วในการพัฒนาและการยศาสตร์ระดับโลก
ทั้งสองระบบนิเวศมีความแข็งแกร่ง สิ่งที่เปลี่ยนแปลงกับ Rust คือปัญหาหลายอย่างที่จะปรากฏเฉพาะตอนรันไทม์ใน Python จะถูกจับได้ตอนคอมไพล์ใน Rust แทน ลดความประหลาดใจและการหยุดทำงาน
การเลือก Rust หมายถึงการลงทุนในเส้นโค้งการเรียนรู้ – แต่สำหรับทีมที่ประสิทธิภาพและความถูกต้องสำคัญที่สุด การแลกเปลี่ยนนั้นคุ้มค่าสำหรับเรา
หมายเหตุผู้เขียน
บทความนี้เขียนโดยผู้สร้าง Hytale Multiplayer เว็บไซต์ที่เน้นบทความทางเทคนิคและการเจาะลึกเกม Hytale รวมถึงการพัฒนาเซิร์ฟเวอร์ เครื่องมือ และการเปรียบเทียบกับระบบนิเวศที่เกี่ยวข้องเช่น Minecraft หากคุณสนุกกับเนื้อหาที่เน้นวิศวกรรมแบบปฏิบัติ อย่าลังเลที่จะสำรวจบทความเพิ่มเติมที่นั่น








