📌 الدليل الرئيسي: WebAssembly في الإنتاج
Cloudflare Workers ينشر الكود في أكثر من 330 مدينة في أقلّ من 30 ثانية بعد الـ push. للأحمال الحرجة CPU — parsing، crypto، تعديل صور — تنفيذ Rust مُجَمَّع إلى WebAssembly أسرع من Worker JavaScript ويُقلِع في عشرات المايكروثوانٍ. الـ crate worker (workers-rs 0.8.3) يُغَلِّف واجهة Workers بـ Rust اصطلاحي، وسلسلة worker-build + wrangler تُؤَتمت الترجمة، الـ bundling، والنشر.
يبدأ هذا الدليل من حاسوب فارغ لنشر خدمة Rust كاملة على edge: routes، KV، D1، R2، مراقبة. الأوامر نُفِّذت مع Rust 1.83، wrangler 4.x، worker-build 0.7.4، وcrate worker 0.8.3.
الخطوة 1 — تثبيت الأدوات المطلوبة
rustup target add wasm32-unknown-unknown
cargo install cargo-generate
npm create cloudflare@latest -- --type=hello-worker --framework=rust
البديل اليدوي:
cargo generate cloudflare/workers-rs
القالب يُفَعِّل panic=unwind افتراضيًّا. منذ workers-rs 0.6، runtime Workers يستعمل WebAssembly Exception Handling لاستعادة panic Rust دون قتل الـ isolate: panic recovery، يجب إبقاؤه نشطًا في الإنتاج.
الخطوة 2 — تشريح المشروع المُوَلَّد
[package]
name = "edge-demo"
version = "0.1.0"
edition = "2021"
[lib]
crate-type = ["cdylib"]
[dependencies]
worker = { version = "0.8", features = ["http", "d1"] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
console_error_panic_hook = "0.1"
[profile.release]
opt-level = "s"
lto = true
name = "edge-demo"
main = "build/worker/shim.mjs"
compatibility_date = "2026-05-01"
compatibility_flags = ["nodejs_compat_v2"]
[build]
command = "cargo install --quiet worker-build && worker-build --release"
الـ compatibility_date يُجَمِّد السلوك حتى لو غيّر Cloudflare الـ API. worker-build --release يستدعي cargo build، يُنَفِّذ wasm-bindgen، ويُوَلِّد shim JavaScript.
الخطوة 3 — كتابة أوّل handler مع routing
use worker::*;
#[event(fetch)]
pub async fn main(req: Request, env: Env, _ctx: Context) -> Result {
console_error_panic_hook::set_once();
let router = Router::new();
router
.get("/", |_, _| Response::ok("Hello edge!"))
.get_async("/version", |_, _| async move {
Response::from_json(&serde_json::json!({
"runtime": "cloudflare-workers",
"engine": "v8-wasm",
"build_at": env!("CARGO_PKG_VERSION"),
}))
})
.run(req, env)
.await
}
الماكرو #[event(fetch)] يَسِم نقطة الدخول المُستدعاة لكلّ طلب HTTP. console_error_panic_hook::set_once() يُوَجِّه panics Rust نحو console.error، ممّا يجعلها مقروءة في سجلّات Wrangler.
الخطوة 4 — الاختبار محلّيًّا بـ wrangler dev
npx wrangler dev
الخرج يعرض endpoint http://localhost:8787. هذا الأمر يُشَغِّل proxy محلّيًّا يُحَمِّل الـ Worker في instance من محرّك Workers (workerd)، نفس runtime الإنتاج. لا محاكاة تقريبية.
curl -s http://localhost:8787/
curl -s http://localhost:8787/version | jq
إن لم يُجَمَّع الـ binary، wrangler dev يُبَلِّغ خطأ Rust. إعادة البناء تلقائية: مع كلّ حفظ ملفّ، يُستدعى worker-build ويُعاد تحميل isolate. الزمن الدوري نمطيًّا 2-4 ثوانٍ.
الخطوة 5 — النشر في الإنتاج
npx wrangler login
npx wrangler deploy
الخرج يُعلن « Total Upload »، « Worker Startup Time »، وURL النهائي edge-demo.<your-subdomain>.workers.dev. startup time هو المؤشّر المفتاح: لـ Worker Rust مُحَسَّن، استهدف تحت 20 ms. فوق ذلك، Cloudflare قد يرفض النشر أو يُطَبِّق حدودًا. حَسِّن الـ binary (opt-level = "s"، تبعيّات أدنى).
الخطوة 6 — ربط KV للاستمرارية مفتاح/قيمة
npx wrangler kv namespace create CACHE
# الأمر يُرجع id، الصقه في wrangler.toml
[[kv_namespaces]]
binding = "CACHE"
id = "<id retourné par la commande>"
router.get_async("/cache/:key", |_, ctx| async move {
let key = ctx.param("key").unwrap_or(&"".to_string()).clone();
let kv = ctx.kv("CACHE")?;
match kv.get(&key).text().await? {
Some(v) => Response::ok(v),
None => Response::error("not found", 404),
}
})
قراءات KV في edge تدور حول median 12 ms، مع أزمنة دون مللي ثانية على المفاتيح المقروءة كثيرًا. الكتابات متّسقة في النهاية، بحدّ أعلى موثَّق 60 ثانية للنشر العالمي.
الخطوة 7 — ربط D1 للعلاقي
npx wrangler d1 create edge-demo-db
[[d1_databases]]
binding = "DB"
database_name = "edge-demo-db"
database_id = "<id retourné par la commande>"
echo "CREATE TABLE orders (id TEXT PRIMARY KEY, amount REAL, currency TEXT);" > schema.sql
npx wrangler d1 execute edge-demo-db --file=schema.sql --remote
router.get_async("/orders", |_, ctx| async move {
let db = ctx.env.d1("DB")?;
let res = db.prepare("SELECT id, amount, currency FROM orders LIMIT 50")
.all().await?;
Response::from_json(&res.results::()?)
})
الخطوة 8 — تخزين الملفّات بـ R2
R2 تخزين كائنات متوافق مع S3، دون رسوم خروج. للصور، تصدير CSV، أرشيف.
npx wrangler r2 bucket create edge-demo-assets
router.get_async("/asset/:key", |_, ctx| async move {
let key = ctx.param("key").unwrap_or(&"".to_string()).clone();
let bucket = ctx.env.bucket("ASSETS")?;
match bucket.get(&key).execute().await? {
Some(obj) => {
let body = obj.body().ok_or(Error::from("empty body"))?;
Response::from_stream(body.stream()?)
}
None => Response::error("not found", 404),
}
})
الخطوة 9 — مراقبة Worker في الإنتاج
npx wrangler tail edge-demo --format pretty
Dashboard Cloudflare يعرض metrics مُجَمَّعة: طلبات/ث، أخطاء، مدّة CPU. لمراقبة أدقّ — traces OpenTelemetry، metrics مخصَّصة — يُهَيَّأ Trace Worker يدفع نحو endpoint OTLP.
الخطوة 10 — أخطاء شائعة
| العَرَض | السبب | الحلّ |
|---|---|---|
| Error: Worker exceeded startup time limit | Binaire ضخم أو init كثير | قَلِّل التبعيّات، release مُحَسَّن للحجم |
| Error: KV binding ‘CACHE’ not found | wrangler.toml غير محاذي للكود | تأكّد من تطابق binding |
| error[E0432]: unresolved import ‘worker’ | worker غير مدرج في Cargo.toml |
أضف التبعية وأعد الترجمة |
| npx wrangler: command not found | Node غير مثبَّت | ثبّت Node 20+ وأعد التشغيل |
| خطأ 1101 في الإنتاج | Panic Rust غير مُسترَدّ | تحقّق من أنّ panic=unwind نشط |
| كلفة طلب أعلى من المتوقّع | Sub-requests KV/D1 غير محسوبة أوّليًّا | اقرأ شبكة Workers Paid: 5 USD/شهر + 10 M طلب، ثم 0.50 USD/مليون |
تحسين cold start والذاكرة
Cloudflare يُنَفِّذ كلّ Worker في isolate V8 قصير؛ مدّة التهيئة تثقل مباشرة على زمن الاستجابة. ثلاثة رافعات لها أثر مقاس على Worker Rust + WebAssembly.
حجم binary. النسبة bytes منزَّلة/مُحَلَّلة تُتَرجَم مباشرة إلى startup time. الـ release بـ opt-level = "s" وlto = true يُقَسِّم الحجم نمطيًّا على اثنين مقارنة بـ release افتراضي. تجنّب crates التي تُفَعِّل networking ثقيل.
تجفيف التبعيّات الثقيلة. إن احتجت regex مُجَمَّعة، أعلنها static مع once_cell::sync::Lazy لتُجَمَّع عند تهيئة isolate لا عند كلّ طلب. كذلك لعملاء HTTP، إعدادات parsées، JSON schemas.
تقاسم الحالة بين الطلبات. Workers يُخَزِّن modules WebAssembly المُجَمَّعة ويُعيد استعمال isolates. لكن isolate قد يخدم آلاف الطلبات قبل إعادة التدوير: تفادي تسريبات الذاكرة (Vec يكبر بلا حدود، caches غير محدودة) مهمّ.
الأمن والأسرار في الإنتاج
Workers يُوَفِّر آليّتَين للأسرار. environment variables مُخَزَّنة بالواضح في dashboard وقابلة للقراءة من أيّ شخص بوصول للحساب. secrets مُشَفَّرة في السكون ولا يمكن قراءتها سوى من Worker نفسه في runtime.
npx wrangler secret put STRIPE_API_KEY
# Enter a secret value: sk_live_...
في Rust، نقرأ secret عبر env.secret("STRIPE_API_KEY")?.to_string(). التمييز secret/variable مسألة تخزين فقط: في الكود، API مطابقة. ضع في secret كلّ مفتاح API ثالث، token توثيق، وwebhook secret.
للدفاع المُتعمَّق، أضف middleware توثيق في router: تحقّق توقيع HMAC على webhooks، صلاحية JWT على routes API.
للتعمّق
- WASI وخوادم WebAssembly مع Wasmtime
- عزل agent IA في sandbox WebAssembly
- الدليل الرئيسي WebAssembly في الإنتاج
مصادر رسمية
developers.cloudflare.com/workers/languages/rustgithub.com/cloudflare/workers-rsdevelopers.cloudflare.com/workers/wranglerdevelopers.cloudflare.com/kvdevelopers.cloudflare.com/d1developers.cloudflare.com/r2blog.cloudflare.com— Rust Workers reliable
Cloudflare Workers + Rust + WebAssembly على الأرجح أربح توليفة لنشر كود edge عالي الأداء في 2026. كلفة تعلّم سلسلة worker-build تُسَدِّدها أزمنة استجابة في عشرات المايكروثوانٍ وفاتورة مستقرّة. لما وراء HTTP الأساسي، binding KV/D1/R2 الموثَّق هنا يكفي لتصنيع API عمل كامل.