Feather, một framework web nhẹ cho Rust lấy cảm hứng từ Express.js, đã gây ra nhiều tranh luận trong cộng đồng lập trình viên về các lựa chọn thiết kế và đặc điểm hiệu suất của nó. Mặc dù framework này hướng đến việc cung cấp kiến trúc đơn giản, ưu tiên middleware với trọng tâm là trải nghiệm của nhà phát triển, các thành viên trong cộng đồng đã xác định một số hạn chế cơ bản có thể ảnh hưởng đến tính thực tiễn của nó.
Kiến trúc đơn luồng gây lo ngại
Chỉ trích nổi bật nhất xoay quanh tính chất đơn luồng của Feather. Phân tích kỹ thuật từ các thành viên cộng đồng cho thấy framework này xử lý các yêu cầu tuần tự thay vì đồng thời, tạo ra một nút thắt cổ chai hạn chế hiệu suất khi có nhiều tải. Một lập trình viên đã chứng minh hạn chế này bằng một bài kiểm tra đơn giản cho thấy khi hai yêu cầu đồng thời được gửi đến máy chủ có thời gian xử lý 2 giây, yêu cầu thứ hai mất 4 giây để hoàn thành vì nó phải đợi yêu cầu đầu tiên kết thúc.
Việc một yêu cầu có thể dễ dàng nhận được tham chiếu có thể thay đổi (mutable reference) đến một ngữ cảnh được chia sẻ khiến tôi cảm thấy đáng ngờ, vì vậy tôi đã chạy một bài kiểm tra nhanh và có vẻ như toàn bộ máy chủ chỉ chạy đơn luồng... khi trình xử lý yêu cầu mất 2 giây, và bạn gửi hai yêu cầu cùng lúc, một trong số đó trả về sau 2 giây, nhưng yêu cầu còn lại mất 4 giây, vì nó phải đợi yêu cầu đầu tiên hoàn thành trước khi có thể bắt đầu.
Lựa chọn thiết kế này dường như xuất phát từ cách tiếp cận quản lý trạng thái của Feather, cho phép truy cập trực tiếp có thể thay đổi vào ngữ cảnh được chia sẻ mà không cần các wrapper an toàn cho luồng như Arc<Mutex>. Mặc dù điều này đơn giản hóa API, nó tạo ra một hạn chế cơ bản về khả năng xử lý đồng thời, trái ngược với danh tiếng của Rust về lập trình đồng thời an toàn.
Những hạn chế chính của Framework Feather:
- Xử lý yêu cầu đơn luồng
- Chặn đầu hàng (head-of-line blocking) cho các yêu cầu đồng thời
- Yêu cầu mẫu MiddlewareResult::Next trong các bộ xử lý tuyến
- Thiếu quản lý trạng thái an toàn đa luồng (không có mẫu Arc<Mutex<T>>)
Các Framework Web Rust thay thế:
- Rocket: Đa luồng với API xử lý tuyến đồng bộ
- Axum: Dựa trên bất đồng bộ nhưng hiệu suất cao hơn
Tính năng Framework:
- Kiến trúc ưu tiên middleware
- API Context để quản lý trạng thái
- Xác thực JWT tích hợp sẵn (tính năng tùy chọn)
- Không yêu cầu mã bất đồng bộ
Đánh đổi giữa trải nghiệm nhà phát triển và hiệu suất
Feather tự quảng bá là ưu tiên trải nghiệm nhà phát triển (DX-first), đặt trải nghiệm nhà phát triển lên trên các yếu tố khác. Framework này cố gắng tạo sự khác biệt bằng cách tránh mô hình lập trình bất đồng bộ của Rust, vốn có thể gây khó khăn cho người mới. Một số người bình luận thừa nhận rằng lập trình bất đồng bộ trong Rust tạo ra gánh nặng tinh thần đáng kể, đặc biệt là đối với các nhà phát triển đến từ các ngôn ngữ như Python, C#, Java hoặc C++.
Tuy nhiên, các thành viên khác trong cộng đồng đặt câu hỏi liệu cách tiếp cận của Feather có thực sự mang lại trải nghiệm nhà phát triển tốt hơn hay không, lưu ý rằng mã khuôn mẫu bắt buộc (như giá trị trả về MiddlewareResult::Next bắt buộc) tạo ra sự lặp lại không cần thiết. Một số người chỉ ra các framework thay thế như Rocket, có thể cung cấp API đồng bộ cho các trình xử lý định tuyến trong khi vẫn duy trì hiệu suất đa luồng bên dưới.
Trường hợp sử dụng và các giải pháp thay thế
Cuộc thảo luận nhấn mạnh rằng cách tiếp cận của Feather có thể phù hợp cho các dự án giáo dục nhỏ hoặc các ứng dụng có yêu cầu hiệu suất tối thiểu. Tuy nhiên, đối với các khối lượng công việc sản xuất, hầu hết các nhà phát triển ưa chuộng các giải pháp thay thế đã được thiết lập có sự cân bằng tốt hơn giữa tính dễ sử dụng và hiệu suất.
So sánh hiệu suất cũng được thảo luận, với các tham chiếu đến các bài kiểm tra TechEmpower cho thấy các framework web Rust được thiết kế tốt thường vượt trội hơn so với các framework viết bằng Go, Node.js hoặc Python. Lợi thế hiệu suất này là một trong những lý do chính khiến các nhà phát triển xem xét sử dụng Rust cho phát triển máy chủ web, làm cho hạn chế đơn luồng của Feather trở nên đặc biệt có vấn đề.
Tóm lại, mặc dù Feather cố gắng mang lại sự đơn giản kiểu Express.js cho phát triển web bằng Rust, các lựa chọn kiến trúc của nó tạo ra những hạn chế hiệu suất đáng kể. Đối với các nhà phát triển muốn tận dụng lợi ích hiệu suất của Rust trong các ứng dụng web, các giải pháp thay thế xử lý đồng thời tốt hơn trong khi vẫn cung cấp trải nghiệm nhà phát triển tốt có thể là lựa chọn phù hợp hơn.
Tham khảo: Feather