خارج المتصفح: الشروع في استخدام WebAssembly بدون خادم
نشرت: 2022-03-10الآن بعد أن تم دعم WebAssembly من قبل جميع المتصفحات الرئيسية وأكثر من 85٪ من المستخدمين في جميع أنحاء العالم ، لم تعد JavaScript هي لغة المتصفح الوحيدة في المدينة. إذا لم تكن قد سمعت ، فإن WebAssembly هي لغة جديدة منخفضة المستوى يتم تشغيلها في المستعرض. إنه أيضًا هدف تجميع ، مما يعني أنه يمكنك ترجمة البرامج الحالية المكتوبة بلغات مثل C و C ++ و Rust إلى WebAssembly ، وتشغيل هذه البرامج في المستعرض. حتى الآن ، تم استخدام WebAssembly لنقل جميع أنواع التطبيقات إلى الويب ، بما في ذلك تطبيقات سطح المكتب وأدوات سطر الأوامر والألعاب وأدوات علوم البيانات.
ملاحظة: للحصول على دراسة حالة متعمقة حول كيفية استخدام WebAssembly داخل المتصفح لتسريع تطبيقات الويب ، راجع مقالتي السابقة.
WebAssembly خارج الويب؟
على الرغم من أن معظم تطبيقات WebAssembly اليوم تتمحور حول المستعرض ، إلا أن WebAssembly نفسه لم يتم تصميمه في الأصل للويب فقط ، ولكن حقًا لأي بيئة وضع الحماية. في الواقع ، كان هناك اهتمام كبير مؤخرًا باستكشاف كيف يمكن أن يكون WebAssembly مفيدًا خارج المتصفح ، كنهج عام لتشغيل الثنائيات على أي نظام تشغيل أو بنية كمبيوتر ، طالما كان هناك وقت تشغيل WebAssembly الذي يدعم هذا النظام. في هذه المقالة ، سنلقي نظرة على كيفية تشغيل WebAssembly خارج المستعرض بطريقة غير خوادم / الوظيفة كخدمة (FaaS).
WebAssembly للتطبيقات بدون خادم
باختصار ، تعد الوظائف التي لا تحتاج إلى خادم نموذجًا للحوسبة حيث تقوم بتسليم التعليمات البرمجية الخاصة بك إلى مزود خدمة سحابية ، والسماح لهم بتنفيذ وإدارة توسيع نطاق هذا الرمز نيابة عنك. على سبيل المثال ، يمكنك أن تطلب تنفيذ وظيفة بدون خادم في أي وقت تتصل فيه بنقطة نهاية واجهة برمجة التطبيقات ، أو أن تكون مدفوعة بأحداث ، مثل عندما يتم تحميل ملف إلى مجموعة السحابة الخاصة بك. على الرغم من أن مصطلح "بدون خادم" قد يبدو تسمية خاطئة نظرًا لأن الخوادم متورطة بوضوح في مكان ما على طول الطريق ، إلا أنه ليس خادمًا من وجهة نظرنا حيث لا داعي للقلق بشأن كيفية إدارة هذه الخوادم أو نشرها أو توسيع نطاقها.
على الرغم من أن هذه الوظائف تُكتب عادةً بلغات مثل Python و JavaScript (Node.js) ، إلا أن هناك عددًا من الأسباب التي قد تجعلك تختار استخدام WebAssembly بدلاً من ذلك:
- أوقات تهيئة أسرع
أبلغ مقدمو الخدمة غير الخادمين الذين يدعمون WebAssembly (بما في ذلك Cloudflare و Fastly أنه يمكنهم تشغيل وظائف على الأقل بترتيب من حيث الحجم أسرع مما يمكن لمعظم موفري السحابة باستخدام اللغات الأخرى. وهم يحققون ذلك عن طريق تشغيل عشرات الآلاف من وحدات WebAssembly في نفس العملية ، وهي ممكن لأن الطبيعة ذات وضع الحماية لـ WebAssembly توفر طريقة أكثر فاعلية للحصول على العزلة التي تُستخدم الحاويات تقليديًا من أجلها. - لا حاجة إلى إعادة كتابة
تتمثل إحدى الميزات الرئيسية لـ WebAssembly في المتصفح في القدرة على نقل التعليمات البرمجية الموجودة إلى الويب دون الحاجة إلى إعادة كتابة كل شيء إلى JavaScript. لا تزال هذه الميزة صحيحة في حالة الاستخدام بدون خادم لأن موفري السحابة يحدون من اللغات التي يمكنك كتابة وظائف بدون خادم بها. عادةً ما يدعمون Python و Node.js وربما البعض الآخر ، ولكن بالتأكيد ليس C أو C ++ أو Rust . من خلال دعم WebAssembly ، يمكن لمقدمي الخدمة بدون خادم دعم الكثير من اللغات بشكل غير مباشر. - خفيف الوزن أكثر
عند تشغيل WebAssembly في المتصفح ، فإننا نعتمد على كمبيوتر المستخدم النهائي لإجراء حساباتنا. إذا كانت هذه العمليات الحسابية مكثفة للغاية ، فلن يسعد مستخدمينا عندما يبدأ مروحة الكمبيوتر الخاصة بهم في إصدار صوت طنين. يمنحنا تشغيل WebAssembly خارج المتصفح مزايا سرعة وقابلية النقل لـ WebAssembly ، مع الحفاظ أيضًا على تطبيقنا خفيف الوزن. علاوة على ذلك ، نظرًا لأننا نقوم بتشغيل كود WebAssembly في بيئة أكثر قابلية للتنبؤ ، فمن المحتمل أن نقوم بإجراء المزيد من العمليات الحسابية المكثفة.
مثال ملموس
في مقالتي السابقة هنا على Smashing Magazine ، ناقشنا كيف قمنا بتسريع تطبيق الويب عن طريق استبدال حسابات JavaScript البطيئة برمز C المترجم إلى WebAssembly. كان تطبيق الويب المعني fastq.bio ، أداة لمعاينة جودة بيانات تسلسل الحمض النووي.
كمثال ملموس ، دعنا نعيد كتابة fastq.bio كتطبيق يستخدم WebAssembly بدون خادم بدلاً من تشغيل WebAssembly داخل المتصفح. في هذه المقالة ، سنستخدم Cloudflare Workers ، وهو مزود بدون خادم يدعم WebAssembly ومبنيًا أعلى محرك مستعرض V8. يعمل موفر سحابي آخر ، Fastly ، على عرض مشابه ، ولكن بناءً على وقت تشغيل Lucet.
أولاً ، دعنا نكتب بعض أكواد Rust لتحليل جودة البيانات لبيانات تسلسل الحمض النووي. للراحة ، يمكننا الاستفادة من مكتبة Rust-Bio bioinformatics للتعامل مع تحليل بيانات الإدخال ، ومكتبة wasm-bindgen لمساعدتنا في تجميع كود Rust الخاص بنا إلى WebAssembly.
إليك مقتطف من الشفرة يقرأ في بيانات تسلسل الحمض النووي ويخرج JSON مع ملخص لمقاييس الجودة:
// Import packages extern crate wasm_bindgen; use bio::seq_analysis::gc; use bio::io::fastq; ... // This "wasm_bindgen" tag lets us denote the functions // we want to expose in our WebAssembly module #[wasm_bindgen] pub fn fastq_metrics(seq: String) -> String { ... // Loop through lines in the file let reader = fastq::Reader::new(seq.as_bytes()); for result in reader.records() { let record = result.unwrap(); let sequence = record.seq(); // Calculate simple statistics on each record n_reads += 1.0; let read_length = sequence.len(); let read_gc = gc::gc_content(sequence); // We want to draw histograms of these values // so we store their values for later plotting hist_gc.push(read_gc * 100.0); hist_len.push(read_length); ... } // Return statistics as a JSON blob json!({ "n": n_reads, "hist": { "gc": hist_gc, "len": hist_len }, ... }).to_string() }
ثم استخدمنا أداة سطر أوامر wrangler في Cloudflare للقيام بالرفع الثقيل للترجمة إلى WebAssembly والنشر في السحابة. بمجرد الانتهاء من ذلك ، يتم منحنا نقطة نهاية API تأخذ بيانات التسلسل كمدخلات وترجع JSON بمقاييس جودة البيانات. يمكننا الآن دمج واجهة برمجة التطبيقات هذه في تطبيقنا.
إليك صورة GIF للتطبيق قيد التشغيل:
الكود الكامل متاح على GitHub (مفتوح المصدر).
وضع كل شيء في السياق
لوضع نهج WebAssembly بدون خادم في السياق ، دعنا نفكر في أربع طرق رئيسية يمكننا من خلالها إنشاء تطبيقات ويب لمعالجة البيانات (مثل تطبيقات الويب حيث نقوم بإجراء تحليل للبيانات المقدمة من المستخدم):
كما هو موضح أعلاه ، يمكن معالجة البيانات في عدة أماكن:
- جانب الخادم
هذا هو النهج الذي تتبعه معظم تطبيقات الويب ، حيث يتم إجراء استدعاءات واجهة برمجة التطبيقات في معالجة بيانات تشغيل الواجهة الأمامية على النهاية الخلفية. - جافا سكريبت من جانب العميل
في هذا الأسلوب ، تتم كتابة كود معالجة البيانات بلغة جافا سكريبت وتشغيله في المتصفح. الجانب السلبي هو أن أداؤك سيتأثر ، وإذا لم تكن شفرتك الأصلية في JavaScript ، فستحتاج إلى إعادة كتابتها من البداية! - WebAssembly من جانب العميل
يتضمن ذلك تجميع كود تحليل البيانات إلى WebAssembly وتشغيله في المتصفح. إذا تمت كتابة كود التحليل بلغات مثل C أو C ++ أو Rust (كما هو الحال غالبًا في مجال علم الجينوم الخاص بي) ، فإن هذا يغني عن الحاجة إلى إعادة كتابة الخوارزميات المعقدة في JavaScript. كما أنه يوفر إمكانية تسريع تطبيقنا (على سبيل المثال ، كما تمت مناقشته في مقالة سابقة). - تجميع ويب بدون خادم
يتضمن ذلك تشغيل WebAssembly المترجم على السحابة ، باستخدام نموذج من نوع FaaS (مثل هذه المقالة).
فلماذا تختار أسلوب عدم وجود خادم على الآخرين؟ لسبب واحد ، مقارنة بالنهج الأول ، أن له الفوائد التي تأتي مع استخدام WebAssembly ، لا سيما القدرة على نقل التعليمات البرمجية الموجودة دون الحاجة إلى إعادة كتابتها إلى JavaScript. مقارنة بالطريقة الثالثة ، فإن WebAssembly بدون خادم يعني أيضًا أن تطبيقنا خفيف الوزن نظرًا لأننا لا نستخدم موارد المستخدم لتحليل الأرقام. على وجه الخصوص ، إذا كانت العمليات الحسابية متضمنة إلى حد ما أو إذا كانت البيانات موجودة بالفعل في السحابة ، فإن هذا النهج يكون أكثر منطقية.
من ناحية أخرى ، يحتاج التطبيق الآن إلى إجراء اتصالات بالشبكة ، لذلك من المحتمل أن يكون التطبيق أبطأ. علاوة على ذلك ، اعتمادًا على حجم الحساب وما إذا كان قابلاً للتقسيم إلى أجزاء تحليل أصغر ، قد لا يكون هذا النهج مناسبًا بسبب القيود التي يفرضها موفرو السحابة بدون خادم على وقت التشغيل ووحدة المعالجة المركزية واستخدام ذاكرة الوصول العشوائي.
خاتمة
كما رأينا ، من الممكن الآن تشغيل رمز WebAssembly بطريقة لا تتطلب خادمًا وجني فوائد كل من WebAssembly (قابلية النقل والسرعة) وتلك الخاصة بهياكل الوظيفة كخدمة (القياس التلقائي والتسعير لكل استخدام) ). يمكن أن تستفيد أنواع معينة من التطبيقات - مثل تحليل البيانات ومعالجة الصور ، على سبيل المثال لا الحصر - بشكل كبير من مثل هذا النهج. على الرغم من أن وقت التشغيل يعاني بسبب الرحلات الإضافية ذهابًا وإيابًا إلى الشبكة ، إلا أن هذا الأسلوب يسمح لنا بمعالجة المزيد من البيانات في وقت واحد وعدم استنزاف موارد المستخدمين.