يعني إيه Backend؟ وإيه اللي بيحصل لما تدوس زرار في أي تطبيق
أي تطبيق ليه وشّين: اللي بتشوفه (الشاشة والأزرار = Frontend) واللي ورا الكواليس (السيرفر والبيانات = Backend). الكتاب ده عن الوش التاني.
1
يعني إيه Backend؟
هو الجزء اللي بيشتغل على السيرفر: بيستقبل طلبك، يفكّر، يجيب البيانات من قاعدة البيانات، ويرجّع لك الرد. كل اللي مهم (البيانات، القرارات، الأمان) بيحصل هنا.
تشبيه 🍽️
المطعم: الصالة اللي قاعد فيها = Frontend. المطبخ والمخزن والحسابات = Backend. إنت بتشوف الطبق بس، مش شايف إيه حصل ورا الباب.
2
مهندس الباك إند بيعمل إيه؟
بيبني الـ API (الطريقة اللي التطبيق بيكلّم بيها السيرفر)
بيكتب المنطق: لو الرصيد كفاية اقبل الطلب
بيتعامل مع قاعدة البيانات
بيعمل تسجيل الدخول والصلاحيات
بيربط مع خدمات تانية (دفع، إيميل، خرائط)
بيخلّي النظام آمن وسريع ومش بيقع
3
رحلة الطلب — من الزرار للرد
إنت بتدوس زرار
→
Request طلب بيتبعت
→
السيرفر بيفهم ويفكّر
→
قاعدة البيانات بيجيب/يحفظ
→
Response رد بيرجع
→
الشاشة بتتحدّث
① إنت بتدوس "اطلب دلوقتي".
② التطبيق بيبعت طلب (Request) للسيرفر: "المستخدم 7 عايز المنتج 42".
③ السيرفر بيوجّه الطلب للكود المسؤول عن الطلبات.
④ الكود بيتأكد: هو مسجّل دخول؟ المنتج متاح؟ الرصيد كفاية؟
⑤ بيحفظ الطلب في قاعدة البيانات.
⑥ بيرجّع رد (Response): "تم ✅ رقم طلبك 1001".
⑦ الشاشة بتعرض الرسالة.
خد بالك: كل ده بيحصل في أقل من ثانية. وطول الكتاب هنفتح كل خطوة فيهم ونشوف إيه اللي جواها.
?
طيب الطلب ده بيتبعت إزاي؟ يعني إيه HTTP؟
3/25→
?
HTTP — اللغة اللي التطبيق بيكلّم بيها السيرفر شكل الطلب وشكل الرد
عشان التطبيق والسيرفر يفهموا بعض، لازم يتفقوا على شكل الرسالة. الاتفاق ده اسمه HTTP. زي ما الجواب البريدي ليه شكل متفق عليه: عنوان، موضوع، محتوى.
HTTP زي ساعي البريد اللي مش بيفتكر حد. كل جواب لازم يكون عليه اسمك وعنوانك كامل، حتى لو بعت 100 جواب النهارده. وHTTPS = نفس الجواب بس في ظرف مقفول بالشمع — محدش يقدر يقرأه في الطريق.
معلومة مهمة:HTTPمش بيفتكر (Stateless). كل طلب مستقل — السيرفر مش فاكر الطلب اللي قبله. عشان كده لازم تبعت "مين إنت" مع كل طلب (هنشوف إزاي في صفحة تسجيل الدخول).
?
طيب الرد بيقول نجح ولا لأ إزاي؟ أكواد الحالة والأفعال
4/25→
?
أكواد الحالة والأفعال الأرقام اللي بتقولك حصل إيه، والأفعال اللي بتطلب بيها
1
أكواد الحالة — احفظ دول بس
الكود
معناه بالبلدي
200
تمام ✅
201
اتعمل جديد ✅
400
طلبك فيه غلط ❌
401
مين إنت؟ سجّل دخول
403
عارفك بس مش مسموح لك
404
مش موجود
429
بطّئ شوية — طلبات كتير
500
السيرفر وقع 🔥
2xx = نجاح · 4xx = الغلط منك · 5xx = الغلط من السيرفر
2
الأفعال — HTTP Methods
الفعل
يعني
مثال
GET
هات لي
هات المستخدم 7
POST
اعمل جديد
سجّل مستخدم
PUT
عدّل كله
غيّر كل بياناته
PATCH
عدّل جزء
غيّر الإيميل بس
DELETE
امسح
امسح المستخدم 7
تشبيه 🍽️
المنيو: GET = "ممكن أشوف المنيو؟" · POST = "عايز أطلب" · PATCH = "غيّر لي المشروب بس" · DELETE = "الغي الطلب".
3
سؤال مقابلة شهير: الفرق بين 401 و 403؟
طلب من غير توكن
→
401 مين إنت؟ سجّل دخول الأول
طلب من مستخدم عادي يمسح أدمن
→
403 عارفك، بس مش مسموح لك
الفرق:401 = ما عرفناكش. 403 = عرفناك ومش مسموح. زي الفرق بين "مين إنت؟" عند باب الشركة، و"إنت موظف بس المكتب ده للمدير بس".
كمان:GET وDELETE لو كرّرتهم 10 مرات النتيجة واحدة (Idempotent). POST كل مرة بيعمل حاجة جديدة — عشان كده لو دوست "اطلب" مرتين ممكن يتعمل طلبين!
?
طيب إزاي ننظّم العناوين دي بشكل الكل يفهمه؟
5/25→
?
REST API — نظام العناوين المتفق عليه إزاي تصمّم API أي مبرمج يفهمه من غير شرح
الـ API = مجموعة العناوين اللي التطبيق بيكلّم بيها السيرفر. وREST = قواعد بسيطة لتنظيمها: كل حاجة ليها عنوان، والفعل بيحدد هتعمل إيه.
1
القواعد في 4 سطور
العنوان اسم مش فعل: /users مش /getUsers
الاسم بصيغة الجمع: /users مش /user
العلاقات متداخلة: /users/7/orders = طلبات المستخدم 7
الفعل من HTTP: GET يجيب، POST يعمل، DELETE يمسح
تشبيه 🗂️
زي الفولدرات على جهازك: مسار واضح لكل حاجة، ونفس الأفعال للكل (افتح، اعمل جديد، امسح). أي حد يعرف النظام يلاقي أي حاجة من غير ما يسأل.
2
مثال: المستخدمين
الفعل
العنوان
بيعمل إيه
GET
/users
كل المستخدمين
GET
/users/7
المستخدم 7 بس
POST
/users
أضف مستخدم جديد
PUT
/users/7
عدّل المستخدم 7
DELETE
/users/7
امسح المستخدم 7
❌ غلط
✅ صح
/getUsers
GET /users
/createUser
POST /users
/deleteUser/7
DELETE /users/7
3
حاجات صغيرة بتفرق كتير
?page=2&limit=10تقسيم الصفحات: متجيبش مليون مستخدم مرة واحدة — هات 10 في كل صفحة
?role=adminفلترة: هات الأدمن بس
?sort=nameترتيب: بالاسم
/api/v1/…رقم إصدار: عشان لما تغيّر الـ API التطبيقات القديمة متبوظش
الـ Hash زي البيضة المقلية: من البيضة تعمل مقلية، بس من المقلية مستحيل ترجّع البيضة. ولما حد يدخل كلمة السر، بتقليها وتقارن المقليتين.
2
الصلاحيات بالأدوار (RBAC)
بدل ما تحدد لكل مستخدم لوحده يقدر يعمل إيه، بتعمل أدوار وتربط المستخدم بدور:
المستخدم
→
الدور Admin
→
الصلاحيات يقرأ · يعدّل · يمسح
الدور
يقدر يعمل
Admin
كل حاجة
Manager
يقرأ ويعدّل
User
يقرأ بس
تشبيه 🔑
مفاتيح المبنى: البواب معاه مفتاح الباب الرئيسي، المدير معاه كل المفاتيح، الموظف معاه مفتاح مكتبه بس.
3
أخطر 3 هجمات وحمايتها
الهجوم
إزاي بيحصل
الحماية
SQL Injection
يكتب كود في خانة البحث يمسح الجدول
متلزقش النص في الاستعلام — استخدم Prepared Statements
XSS
يكتب سكريبت في تعليق، يتنفّذ عند كل زائر
نضّف أي حاجة جاية من المستخدم قبل عرضها
تخمين الباسورد
يجرّب ألف كلمة سر في الثانية
حدّد عدد المحاولات + اقفل الحساب مؤقتًا
القاعدة الذهبية:أي حاجة جاية من المستخدم = مش موثوقة. اتأكد منها، نضّفها، وحطها في مكانها الصح.
?
البيانات دي كلها بتتخزن فين؟ قاعدة البيانات
8/25→
?
قاعدة البيانات Database فين البيانات بتتحفظ، وإزاي بننظّمها
قاعدة البيانات = المكان اللي كل حاجة بتتحفظ فيه بشكل دائم ومنظّم: المستخدمين، الطلبات، المنتجات. لو السيرفر اتقفل وفتح تاني، البيانات لسه موجودة.
1
نوعين أساسيين
SQL (جداول)
NoSQL (مرنة)
الشكل
صفوف وأعمدة زي Excel
مستندات زي JSON
القواعد
صارمة — كل صف نفس الأعمدة
مرنة — كل مستند شكله
الأقوى في
علاقات وحسابات دقيقة
كميات ضخمة وسرعة
أمثلة
MySQL · PostgreSQL
MongoDB · Redis
اختار إيه؟SQL للبنوك والطلبات وأي حاجة فيها فلوس وعلاقات. NoSQL للوجات والتحليلات والبيانات اللي شكلها بيتغيّر. وأغلب المشاريع بتبدأ بـ SQL.
2
الجداول والعلاقات
كل كيان (مستخدم، طلب) = جدول. وبنربط الجداول ببعض بـمفاتيح:
Orders id user_id ← بيشاور على Users total
←
1 لـ N
Users id ← المفتاح الأساسي name email
Primary Key رقم فريد لكل صف — زي الرقم القومي
Foreign Key بيشاور على صف في جدول تاني — "الطلب ده بتاع المستخدم 7"
Unique متتكررش — الإيميل مثلًا
3
ليه نقسّم الجداول؟ (Normalization)
لو حطيت اسم المستخدم في كل طلب، وغيّر اسمه… هتعدّل في 1000 صف! الحل: المستخدم في جدول، والطلبات بتشاور عليه بالرقم بس.
❌ قبل: التكرار
الطلب
الاسم
المنتج
1
Ahmed
لابتوب
2
Ahmed
ماوس
3
Sara
كيبورد
✅ بعد: جدولين مترابطين
id
الاسم
1
Ahmed
2
Sara
الطلب
user_id
المنتج
1
1
لابتوب
2
1
ماوس
3
2
كيبورد
تشبيه 📇
بدل ما تكتب عنوان صاحبك كامل على كل جواب، تكتب "أحمد" وعنوانه محفوظ في دفتر العناوين مرة واحدة. غيّر عنوانه؟ تعدّل الدفتر بس.
?
الاستعلام بطيء… إزاي نخلّي قاعدة البيانات أسرع وأأمن؟
9/25→
?
الفهرس Index والمعاملة Transaction السرعة والأمان في قاعدة البيانات
1
Index — ليه البحث بطيء؟
من غير Index، قاعدة البيانات بتفتّش كل الصفوف واحد واحد عشان تلاقي إيميل. مع مليون مستخدم = بطء رهيب.
تشبيه 📖
فهرس آخر الكتاب: بدل ما تقلّب 500 صفحة تدوّر على كلمة "Redis"، تبص في الفهرس يقولك صفحة 212. بس كل ما تضيف صفحة لازم تحدّث الفهرس — عشان كده الـ Indexبيسرّع القراءة وبيبطّأ الكتابة شوية.
حط Index على الأعمدة اللي بتدوّر بيها كتير (الإيميل، رقم المستخدم)
متحطش على كل حاجة — كل Index بيكلّف وقت كتابة
الـ Primary Key عليه Index تلقائي
2
نصايح تخلّي الاستعلام أسرع
هات الأعمدة اللي محتاجها بس، مش SELECT *
استخدم LIMIT — متجيبش مليون صف
متعملش استعلام جوه loop (مشكلة N+1)
اعرف الاستعلام بيعمل إيه بـ EXPLAIN
بطيء ❌
SELECT * FROM users
WHERE
LOWER(email)='a@x.com'
سريع ✅
SELECT id, name FROM
users
WHERE email='a@x.com'
N+1 يعني إيه؟ جبت 100 طلب، وبعدين لكل طلب عملت استعلام تجيب صاحبه = 101 استعلام. الحل: استعلام واحد بيجيب الكل (JOIN).
3
Transaction — كله أو ولا حاجة
تحويل 1000 جنيه من أحمد لسارة = خطوتين: اخصم من أحمد، ضيف لسارة. لو الكهربا قطعت بعد الخطوة الأولى… الفلوس راحت فين؟
الحل
1BEGIN;
2UPDATE accounts SET balance = balance - 1000WHERE id = 1; -- أحمد3UPDATE accounts SET balance = balance + 1000WHERE id = 2; -- سارة4COMMIT; -- لو أي خطوة فشلت → كله يتلغي
الـ Transaction بتضمن إن الخطوتين يحصلوا مع بعض أو ولا واحدة تحصل. دي أهم صفة فيها، وليها 3 صفات تانية (بيسمّوهم ACID):
الصفة
يعني
Atomic
كله أو ولا حاجة
Consistent
القواعد متتكسرش (مفيش رصيد سالب)
Isolated
معاملتين في نفس الوقت ميلخبطوش بعض
Durable
بعد النجاح، محفوظة للأبد
تشبيه 🛒
زي الكاشير: يا إمّا تدفع وتاخد الأكياس، يا إمّا الصفقة تتلغي. مفيش حالة إنك دفعت ومخدتش حاجة.
?
قاعدة البيانات بطيئة مهما عملت… الحل: الكاش!
10/25→
?
الكاش Cache الذاكرة السريعة اللي بتوفّر على قاعدة البيانات
الكاش = نسخة من البيانات اللي بتتطلب كتير محفوظة في مكان سريع جدًا (الرامات). بدل ما تروح لقاعدة البيانات كل مرة، تاخدها من الكاش فورًا.
1
إزاي بيشتغل؟
التطبيق
→
الكاش Redis · سريع
قاعدة البيانات أبطأ
① بص في الكاش الأول.
② لقيتها؟ رجّعها فورًا ✅.
③ ملقتهاش؟ هاتها من قاعدة البيانات.
④ احفظها في الكاش لمدة معيّنة (TTL) عشان المرة الجاية.
2
الفرق بينهم
الكاش
قاعدة البيانات
السرعة
سريع جدًا (رامات)
أبطأ (هارد)
الحجم
صغير
كبير
لو اتقفل
بيتمسح
بيفضل
دوره
نسخة سريعة
المصدر الأصلي
تشبيه 🧠
الكاش زي ذاكرتك: رقم صاحبك المقرّب حافظه، مش بتفتح دفتر التليفونات كل مرة. بس لو غيّر رقمه ومحدّثتش ذاكرتك — هتتصل برقم غلط. دي مشكلة الكاش الكبرى.
3
إمتى تعمل كاش وإمتى لأ؟
✅ اعمل كاش لـ:
الحاجات اللي بتتقرأ كتير وبتتغيّر قليل
صفحة المنتجات، الصفحة الرئيسية، إعدادات الموقع
نتائج حسابات تقيلة
❌ متعملش كاش لـ:
الرصيد البنكي أو أي حاجة لازم تكون دقيقة لحظيًا
بيانات بتتغيّر كل ثانية
حاجة بتتطلب مرة واحدة بس
مثال — احفظ لمدة ساعة
1 data = redis.get("user:7");
2if (!data) {
3 data = db.find(7);
4 redis.set("user:7", data, "EX", 3600);
5 }
?
طيب الكاش بيبقى فيه بيانات قديمة… إمتى نمسحه؟ وإيه اللي ممكن يبوظ؟
11/25→
?
مشاكل الكاش وحلولها إمتى تمسح؟ وإيه الـ Stampede؟
1
TTL — عمر البيانات
كل حاجة في الكاش ليها عمر. بعده بتتمسح لوحدها. كده مش هتفضل بيانات قديمة للأبد.
حفظت المنتج في الكاش الساعة 10:00
↓
TTL = ساعة
↓
الساعة 11:00 → اتمسح لوحده
↓
الطلب الجاي يجيبه من الأول
تشبيه 🥛
زي تاريخ الصلاحية على اللبن: بعده بترميه وتجيب جديد، حتى لو شكله لسه كويس.
2
إمتى أمسح قبل الوقت؟
لو المستخدم غيّر اسمه دلوقتي، مش هنستنّى ساعة. بنمسح الكاش فورًا:
الطريقة
الفكرة
بالوقت (TTL)
ينتهي لوحده — الأبسط
يدوي
لما تعدّل، امسح الكاش بتاع الحاجة دي
Write-Through
اكتب في الكاش وقاعدة البيانات مع بعض
المقولة الشهيرة: "في حاجتين صعبين في البرمجة: تسمية الأشياء، وإبطال الكاش". السؤال دايمًا: قد إيه تتحمّل بيانات قديمة؟
3
مشكلة شهيرة: Cache Stampede
السيناريو: الصفحة الرئيسية محفوظة في الكاش. انتهى الـ TTL في لحظة فيها 10,000 زائر. كلهم ملقوهاش → كلهم راحوا لقاعدة البيانات في نفس الثانية → وقعت 💥.
تشبيه 🚪
باب المدرسة فتح، والطلبة كلهم اندفعوا مرة واحدة. الحل إن واحد بس يدخل ويفتح الباب التاني، والباقي يستنّوا ثانية.
الحلول:
قفل: أول طلب بس يروح لقاعدة البيانات، الباقي يستنّى
جدّد بدري: قبل ما ينتهي بشوية
رجّع القديم: وجدّد في الخلفية
عشوائية: خلّي الـ TTL مش نفس الرقم بالظبط للكل
?
المهام الطويلة (إيميل، تقرير)… المستخدم لازم يستنّاها؟
12/25→
?
الطابور Queue والمهام الخلفية خلّي المستخدم ياخد رده فورًا، والشغل الطويل يتم في الخلفية
لما تسجّل في موقع، بيبعتلك إيميل ترحيب. الإيميل بياخد 3 ثواني. هل لازم تستنّى الـ 3 ثواني قبل ما تشوف "تم التسجيل"؟ لأ — الطابور بيحل ده.
1
من غير طابور ❌
طلب تسجيل
↓
احفظ المستخدم سريع
↓
ابعت إيميل 3 ثواني ⏳
↓
رد للمستخدم بطيء 😩
2
مع طابور ✅
طلب تسجيل
↓
احفظ المستخدم سريع
↓
حط رسالة في الطابور جزء من الثانية
↓
رد للمستخدم فورًا ⚡
وفي الخلفية: Worker بياخد الرسالة من الطابور ويبعت الإيميل براحته
3
الفكرة والمصطلحات
المُرسِل بيحط رسالة ويمشي
→
الطابور ✉️✉️✉️
→
المستلم (Worker) بياخد ويعالج
تشبيه 🍔
طابور الطلبات في مطعم: الكاشير بياخد طلبك ويحطه على الشاشة ويخدم اللي بعدك فورًا. المطبخ بيشتغل على الطلبات بالترتيب. لو جه 50 زبون مرة واحدة، الطابور بيطوّل بس محدش بيترفض.
Retry لو المهمة فشلت، حاول تاني (3 مرات مثلًا)
Backoff استنّى بين المحاولات: 5 ثواني، 10، 20…
Dead Letter فشلت نهائيًا؟ حطها في طابور "المراجعة"
⚠️ الأهم — Idempotent: المهمة ممكن تتنفّذ مرتين بالغلط (فشلت في النص واتعادت). لازم التكرار ميعملش ضرر: الإيميل يتبعت مرة، الفلوس تتخصم مرة. الحل: رقم فريد لكل عملية، لو اتنفّذ قبل كده — تجاهل.
التزامن Concurrency إزاي سيرفر واحد يخدم ناس كتير في نفس اللحظة
1
الفكرة
أغلب وقت السيرفر بيكون مستنّي: مستنّي قاعدة البيانات ترد، مستنّي الشبكة. بدل ما يقف ساكت، بيشتغل على طلب تاني لحد ما الأول يرجع.
تشبيه 👨🍳
شيف واحد و5 حلل: يحط الأولى على النار ويسيبها، يقلّب التانية، يملّح التالتة… وبيرجع للأولى لما تغلي. ده Concurrency: مش بيعمل الـ 5 حاجات في نفس اللحظة، بس مش بيضيّع وقت في الانتظار. وParallelism = 5 شيفات فعلًا.
نوع الشغل
الحل
انتظار (قاعدة بيانات، شبكة)
async/await — شيف واحد كفاية
حسابات تقيلة (معالجة فيديو)
أكتر من Worker — شيفات كتير
2
أخطر مشكلة: Race Condition
السيناريو: رصيدك 100 جنيه. بعت طلبين سحب 100 في نفس اللحظة من جهازين.
الطلب 1: الرصيد 100؟ أيوه ✓
الطلب 2: الرصيد 100؟ أيوه ✓
الطلب 1: اخصم → 0
الطلب 2: اخصم → -100 😱
الحل: خلّي الفحص والخصم خطوة واحدة متتقطعش:
1UPDATE accounts
2SET balance = balance - 1003WHERE id = 7AND balance >= 100;
4-- لو الشرط فشل، مفيش خصم
تشبيه 🚻
قفل باب الحمام: أول واحد يدخل يقفل، التاني يستنّى. من غير القفل الاتنين يدخلوا مع بعض — كارثة.
Deadlock — التعليق الأبدي: مهمة A ماسكة المفتاح 1 ومستنية المفتاح 2. مهمة B ماسكة 2 ومستنية 1. الاتنين واقفين للأبد. زي اتنين في ممر ضيق كل واحد مستنّي التاني يعدّي. الحل: دايمًا خد المفاتيح بنفس الترتيب، وحط مهلة (timeout) لأي انتظار.
?
لو المستخدم دوس "ادفع" مرتين بالغلط… هيتخصم مرتين؟
14/25→
?
لو العملية اتكرّرت بالغلط؟ Idempotency أهم فكرة في الأنظمة الموزّعة — وأكتر سؤال بيتسأل
المستخدم دوس "ادفع"، النت قطع قبل ما الرد يوصله، فدوس تاني. هل هيتخصم منه مرتين؟ لو نظامك مش مستعد للسيناريو ده — أيوه.
1
المشكلة
المستخدم: ادفع 100
↓
السيرفر: خصم 100 ✓
↓
الرد ضاع في الطريق ❌
↓
المستخدم: ادفع 100 (تاني)
↓
السيرفر: خصم 100 ✓ — اتخصم 200! 😱
نفس الحاجة بتحصل مع الطوابير: المهمة فشلت في النص واتعادت — فالإيميل اتبعت مرتين، أو الطلب اتعمل مرتين.
2
الحل: مفتاح فريد لكل عملية
التطبيق بيبعت مع كل عملية رقم فريد (Idempotency Key). السيرفر بيحفظه. لو جاله نفس الرقم تاني → يرجّع نفس الرد القديم من غير ما ينفّذ.
ادفع 100 · key: abc-123
↓
السيرفر: الـ key جديد؟ أيوه → نفّذ واحفظ
↓
ادفع 100 · key: abc-123 (تاني)
↓
السيرفر: شفت الـ key ده! → رجّع الرد القديم ✓
تشبيه 🎟️
تذكرة السينما: عليها رقم. دخلت بيها مرة، لو حاولت تدخل تاني بنفس الرقم الماكينة تقولك "اتستخدمت". مش هتاخد كرسيين.
3
قواعد عملية
GET و PUT و DELETE بطبيعتهم آمنين للتكرار. POST لأ — ده اللي محتاج المفتاح.
أي مهمة في طابور لازم تستحمل تتنفّذ مرتين: اتأكد "اتعملت قبل كده؟" قبل ما تنفّذ.
في قاعدة البيانات: استخدم Unique constraint على رقم العملية — لو اتكرّر، القاعدة نفسها هترفض.
Retry من غير Idempotency = كارثة. الاتنين لازم مع بعض.
الخدمات بقت كتير… مين الباب الموحّد اللي الكل يدخل منه؟
15/25→
?
API Gateway — الباب الموحّد نقطة دخول واحدة لكل الطلبات
لما النظام بيكبر وبيبقى فيه خدمات كتير، بدل ما كل تطبيق يكلّم كل خدمة لوحدها، بنحط باب واحد قدام الكل. الباب ده بيتأكد منك ويوجّهك.
1
الفكرة في رسمة
موبايل
متصفح
→
API Gateway مين إنت؟ مش بتبعت كتير؟ رايح فين؟
→
خدمة المستخدمين
خدمة الطلبات
خدمة الدفع
تشبيه 🏢
ريسبشن الشركة: أي زائر بيعدّي عليه الأول. بيتأكد من هويته، يديله بادج، يقوله الدور كام، ويسجّل دخوله. الموظفين جوه مش محتاجين يعملوا كل ده مع كل زائر.
2
بيعمل إيه؟
المهمة
بالبلدي
Routing
يوجّه كل طلب للخدمة الصح
Auth
يتأكد مين إنت مرة واحدة للكل
Rate Limiting
يمنع اللي بيبعت طلبات أكتر من اللازم
Load Balancing
يوزّع الطلبات على نسخ الخدمة
Caching
يحفظ الردود المتكررة
Logging
يسجّل كل حاجة بتعدّي
أمثلة:Nginx · Kong · AWS API Gateway
3
Rate Limiting — ليه مهم؟
لو حد كتب سكريبت يبعت 10,000 طلب في الثانية، السيرفر هيقع وكل الناس هتتأذى. فبنحدد: "كل مستخدم 100 طلب في الدقيقة بس".
تشبيه 🪣
جردل الكوبونات: معاك جردل فيه 100 كوبون، وبيتملى 10 كل ثانية. كل طلب بياخد كوبون. الجردل فضي؟ ترجع بـ 429 Too Many Requests وتستنّى شوية.
Load Balancing — التوزيع:
الطلبات
→
الموزّع
→
سيرفر 1
سيرفر 2
سيرفر 3
أبسط طريقة: بالدور (Round Robin). أذكى: الأقل انشغالًا.
?
المستخدمين زادوا 100 ضعف… النظام يستحمل إزاي؟
16/25→
?
التوسّع Scaling لما المستخدمين يزيدوا، النظام يكبر معاهم من غير ما يقع
1
طريقتين للتكبير
رأسي ⬆️
4GB
↓
32GB
كبّر الماكينة نفسها. سهل بس ليه سقف وغالي.
أفقي ➡️
S1
S2
S3
موزّع
زوّد ماكينات. مفيش سقف، ولو واحدة وقعت الباقي شغّال.
تشبيه 🚚
رأسي = تشتري شاحنة أكبر. أفقي = تشتري شاحنات أكتر. الشاحنة الأكبر ليها حد، بس 100 شاحنة صغيرة تشيل أي حاجة — ولو واحدة عطلت الباقي ماشي.
2
شرط التوسّع الأفقي: Stateless
عشان أي سيرفر يقدر يخدم أي طلب، مينفعش السيرفر يفتكر حاجة عنك. بياناتك (الجلسة، السلة) تبقى في مكان مشترك (Redis / قاعدة بيانات)، مش في ذاكرة سيرفر معيّن.
تشبيه 🏧
ماكينة ATM: أي ماكينة في أي فرع تخدمك لأن رصيدك محفوظ في البنك مش في الماكينة. لو السيرفر "فاكرك" (Stateful)، لازم ترجع لنفس السيرفر كل مرة — ولو وقع، ضعت.
Auto Scaling: زوّد السيرفرات تلقائيًا لما الضغط يزيد، وقلّلهم لما يهدى.
راقب CPU
→
زاد عن 70%؟
→
زوّد سيرفر
هدى؟
→
قلّل
?
والسيرفر لو وقع؟ إزاي النظام يفضل شغّال؟
17/25→
?
النظام ميقعش High Availability التكرار · الفحص الصحي · توسيع قاعدة البيانات
1
الفكرة: مفيش حاجة واحدة بس
لو عندك سيرفر واحد ووقع، الموقع كله وقع. الحل: أكتر من نسخة من كل حاجة، وحد بيراقبهم.
الموزّع بيسأل: عايش؟
→
سيرفر 1 ✅
سيرفر 2 ❌ وقع
سيرفر 3 ✅
→
سيرفر جديد بيتعمل تلقائي
تشبيه 🏥
الإسعاف: مش عربية واحدة، كذا عربية. ولو واحدة عطلت، المركز بيعرف فورًا ويبعت غيرها. 99.9% توافر = الموقع يقع 8 ساعات بس في السنة كلها.
2
قاعدة البيانات لما تبقى هي المشكلة
نسخ للقراءة
التطبيق
→
الأساسية الكتابة
نسخة قراءة
نسخة قراءة
أغلب التطبيقات بتقرأ أكتر ما بتكتب بكتير. فنعمل نسخ للقراءة، والكتابة على الأساسية بس.
تقسيم (Sharding)
لما البيانات نفسها تبقى أضخم من ماكينة واحدة: المستخدمين أ–ح في قاعدة، خ–ع في تانية… معقّد — آخر حل.
الترتيب الصح لما قاعدة البيانات تبطّأ: ① Index وحسّن الاستعلامات ② كاش ③ نسخ للقراءة ④ تقسيم. متقفزش للآخر — 90% من المشاكل بتتحل بالخطوة 1 و2.
?
التطبيق كبر جدًا… نقسّمه لخدمات صغيرة؟
18/25→
?
الخدمات الصغيرة Microservices تطبيق واحد كبير ولا خدمات صغيرة مستقلة؟
1
Monolith — القطعة الواحدة
الواجهة
المنطق
البيانات
→
قاعدة بيانات واحدة
كود واحد، تطبيق واحد. كل حاجة مع بعض.
سهل تبدأ وتنشر
مناسب للصغير والمتوسط
لما يكبر بيصعب التعديل
غلطة واحدة توقّع الكل
2
Microservices — خدمات مستقلة
الباب
→
المستخدمين + قاعدتها
الطلبات + قاعدتها
الدفع + قاعدتها
كل جزء خدمة لوحدها، بكودها وقاعدتها، وبتتنشر لوحدها.
كل خدمة تكبر وتتصلّح لوحدها
فرق كتير تشتغل بالتوازي
معقّد (شبكة، مراقبة)
مش للبداية
تشبيه 🏠
Monolith = فيلا: كل حاجة تحت سقف واحد، سهلة في الأول، بس لو عايز توسّع المطبخ لازم تهدّ حيطان. Microservices = كومباوند: كل وحدة مستقلة، أي واحدة تتعدّل من غير ما تأثر على التانية، بس محتاج طرق وأمن وإدارة.
النصيحة: ابدأ بفيلا منظّمة (Monolith مقسوم لأجزاء واضحة جوه). لما الفريق يكبر وتظهر حدود واضحة، فكّك الأجزاء اللي محتاجة تكبر لوحدها. Microservices من اليوم الأول = تعقيد من غير سبب.
?
طيب الخدمات دي بتكلّم بعض إزاي؟ ولو واحدة فشلت في النص؟
19/25→
?
الخدمات بتكلّم بعض إزاي؟ مباشر · عبر طابور · بالأحداث · والتراجع لو فشل
1
3 طرق
الطريقة
إمتى
مثال
مباشر (REST)
محتاج الرد فورًا
"هات سعر المنتج"
عبر طابور
مهمة خلفية مش مستعجلة
"ابعت إيميل"
بالأحداث
الخدمة تقول "حصل كذا" ومش بتعرف مين سامع
"طلب جديد اتعمل!"
بالأحداث — الأقوى في الأنظمة الكبيرة:
خدمة الطلبات "طلب جديد!"
→
Event Bus
→
المخزن يقلّل الكمية
الإشعارات يبعت رسالة
التحليلات يسجّل
تشبيه 📢
زي الميكروفون في المدرسة: المدير بيقول "الحصة خلصت" مرة واحدة، وكل فصل بيتصرف. مش محتاج يروح لكل فصل لوحده. ولو فصل جديد اتفتح، بيسمع من غير ما المدير يعمل حاجة.
2
المشكلة الكبرى: فشل في النص
طلب شراء = احجز المنتج (خدمة 1) + اخصم الفلوس (خدمة 2). لو التانية فشلت، الأولى لازم تتراجع. مفيش Transaction واحدة تغطي الاتنين.
الحل (Saga): كل خطوة ليها خطوة تراجع:
احجز المنتج ✓
→
اخصم الفلوس ✓
→
اشحن ❌ فشل
↓ التراجع بالعكس
رجّع الفلوس تراجع 2
→
فكّ الحجز تراجع 1
→
الطلب اتلغى
تشبيه ✈️
حجزت طيارة ✅ وفندق ✅ والعربية ❌ فشلت. مفيش "إلغاء الكل" سحري — لازم إنت ترجع تلغي الفندق وبعدين الطيارة، واحدة واحدة بالعكس.
"شغّال على جهازي" مش كفاية. في الإنتاج فيه مستخدمين حقيقيين وأعطال مفاجئة. لازم تشوف إيه اللي بيحصل جوه النظام في كل لحظة.
1
تشوف بإيه؟ — 3 عيون
العين
بتقولك إيه
أداة شهيرة
السجلات — Logs
إيه اللي حصل بالظبط؟ (كل حدث مكتوب)
ELK
الأرقام — Metrics
النظام صحته إيه؟ (CPU، عدد الطلبات، الأخطاء)
Prometheus + Grafana
التتبّع — Traces
الطلب عدّى على إيه وفين بطّأ؟
Jaeger
التنبيه — Alerts
حصلت مشكلة؟ صحّي حد
PagerDuty
تشبيه 🚗
الفرق بين عربية في الجراج وعربية على الطريق السريع: الثانية محتاجة عدّاد سرعة (Metrics)، لمبات تحذير (Alerts)، كاميرا تسجيل (Logs)، وإطار احتياطي (نسخة ثانية).
2
أرقام تراقبها
المقياس
الهدف
وقت الرد (p95)
أقل من 300ms
نسبة الأخطاء
أقل من 1%
CPU / الذاكرة
أقل من 70%
نسبة إصابة الكاش
أكتر من 80%
ليه p95 مش المتوسط؟ لو 95% من الطلبات 100ms و5% 10 ثواني — المتوسط يبان كويس، بس 5% من الناس بيعانوا. p95 بيقولك "أسوأ 5% بيشوفوا إيه".
3
الفحص الصحي والنشر
الموزّع
→
/health عايش؟
→
200 OK
الموزّع بيسأل كل سيرفر كل شوية "عايش؟". اللي ميردش بيتشال من الدور ويتعمل مكانه واحد جديد.
طريقة النشر
الفكرة
Rolling
بدّل السيرفرات واحد واحد — مفيش توقف
Blue-Green
نسختين، حوّل بينهم — رجوع فوري
Canary
انشر لـ 5% الأول — لو تمام كمّل
مشاكل شائعة وحلّها: بطء → Index أو كاش · أخطاء كتير → خدمة خارجية واقعة، حط Retry وTimeout · الذاكرة بتخلص → Memory leak · ضغط مفاجئ → Auto scaling وRate limit
?
وإزاي الكود بيوصل للسيرفر ويتحدّث من غير ما يقع؟
21/25→
?
التشغيل والنشر Docker · Kubernetes · CI/CD — بالبلدي
كتبت الكود وجرّبته على جهازك. دلوقتي عايز تشغّله على 50 سيرفر وتحدّثه 10 مرات في اليوم من غير ما يقع. الأدوات دي بتعمل ده.
1
Docker — الكود في علبة
المشكلة القديمة: "شغّال على جهازي بس مش شغّال على السيرفر!" — لأن الإصدارات مختلفة.
Docker بيحط الكود وكل اللي محتاجه (اللغة، المكتبات، الإعدادات) في علبة واحدة (Container) بتشتغل بنفس الشكل في أي مكان.
كودك
+
اللغة والمكتبات
=
Container بيشتغل في أي مكان
تشبيه 🍱
علبة الأكل الجاهزة: الأكل والملعقة والصوص كله جوه. تفتحها في البيت أو الشغل أو القطر — نفس الوجبة بالظبط.
2
Kubernetes — مدير العلب
عندك 200 علبة (Container) على 50 سيرفر. مين بيوزّعهم؟ مين بيعيد تشغيل اللي وقع؟ مين بيزوّد لما الضغط يزيد؟ Kubernetes (K8s).
بيوزّع العلب على السيرفرات
علبة وقعت؟ بيعمل غيرها تلقائي
ضغط زاد؟ بيزوّد علب
تحديث؟ بيبدّلهم واحدة واحدة من غير توقف
تشبيه 🚢
ميناء الحاويات: الرافعات بتحط الحاويات على السفن، ولو سفينة اتأخرت بتحوّل على غيرها. الكابتن (Kubernetes) بيدير الكل من برج المراقبة.
3
CI/CD — من الكود للمستخدم تلقائي
كتبت كود git push
→
اختبار تلقائي CI
→
بناء العلبة Docker
→
نشر CD
→
المستخدم شاف التحديث
CI (Continuous Integration) = كل ما تحفظ كود، الاختبارات بتتشغّل لوحدها. غلط؟ بتعرف فورًا قبل ما يوصل للناس.
CD (Continuous Deployment) = لو الاختبارات نجحت، الكود بيتنشر لوحده. شركات كبيرة بتنشر مئات المرات في اليوم.
طريقة النشر
الفكرة
Rolling
بدّل السيرفرات واحد واحد — مفيش توقف
Blue-Green
نسختين، حوّل بينهم — لو مشكلة ارجع فورًا
Canary
انشر لـ 5% من الناس الأول — تمام؟ كمّل للباقي
?
جاهز للمقابلة؟ أسلوب الإجابة على "صمّم نظام"
22/25→
?
سؤال المقابلة الأشهر: "صمّم لي نظام" إزاي تجاوب بثقة حتى لو مش عارف كل حاجة
1
الخطوات بالترتيب — متقفزش
① اسأل قبل ما ترسم: النظام بيعمل إيه بالظبط؟ كام مستخدم؟ بيقرأوا أكتر ولا بيكتبوا؟ (المقابِل بيحب الأسئلة دي)
② ارسم الصورة الكبيرة:Client → Gateway → خدمات → قاعدة بيانات. الصناديق اللي في الكتاب ده.
③ ادخل في التفاصيل: العناوين (API)، شكل الجداول، فين الكاش، فين الطابور.
④ اتكلم عن اللي ممكن يبوظ: لو السيرفر وقع؟ لو الضغط زاد 10 مرات؟ لو حد حاول يخترق؟
⑤ قول "اخترت X بدل Y لأن…": مفيش إجابة واحدة صح. المهم تبرّر.
تشبيه 🏗️
زي المهندس المعماري: مش بيرسم الفيلا قبل ما يسأل: كام فرد؟ ميزانية؟ أرض قد إيه؟ لو رسمت على طول هتبقى غلط مهما كانت حلوة.
?
يلا نطبّق على مثالين حقيقيين
23/25→
?
مثالين من المقابلات مختصر روابط · تطبيق شات
1
مثال: صمّم مختصر روابط (bit.ly)
المطلوب: ياخد رابط طويل ويرجّع قصير، ولما حد يفتح القصير يروح للطويل. ملاحظة مهمة: الناس بتفتح الروابط أكتر بكتير ما بتعملها.
المستخدم
→
الموزّع
→
سيرفر
سيرفر
→
كاش الروابط المشهورة
قاعدة بيانات قصير → طويل
كود قصير فريد: رقم تسلسلي محوّل لحروف (abc123)
كاش للمشهورة — لأن القراءة ثقيلة
الإحصائيات (مين فتح من فين) في طابور عشان متأخّرش الفتح
Rate limit ضد الـ Spam
2
مثال: صمّم تطبيق شات
المطلوب: رسائل فورية، تعرف مين أونلاين، إشعارات. الفرق المهم: السيرفر لازم يبعت لك الرسالة من نفسه — مش تستنّى تسأل.
أحمد
⇄
سيرفر الشات اتصال مفتوح
⇄
سارة
WebSocket: اتصال مفتوح دايم بدل طلب/رد
طابور بين سيرفرات الشات عشان أحمد على سيرفر 1 وسارة على سيرفر 2
قاعدة بيانات تستحمل كتابة ضخمة للرسائل (Cassandra)
Redis لمين أونلاين
تحدي للنقاش: لو سارة offline؟ → احفظ الرسالة وابعت إشعار من طابور.
?
خلّصت الكتاب! الخلاصة واختبر نفسك
24/25→
?
مبروك! الصورة الكبيرة بقت واضحة كل اللي اتعلمته في رسمة واحدة + اختبر نفسك
1
رحلة الطلب في نظام حقيقي
التطبيق
→
الموزّع
→
الباب Gateway
→
نقاط التفتيش Middleware
→
الكود
→
كاش
قاعدة بيانات
طابور
وفوق كل ده: سجلات وأرقام وتنبيهات — عشان تعرف إيه اللي بيحصل في كل لحظة
2
اختبر نفسك ✍️
1. ليه HTTP "مش بيفتكر" وإيه الحل؟
2. الفرق بين Authentication وAuthorization؟
3. الـ Index بيسرّع إيه وبيبطّأ إيه؟
4. إمتى تستخدم كاش وإمتى لأ؟
5. ليه المهمة في الطابور لازم تستحمل تتنفّذ مرتين؟
6. رأسي ولا أفقي — وليه "Stateless" مهم؟
7. إمتى تبدأ بـ Microservices؟
8. ليه p95 أهم من المتوسط؟
الإجابات: 1) كل طلب مستقل → توكن مع كل طلب · 2) مين إنت / مسموح لك بإيه · 3) القراءة ↑ الكتابة ↓ · 4) بيتقرأ كتير وبيتغيّر قليل / مش للرصيد البنكي · 5) ممكن تتعاد بعد فشل · 6) أفقي بلا سقف، وأي سيرفر يخدم أي طلب · 7) مش من الأول — لما تكبر فعلًا · 8) بيكشف أسوأ 5%
3
الخطوة الجاية 🗺️
① ابني مشروع: API + تسجيل دخول + قاعدة بيانات + كاش + طابور لإيميل. ده بيغطي 70% من الكتاب.
② انشره على سيرفر حقيقي وحط فحص صحي وسجلات.
③ اضغط عليه (Load test) وشوف فين بيقع — وصلّحه بالكاش والـ Index.
④ تدرّب على "صمّم نظام" بصوت عالي: 30 دقيقة على كل مثال.
الأهم: المفاهيم دي بتتثبّت بالتطبيق مش بالقراءة. كل فكرة جرّبتها بإيدك مرة = بقت بتاعتك.