يا جماعة الخير، بتذكر هذاك اليوم زي كأنه امبارح. كنا قاعدين أنا والشباب في المكتب، بنشرب القهوة السادة وبنخطط للميزات الجديدة في تطبيقنا. الأجواء كانت حلوة والكل مبسوط، لحد ما وصلني إيميل من أمازون… فاتورة AWS الشهرية.
فتحت الإيميل، وشفت الرقم. بصراحة، القهوة اللي شربتها صارت مرة فجأة. الرقم كان أكبر بكثير من المتوقع، وكأنه في حدا ناسي حنفية المصاري مفتوحة. صار الكل يطلع فيّ، وأنا مش عارف شو أحكي. بدأنا فوراً “تحقيق جنائي” في لوحة تحكم AWS، لنكتشف من هو المجرم الذي يلتهم ميزانيتنا بهذه الشراهة.
المجرم لم يكن شخصاً، بل كان “خادماً” (Server). خادم افتراضي من نوع EC2، قوي ومحترم، لكنه كان “خامل” معظم الوقت. كان مثل موظف منوم مغناطيسياً، يأخذ راتباً كاملاً مقابل دقائق معدودة من العمل الفعلي يومياً. هنا كانت بداية رحلتنا مع عالم الـ Serverless، العالم الذي أنقذنا من جحيم الموارد الخاملة.
ما هي مشكلة الموارد الخاملة (The Idle Resources Problem)؟
قبل ما ندخل في الحل، خلينا نفهم أصل المشكلة. في النموذج التقليدي للحوسبة السحابية (المعروف بـ IaaS أو Infrastructure as a Service)، أنت تقوم باستئجار خوادم افتراضية (Virtual Machines) مثل EC2 في AWS أو VMs في Azure. أنت تختار مواصفات الخادم (المعالج، الذاكرة، إلخ) وتدفع مقابل تشغيله، عادة بالساعة أو بالثانية.
المشكلة تظهر عندما يكون حمل العمل (Workload) على تطبيقك غير منتظم. تخيل معنا السيناريو التالي:
- لديك تطبيق يسمح للمستخدمين برفع صور، ويقوم خادمك بمعالجة هذه الصور (تغيير حجمها، إضافة علامة مائية، إلخ).
- معظم المستخدمين يرفعون الصور خلال ساعات النهار والمساء الباكر.
- أما في الليل، فالحركة شبه معدومة.
لكي تضمن تجربة مستخدم جيدة، أنت مضطر لحجز خادم قوي بما يكفي للتعامل مع “ساعات الذروة”. لكن ماذا يحدث في بقية الـ 20 ساعة من اليوم؟ الخادم يبقى يعمل، وأنت تدفع ثمنه كاملاً، وهو “قاعد بصرف مصاري عالفاضي”. هذا بالضبط ما نسميه الموارد الخاملة (Idle Resources). إنه مثل استئجار حافلة كبيرة وتوظيف سائق لها على مدار 24 ساعة، فقط لنقل راكب واحد أو اثنين في الصباح الباكر.
الحل السحري: الحوسبة بلا خوادم (Serverless)
هنا يأتي دور المنقذ: الحوسبة بلا خوادم أو الـ Serverless. هي ليست سحراً بالمعنى الحرفي، ولكن نتائجها تبدو كذلك!
شو يعني “بلا خوادم”؟ هل ما في سيرفرات بالمرة؟
هذا أول سؤال يخطر على بال الجميع. والجواب البسيط: لأ، طبعاً في خوادم! الاسم مضلل بعض الشيء. الفكرة ليست أنه لا توجد خوادم، بل الفكرة هي أنك كمطور لم تعد مسؤولاً عن إدارة هذه الخوادم.
مزود الخدمة السحابية (AWS, Google, Azure) هو من يتكفل بكل شيء:
- توفير الخادم عند الحاجة.
- تشغيل الكود الخاص بك عليه.
- توسيع النطاق (Scaling) تلقائياً إذا زاد الضغط.
- إيقاف كل شيء عند انتهاء التنفيذ.
- صيانة وتحديث الخوادم وأنظمة التشغيل.
أنت كل ما عليك هو كتابة الكود الخاص بك على شكل “دالة” (Function) ورفعها على المنصة. من هنا جاء اسم آخر لهذه التقنية: Functions as a Service (FaaS). النموذج تغير جذرياً: بدلاً من الدفع مقابل “وقت تشغيل الخادم”، أصبحت تدفع فقط مقابل “وقت تنفيذ الكود الفعلي”، محسوباً بالميلي ثانية!
بالعودة إلى مثال الحافلة، بدلاً من استئجارها طوال اليوم، أنت الآن تدفع لخدمة توصيل فقط عندما يكون لديك طرد تريد إرساله. لا يهمك نوع السيارة التي يستخدمونها أو أين يوقفونها، المهم أن الطرد يصل، وأنت تدفع فقط مقابل تلك الرحلة المحددة.
قصتنا مع AWS Lambda: من الفاتورة الصادمة إلى التوفير الهائل
بعد التحقيق في فاتورتنا، وجدنا أن المتهم الرئيسي هو خادم EC2 المخصص لمعالجة الصور التي يرفعها المستخدمون. كان خادماً قوياً لضمان سرعة المعالجة في أوقات الذروة، ولكنه كان ينام معظم الليل، وفاتورته لا تنام.
التشخيص والانتقال إلى Lambda
القرار كان واضحاً: هذه المهمة مثالية للتحويل إلى بنية Serverless. المهمة بطبيعتها “event-driven” أو “مدفوعة بالأحداث”:
- الحدث (Event): مستخدم يرفع صورة جديدة إلى مخزن الملفات (AWS S3).
- الإجراء (Action): دالة برمجية تبدأ بالعمل، تقرأ الصورة، تعالجها، ثم تحفظ النسخ الجديدة في مكان آخر.
الخطة كانت بسيطة: سنتخلص من خادم EC2 تماماً، ونستبدله بدالة AWS Lambda يتم استدعاؤها تلقائياً كلما تم رفع ملف جديد إلى S3.
مثال كود بسيط (باستخدام Python)
لتقريب الصورة، هذا مثال مبسط جداً للكود الذي كتبناه. الدالة تستخدم مكتبة Pillow لمعالجة الصور.
import boto3
from PIL import Image
import io
import os
# Create S3 client
s3 = boto3.client('s3')
# Get destination bucket from environment variables for flexibility
DESTINATION_BUCKET = os.environ['DESTINATION_BUCKET']
def lambda_handler(event, context):
# 1. Get the bucket and key (file name) from the trigger event
source_bucket = event['Records'][0]['s3']['bucket']['name']
key = event['Records'][0]['s3']['object']['key']
try:
# 2. Download the image from the source S3 bucket
response = s3.get_object(Bucket=source_bucket, Key=key)
image_content = response['Body'].read()
# 3. Process the image using Pillow library
with Image.open(io.BytesIO(image_content)) as image:
# Create a thumbnail (e.g., 128x128 pixels)
image.thumbnail((128, 128))
# Prepare buffer to save the new image without writing to disk
buffer = io.BytesIO()
image.save(buffer, format="JPEG")
buffer.seek(0) # Rewind the buffer to the beginning
# 4. Upload the processed thumbnail to the destination bucket
new_key = f"thumbnails/{key}"
s3.put_object(
Bucket=DESTINATION_BUCKET,
Key=new_key,
Body=buffer,
ContentType='image/jpeg'
)
print(f"Successfully processed {key} and created thumbnail {new_key}.")
return {'status': 'success'}
except Exception as e:
print(f"Error processing image {key}: {e}")
raise e
ربطنا هذه الدالة بـ S3 بحيث يتم تشغيلها تلقائياً عند أي عملية s3:ObjectCreated:*. والنتيجة؟
النتيجة: “يا فرحة ما تمت!”.. بس تمت!
مر شهر، ووصلت الفاتورة الجديدة. كنت أفتح الإيميل وأنا أترقب بقلق. فتحت الفاتورة، وبدأت أبحث عن تكلفة معالجة الصور…
- التكلفة قبل (EC2 Server): حوالي 180 دولار شهرياً (لخادم يعمل 24/7).
- التكلفة بعد (AWS Lambda): حوالي 5 دولارات شهرياً!
نعم، 5 دولارات فقط. في الحقيقة، جزء كبير من استخدامنا كان يقع ضمن “الطبقة المجانية” (Free Tier) التي توفرها AWS لخدمة Lambda (مليون طلب مجاني و 400,000 جيجابايت-ثانية من وقت الحوسبة شهرياً). لقد وفرنا أكثر من 95% من التكلفة، والأجمل من ذلك:
- لا إدارة للخوادم: تخلصنا من عبء التحديثات، الرقابة الأمنية، وكل ما يتعلق بإدارة الخادم. “راسنا برد” كما نقول.
- توسع لانهائي (تقريباً): إذا قام 1000 مستخدم برفع صور في نفس اللحظة، ستقوم AWS بتشغيل 1000 نسخة من الدالة بالتوازي تلقائياً. لم نعد بحاجة للقلق بشأن “ساعة الذروة”.
نصائح من خبرة أبو عمر
بعد هذه التجربة وغيرها، تعلمت بعض الدروس التي أحب أن أشاركها معكم:
ابدأ صغيراً (Start Small)
لا تحاول تحويل تطبيقك بالكامل إلى Serverless مرة واحدة. ابدأ بجزء صغير ومعزول، مثل مهمتنا لمعالجة الصور، أو إرسال إيميل ترحيبي، أو مهمة مجدولة (Cron Job). انظر للنتائج، تعلم، ثم توسع.
راقب التكاليف والأخطاء (Monitor Costs & Errors)
صحيح أن Serverless رخيص، لكن خطأ برمجي بسيط (مثل حلقة لا نهائية تستدعي الدالة نفسها) يمكن أن يؤدي إلى فاتورة ضخمة. استخدم أدوات المراقبة مثل AWS Cost Explorer و CloudWatch، وقم بتعيين تنبيهات للفواتير (Billing Alerts).
افهم القيود (Understand the Limitations)
دوال Lambda لها قيود، مثل أقصى مدة للتنفيذ (حالياً 15 دقيقة) وحدود للذاكرة. هي ليست مناسبة للمهام الطويلة جداً أو التطبيقات التي تحتاج للتحكم الكامل في بيئة التشغيل.
استخدم البنية التحتية ككود (Use IaC)
لا تقم بإعداد الدوال والمحفزات يدوياً من خلال الواجهة الرسومية في البيئة الإنتاجية. استخدم أدوات مثل AWS SAM, Serverless Framework, أو Terraform. هذا يجعل بنيتك التحتية قابلة للتكرار، التوثيق، والإدارة عبر أنظمة التحكم في الإصدارات (مثل Git).
الخلاصة: متى تستخدم Serverless ومتى تبتعد عنه؟
الحوسبة بلا خوادم ليست حلاً لكل المشاكل، بل هي أداة قوية جداً في صندوق أدوات المطور الحديث. يجب أن تعرف متى تستخدمها.
استخدم Serverless بثقة في الحالات التالية:
- المهام المدفوعة بالأحداث: معالجة الصور والفيديو، تحليل السجلات (Logs)، مهام ETL البسيطة.
- واجهات برمجة التطبيقات (APIs): خاصة تلك التي تعاني من حركة مرور غير منتظمة.
- المهام المجدولة (Cron Jobs): لتنفيذ مهام دورية دون الحاجة لخادم يعمل طوال الوقت.
- النماذج الأولية (Prototyping): لسرعتها وسهولة إطلاقها.
كن حذراً أو ابحث عن بدائل في الحالات التالية:
- العمليات الطويلة جداً: التي تتجاوز مدة تنفيذ الدالة (أكثر من 15 دقيقة).
- التطبيقات الحساسة جداً لزمن الاستجابة: قد تعاني الدوال من “البداية الباردة” (Cold Start)، وهي تأخير بسيط في أول استدعاء. يمكن التخفيف من هذا لكنه يضيف تعقيداً.
- التطبيقات ذات الحالة (Stateful Applications): مثل خوادم الدردشة التي تحتاج لاتصال دائم (WebSockets).
في النهاية، كانت رحلتنا مع Serverless درساً قيّماً في كيفية التفكير بشكل مختلف حول البنية التحتية. لقد حررتنا من قيود إدارة الخوادم ومنحتنا مرونة وتوفيراً لم نكن نحلم به. نصيحتي لكل مطور وفريق: لا تهملوا هذه الأداة الجبارة. جربوها، ولو في مشروع جانبي، وشاهدوا الفرق بأنفسكم. 👍