ميكروسيرفيسات بلغة Rust: بنية متقدمة وممارسات تطبيقية

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

ميكروسيرفيسات بلغة Rust: بنية متقدمة وممارسات تطبيقية



تحتل Rust مكانة قوية في مجال الميكروسيرفيسات عالية التحميل، حيث تكون الأداء وأمان الذاكرة واستهلاك الموارد المتوقع أمورًا حاسمة. على المستوى المتقدم، يتطلب التطوير بلغة Rust ليس فقط معرفة القواعد النحوية، بل أيضًا فهمًا عميقًا لبيئات التشغيل غير المتزامنة، والملكية (ownership) في الأنظمة الموزعة، وأنماط تحمل الأخطاء. في هذه المقالة، سنستعرض القرارات المعمارية والتقنيات العملية للميكروسيرفيسات الجاهزة للإنتاج بلغة Rust.



1. البنية المعتمدة على Actix Web و Tokio



يحدد اختيار الإطار نموذج التوازي. Actix Web (المبني على Tokio) هو المعيار الفعلي لميكروسيرفيسات HTTP. النهج المتقدم لا يقتصر على التوجيه فحسب، بل يشمل الفصل المناسب إلى طبقات: النقل، منطق الأعمال، الوصول إلى البيانات.



مثال على هيكل ميكروسيرفيس أساسي مع حقن التبعيات (DI) عبر Arc:



use actix_web::{web, App, HttpServer, HttpResponse, middleware};use std::sync::Arc;

// طبقة البياناتstruct DbPool { // اتصال حقيقي بقاعدة البيانات}

// طبقة الخدمةstruct UserService { pool: Arc<DbPool>,}

impl UserService { async fn get_user(&self, id: u32) -> Result<String, actix_web::Error> { // منطق الأعمال Ok(format!("User {}", id)) }}

// طبقة النقلasync fn handler_get_user( path: web::Path<u32>, service: web::Data<Arc<UserService>>,) -> HttpResponse { match service.get_user(path.into_inner()).await { Ok(data) => HttpResponse::Ok().json(data), Err(e) => HttpResponse::InternalServerError().body(e.to_string()), }}

#[actix_web::main]async fn main() -> std::io::Result<()> { let db_pool = Arc::new(DbPool {}); let user_service = Arc::new(UserService { pool: db_pool });

HttpServer::new(move || { App::new() .app_data(web::Data::new(user_service.clone())) .route("/user/{id}", web::get().to(handler_get_user)) .wrap(middleware::Logger::default()) }) .bind("127.0.0.1:8080")? .run() .await}


نقاط رئيسية للإنتاج:

  • Middleware: استخدم middleware مخصصة للتتبع (OpenTelemetry) وتحديد المعدل.
  • Graceful shutdown: قم بتنفيذ معالجة إشارات SIGTERM/SIGINT عبر tokio::signal.
  • Configuration: أخرج جميع المعاملات إلى متغيرات البيئة أو ملفات التكوين (مكتبة config).


2. التواصل بين الخدمات: gRPC مع Tonic



للتواصل عالي الأداء بين الميكروسيرفيسات، يُفضل استخدام gRPC. توفر حزمة Rust Tonic قنوات آمنة ومكتوبة بقواعد صارمة مبنية على Tokio و Prost (مترجم protobuf).



مثال على ملف proto وخادم:



// proto/user.protosyntax = "proto3";package user;

service UserService { rpc GetUser (UserRequest) returns (UserResponse);}

message UserRequest { uint32 id = 1;}

message UserResponse { string name = 1; string email = 2;}


// خادم على Tonicuse tonic::{transport::Server, Request, Response, Status};use user::user_service_server::{UserService, UserServiceServer};use user::{UserRequest, UserResponse};

pub mod user { tonic::include_proto!("user");}

#[derive(Default)]pub struct MyUserService;

#[tonic::async_trait]impl UserService for MyUserService { async fn get_user( &self, request: Request<UserRequest>, ) -> Result<Response<UserResponse>, Status> { let id = request.into_inner().id; // هنا يتم الوصو

المدونات

توصيات الكتب