WebAssembly يتحول بهدوء إلى بيئة التشغيل الافتراضية للحوسبة الطرفية

مشاركة:
WebAssembly يتحول بهدوء إلى بيئة التشغيل الافتراضية للحوسبة الطرفية

تتنافس Cloudflare وFastly على العملاء أنفسهم، وتُشغّلان منصتين غير متوافقتين، ونادراً ما تتفقان علناً على أي شيء. ومع ذلك، توصلت الشركتان إلى الاستنتاج نفسه بشأن منتجاتهما للحوسبة الطرفية: WebAssembly، وليس الحاويات، هو بيئة التشغيل التي تجعل التنفيذ الموزّع عالمياً بزمن استجابة منخفض يعمل فعلياً. هذا التقارب ليس صدفة ولا مجرد مواكبة لموجة رائجة، بل مشكلة فيزيائية لا تستطيع الحاويات حلها عند الحجم الذي تعمل به شبكات الحافة.

مشكلة الإقلاع البارد التي لم تحلها الحاويات قط

تحتاج الحاوية إلى نواة نظام تشغيل، وطبقة نظام ملفات، وقرار من المُجدوِل (scheduler) قبل أن ينفّذ الكود لديك تعليمة واحدة فقط. حتى بيئات تشغيل الحاويات المُحسَّنة تقيس زمن الإقلاع بعشرات الميلي ثانية. وهذا مقبول لمركز بيانات يستقبل حركة مرور ثابتة نحو حفنة من المناطق، لكنه غير مقبول لشبكة طرفية تريد تشغيل دالتك بشكل بارد في أي نقطة من أكثر من 330 نقطة حضور، أقربها إلى الطلب، مع كل استدعاء على حدة، لأن إبقاء الحاويات "دافئة" في كل موقع طرفي لكل عميل أمر غير قابل للتوسع اقتصادياً.

يتجاوز WebAssembly هذه المشكلة تماماً. فوحدة Wasm هي تنسيق بايت-كود مضغوط ومعزول (sandboxed) لا يعتمد على أي نواة نظام تشغيل، وتبدأ ضمن العملية نفسها الخاصة بمضيف بيئة التشغيل. تُنشئ Fastly Compute، المبنية على Wasmtime، الوحدات في نطاق الميكروثانية بدلاً من الميلي ثانية. وتُشغّل Cloudflare Workers كود Wasm ضمن معمارية عزل V8 نفسها التي تستخدمها بالفعل لتشغيل JavaScript، بحيث تتشارك وحدة Wasm ودالة JS الضمان نفسه للإقلاع السريع. هذا فارق يبلغ 1000 ضعف في فئة زمن الإقلاع، وعند الحافة، زمن الإقلاع ليس مجرد تحسين، بل هو جوهر القيمة المقدَّمة بالكامل.

Component Model يجعل كود الحافة متعدد اللغات عملياً

حتى وقت قريب، كانت أكبر نقطة ضعف عملية في Wasm هي قابلية التشغيل البيني. فوحدة Wasm مُترجَمة من Rust ووحدة أخرى مُترجَمة من Go لم يكن بإمكانهما استدعاء دوال بعضهما البعض بسهولة أو مشاركة أنواع بيانات معقدة، إذ كان على المطورين تسلسل (serialize) كل شيء يدوياً عبر حدود مصفوفة بايتات، ما كان يُفقد الكثير من جاذبية Wasm بالنسبة للفرق التي تمتلك قواعد كود متعددة اللغات.

يعالج WebAssembly Component Model هذه المشكلة مباشرة. فهو يُعرّف نظام أنواع واجهات موحّداً (WIT) يتيح للوحدات المُترجَمة من لغات مصدر مختلفة أن تعرض واجهات مُصنَّفة (typed) لبعضها البعض، قابلة للتركيب كما كانت المكتبات المشتركة قبل أن تجعل صور الحاويات هذا النوع من التركيب أمراً مرهقاً. وتُظهر بيانات استطلاع المطورين الخاص بـCloudflare هذا التحول بشكل ملموس: شكّلت مكوّنات WASM 12% من عمليات نشر Workers في عام 2023، وارتفعت هذه النسبة إلى 34% في آخر قياس لها. هذا ليس مجرد ضجيج من المتبنّين الأوائل، بل بيئة تشغيل تتحول إلى بنية تحتية افتراضية.

ما الذي يُترجَم فعلياً إلى Wasm اليوم

تبقى Rust الهدف الأكثر نضجاً، إذ يجعلها غياب جامع القمامة (garbage collector) وحجم الملفات الثنائية الصغير توافقاً شبه مثالي مع قيود الحافة. أما Go فتمتلك دعماً قابلاً للاستخدام لكنه أثقل عبر TinyGo. وتُترجَم C وC++ عبر Emscripten، مع قدرة عقود من الكود القائم على استهداف Wasm بتعديلات متواضعة. وتعمل Python وJavaScript عبر مفسِّرات (interpreters) مُترجَمة إلى Wasm، وهو ما ينجح لكنه يضحي ببعض ميزة الإقلاع البارد لأنك تشحن مفسِّراً إلى جانب الكود الخاص بك. وإذا كان منطق الحافة لديك حساساً فعلياً للأداء — توجيه الطلبات، فحوصات المصادقة، إعادة كتابة الترويسات، تحويل الصور — فإن مسار Rust إلى Wasm يمثل حالياً أقوى مزيج من نضج المنظومة وخصائص بيئة التشغيل.

أين لا تزال هناك ثغرات

يعني نموذج العزل (sandboxing) في Wasm أن الوصول المباشر لنظام الملفات والمقابس الخام (raw sockets) يمر عبر WASI (واجهة نظام WebAssembly)، وهي لا تزال في طور الاستقرار — لذا توقع تغييرات في سطح الـAPI مع نضوج ميزات WASI Preview 2 نحو دعم أوسع. كما لا يزال التصحيح (debugging) متأخراً مقارنة بالحاويات: تتحسن أدوات تتبع المكدس (stack trace) والتنميط (profiling) الخاصة بـWasm العاملة داخل مضيف طرفي، لكنها لم تصل بعد إلى نضج عقد كامل من أدوات الحاويات. وبالنسبة للأحمال التي تحتاج إلى حالة طويلة الأمد، أو وصولاً مكثفاً لوحدة معالجة الرسوميات (GPU)، أو تكاملاً عميقاً مع نظام التشغيل، فإن Wasm عند الحافة ليس الأداة المناسبة — إذ يبقى هذا النوع من العمل مكانه في حاوية تقليدية أو آلة افتراضية (VM) أقرب إلى بياناتك.

ما الذي ينبغي فعله فعلياً حيال ذلك

إذا كنت تبني أي شيء يعمل وقت الطلب على Cloudflare Workers أو Fastly Compute أو Vercel Edge Functions، فعامل Wasm بوصفه الهدف الافتراضي، لا مجرد تجربة. وبالنسبة للخدمات الجديدة المصمَّمة أصلاً للحافة، ابنِ نموذجاً أولياً بلغة Rust قبل اللجوء إلى نهج قائم فقط على JS/TS إذا كان زمن الاستجابة مهماً، لأن الفجوة في زمن الإقلاع تتراكم عبر ملايين الاستدعاءات. وإذا كان فريقك يشحن بالفعل عدة لغات، فابدأ الآن بمتابعة أدوات WIT الخاصة بـComponent Model؛ فهي العنصر الذي سيتيح لك التوقف عن كتابة كود تسلسل يدوي وهش بين وحدات الحافة. وإذا كان حمل العمل لديك يحتاج فعلياً إلى اتصالات دائمة، أو حالة كبيرة في الذاكرة، أو حوسبة GPU، فلا تُجبره على العمل ضمن Wasm لمجرد أنه رائج — فهذا بالضبط نوع الحمل الذي لم يُصمَّم نموذج بيئة تشغيل الحافة لحله أساساً.

مشاركة:
WebAssembly يتحول بهدوء إلى بيئة التشغيل الافتراضية للحوسبة الطرفية | AIO APEX