مقدمة: لماذا Rust هي اللغة المثالية لـ Serverless
أصبحت بنية Serverless المعيار للتطبيقات السحابية الحديثة. ومع ذلك، غالبًا ما تعاني اللغات التقليدية (Python, Node.js) من بطء بدء التشغيل البارد واستهلاك عالٍ للذاكرة. Rust تحل هذه المشاكل: حيث يتم تشغيل ملفاتها الثنائية المترجمة في أجزاء من الثانية، ويكون استهلاك الذاكرة في حده الأدنى. في هذه المقالة، سنشرح كيفية إنشاء ونشر وتحسين وظائف AWS Lambda بلغة Rust - من إعداد البيئة إلى النشر في الإنتاج.
1. إعداد البيئة والأدوات
تثبيت Rust و Cargo Lambda
للعمل مع AWS Lambda بلغة Rust، ستحتاج إلى:
- Rust (التثبيت عبر
rustup) - Cargo Lambda - الأداة الرسمية للبناء والنشر
- AWS CLI مع بيانات الاعتماد (credentials) المهيأة
# تثبيت Rustcurl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# تثبيت Cargo Lambdacargo install cargo-lambda
# التحققcargo lambda --versionإنشاء مشروع جديد
يقوم Cargo Lambda تلقائيًا بإنشاء قالب مع دعم Lambda Runtime API:
cargo lambda new my-rust-lambdacd my-rust-lambdaيتضمن هيكل المشروع ملف Cargo.toml مع تبعيات lambda_runtime و serde، بالإضافة إلى ملف src/main.rs مع دالة معالج أساسية.
2. كتابة أول وظيفة Serverless بلغة Rust
الهيكل الأساسي للمعالج
لننظر إلى دالة Lambda بسيطة تستقبل JSON باسم وتُرجع تحية:
use lambda_runtime::{service_fn, LambdaEvent, Error};use serde::{Deserialize, Serialize};
#[derive(Deserialize)]struct Request { name: String,}
#[derive(Serialize)]struct Response { message: String, request_id: String,}
async fn handler(event: LambdaEvent<Request>) -> Result<Response, Error> { let req = event.payload; let resp = Response { message: format!("مرحبًا، {}! أنت على Rust!", req.name), request_id: event.context.request_id, }; Ok(resp)}
#[tokio::main]async fn main() -> Result<(), Error> { lambda_runtime::run(service_fn(handler)).await}النقاط الرئيسية:
service_fnيغلف الدالة غير المتزامنة في معالجLambdaEventيحتوي على الحمولة (payload) والسياق (request_id, deadline، إلخ)- التسلسل/إلغاء التسلسل عبر
serde
الاختبار المحلي
قبل النشر، اختبر الدالة محليًا:
cargo lambda watch# في محطة طرفية أخرى:cargo lambda invoke --data-ascii '{"name": "العالم"}'يجب أن تحصل على الرد: {"message":"مرحبًا، العالم! أنت على Rust!","request_id":"..."}
3. العمل مع خدمات AWS (S3, DynamoDB)
التكامل مع S3 عبر AWS SDK
أضف إلى Cargo.toml:
[dependencies]aws-sdk-s3 = "1.0"aws-config = "1.0"مثال لدالة تقرأ كائنًا من S3:
use aws_sdk_s3::Client;
async fn handler(event: LambdaEvent<Request>) -> Result<Response, Error> { let config = aws_config::load_from_env().await; let s3_client = Client::new(&config);
let bucket = "my-bucket"; let key = &event.payload.name;
let object = s3_client .get_object() .bucket(bucket) .key(key) .send() .await?;
let body = object.body.collect().await?; let content = String::from_utf8(body.to_vec())?;
Ok(Response { message: format!("محتوى الملف: {}", content), request_id: event.context.request_id, })}في