Files
intaleq/docs/01_overview/server_architecture_feedback.md
T
Hamza-AyedandClaude Opus 5 92dc6b3641 chore: استيراد أولي من سيرو (ecfe7568) — بلا أي تعديل
نسخة كاملة من مستودع سيرو عند ecfe7568 لتكون أساس تطبيق «انطلق».
نُسخ المتعقَّب في git فقط (12,509 ملفاً / 302 م.ب) بـ git archive، لا
`cp -r` — فاستُثنيت تلقائياً مخلفات البناء (build · node_modules ·
.dart_tool · .gradle · Pods ≈ 10.7 غ.ب) وكل ما يستثنيه .gitignore.

هذا الكوميت **بلا أي تعديل عمداً** حتى يكون كل ما يليه فرقاً مقروءاً
مقابل سيرو الأصلي. سيرو نفسه لم يُمسّ.

⚠️ لا يبني بعد: `.env` و`lib/env/env.g.dart` غير متعقَّبين في سيرو (وهذا
صحيح — أسرار لكل مستأجر). كل تطبيق فلاتر هنا يحتاج .env خاصاً بانطلق ثم
توليد env.g.dart عبر build_runner. لا تُنسخ أسرار سيرو.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-27 05:10:29 +03:00

21 KiB
Raw Blame History

تقرير التدقيق وتصميم بنية سيرفرات منصة Siro (نسخة محدثة ونهائية)

بناءً على التوضيح الدقيق للهيكلية الفعلية المعتمدة للمنظومة، يهدف هذا التقرير إلى تقديم تفصيل كامل للمكونات، ورسم طوبولوجيا الشبكة المطابقة للواقع، وحل مشكلة اتصال وتزامن خوادم الـ WebSockets مع خوادم الباك إند والعملاء.


أولاً: الهيكلية المعتمدة للنظام (Actual Architecture Topology)

تتكون المنظومة من المكونات الأساسية التالية وتوزيعها كالتالي:

  1. موزع الأحمال (Load Balancer): يقع في المقدمة لتلقي طلبات الـ API (HTTP/HTTPS) فقط وتوزيعها على خادمين.
  2. خوادم الـ API (Web Server A & B): خوادم Stateless تستقبل الطلبات وتقوم بالمعالجة وحفظ الملفات، وتتصل بكل من قاعدة البيانات وذاكرة Redis المؤقتة.
  3. قاعدة البيانات الرئيسية (MySQL Master): تحتوي على البيانات الأساسية ولها خادمان تابعان:
    • نسخة مطابقة (Replica): للمزامنة الحية وتخفيف ضغط القراءة.
    • نسخة نسخ احتياطي (Dump Server): لأخذ النسخ الاحتياطية الدورية دون التأثير على الأداء.
  4. خوادم الـ Redis: تعمل كطبقة كاش ذكية أولى/ثانية أمام قاعدة البيانات لحفظ الجلسات، التحقق، ومعدل الطلبات، ولها خادم احتياطي (Replica).
  5. خوادم الـ WebSockets المنفصلة:
    • سيرفر الموقع الجغرافي (Location Server): خادم مستقل يستقبل إحداثيات GPS حية من تطبيق السائق.
    • سيرفر الرحلات (Ride/Passenger Server): خادم مستقل يدير قنوات الاتصال الحي بين الراكب والسائق أثناء الرحلة.
    • ملاحظة: تطبيق الفلاتر (الراكب والسائق) يتصل مباشرة بهذين السيرفرين عبر بروتوكول WS/WSS.

ثانياً: حل معضلة اتصال الـ WebSockets (The WebSocket Integration Solution)

Important

السؤال الأساسي: كيف تتواصل خوادم الباك إند (Web Server A & B) مع خوادم الـ Sockets المنفصلة وتزامن حالة الرحلة؟

بما أن خوادم الباك إند معزولة خلف موزع الأحمال، وتطبيقات الموبايل متصلة مباشرة بخوادم الـ Sockets، فإن أفضل طريقة تشغيلية ومعمارية للربط هي استخدام Redis Pub/Sub (نظام النشر والاشتراك) كجسر تواصل سريع جداً (Event Bus):

sequenceDiagram
    autonumber
    actor Driver as تطبيق السائق
    participant WebAPI as خادم الباك إند (A أو B)
    participant Redis as Redis Pub/Sub
    participant RideSocket as سيرفر الـ Sockets (Ride)
    actor Rider as تطبيق الراكب

    Driver->>WebAPI: 1. قبول الرحلة (طلب API)
    WebAPI->>WebAPI: 2. معالجة الطلب وحفظ الحالة بقاعدة البيانات
    WebAPI->>Redis: 3. نشر حدث (Publish) -> "قبول_رحلة" لقناة Redis
    Note over Redis: الحدث يحتوي على معرف الرحلة والراكب
    Redis-->>RideSocket: 4. استلام الحدث فوراً (Subscription)
    RideSocket->>Rider: 5. دفع تنبيه حقيقي (WebSocket Push) -> "السائق قبل رحلتك"

مزايا هذا الحل:

  • Stateless API: تبقى خوادم الباك إند خفيفة ولا تحتاج لمعرفة من متصل بأي سيرفر سوكت.
  • تزامن فوري: تتم عملية النشر والاستلام عبر الـ Redis في أجزاء من الميلي ثانية.
  • فصل كامل للمسؤولية: خوادم السوكت تركز فقط على الحفاظ على الاتصالات المفتوحة وإرسال البيانات، بينما خوادم الباك إند تركز على منطق العمل وحساب الأسعار.

ثالثاً: مخطط طوبولوجيا الشبكة المقترح (Network Topology Diagram)

يوضح المخطط التالي العلاقة التفاعلية ومسارات اتصال تطبيقات الموبايل بالمنظومة:

graph TD
    %% Clients
    Rider([تطبيق الراكب])
    Driver([تطبيق السائق])
    
    %% API Routing
    Rider -.->|1. API Requests HTTPS| LB[Load Balancer]
    Driver -.->|1. API Requests HTTPS| LB
    
    LB --> WebA[Web Server A]
    LB --> WebB[Web Server B]
    
    %% Direct Web Sockets Connection
    Rider ==>|2. WebSocket WSS| RideSocket[Ride/Passenger Server]
    Driver ==>|2. Live Location WSS| LocationSocket[Location Server]
    
    %% Shared Storage for Uploads
    WebA -->|Uploads| SharedStorage[(Shared Storage / NFS)]
    WebB -->|Uploads| SharedStorage
    
    %% Caching & PubSub Bridge
    WebA --> RedisMaster[Redis Master]
    WebB --> RedisMaster
    RideSocket --> RedisMaster
    LocationSocket --> RedisMaster
    RedisMaster -->|Replication| RedisReplica[Redis Replica]
    
    %% Databases
    WebA --> DBMaster[(MySQL Master DB)]
    WebB --> DBMaster
    LocationSocket -.->|Save Trackings| DBMaster
    RideSocket -.->|Save Ride States| DBMaster
    
    %% DB Backup & Replication
    DBMaster -->|Streaming| DBReplica[(MySQL Replica DB)]
    DBMaster -->|Dumps| DBBackup[(MySQL Dump Server)]

رابعاً: معالجة البيانات والتخزين المؤقت (Redis Caching Strategy)

  • البيانات المخزنة في Redis: الجلسات النشطة (Sessions)، التوكنات المؤقتة للتحقق (OTP & JWT)، معدل الطلبات (Rate Limiting)، والبيانات الجغرافية المؤقتة للسائقين القريبين.
  • البيانات في MySQL: بيانات المستخدمين، تفاصيل الرحلات، الحسابات المالية، سجلات الحظر والوثائق.
  • عند طلب بيانات معينة (مثل الملف الشخصي)، يفحص السيرفر الـ Redis أولاً؛ إن لم يجدها (Cache Miss) يقرأها من MySQL Master/Replica ويخزنها في Redis لمرة ثانية لتسريع الطلبات القادمة.

خامساً: خطة الشراء واختيار السيرفرات (Hosting & Sizing Recommendations)

بناءً على عروض الاستضافة المتاحة من شركتي Netcup و Contabo، تم تصميم خطة الشراء التالية لتوفر أفضل أداء مقابل السعر مع تحقيق توازن كامل للمنظومة:

١. مبررات اختيار الشركات لكل خدمة:

  • سيرفرات قواعد البيانات والـ Sockets والـ Redis (اختيار Netcup): قواعد البيانات والاتصالات الحية تحتاج إلى استقرار كامل للـ CPU ونوعية رام مدعومة بكشف الأخطاء وتصحيحها (ECC DDR5 RAM)، بالإضافة إلى سرعة قراءة وكتابة فائقة للأقراص (NVMe SSD)، وهو ما تتفوق فيه Netcup بشكل قطعي.
  • سيرفرات الـ API المستقلة وسيرفر الخرائط (اختيار Contabo): خوادم الـ API هي Stateless وتتطلب سعة ذاكرة رام عالية وأنوية معالجة بتكلفة اقتصادية لتوزيع الأحمال. كما أن سيرفر الخرائط يحتاج لمساحة ديسك ضخمة ورام كبيرة جداً لتحميل ملفات الـ PBF والـ Tiles، وتوفر Contabo أحجام رام ضخمة بأسعار منافسة جداً.

٢. جدول توزيع المشتريات ومواصفات السيرفرات (١٢ سيرفر):

# السيرفر ووظيفته المواصفات المطلوبة الشركة والخطة المقترحة التكلفة (€/شهر) التكلفة ($/شهر) نوع القرص والتخزين
1 موزع الأحمال (Load Balancer) 2GB RAM / 2 Cores Netcup: VPS nano G11s €2.58 $2.92 60 GB SSD
2 خادم الـ API الأول (Web Server A) 8GB RAM / 4 Cores Contabo: Cloud VPS 10 €4.40 $4.97 75 GB NVMe
3 خادم الـ API الثاني (Web Server B) 8GB RAM / 4 Cores Contabo: Cloud VPS 10 €4.40 $4.97 75 GB NVMe
4 قاعدة البيانات الرئيسية (MySQL Master) 32GB RAM / 12 Cores Netcup: VPS 4000 G12 €27.00 $30.51 1 TB NVMe
5 قاعدة البيانات الاحتياطية (MySQL Replica) 16GB RAM / 8 Cores Netcup: VPS 2000 G12 €16.17 $18.27 512 GB NVMe
6 سيرفر النسخ الاحتياطي (Dump DB) 4GB RAM / 2 Cores Netcup: VPS 500 G12 €4.96 $5.61 128 GB NVMe
7 ذاكرة Redis الرئيسية (Redis Master) 2GB RAM / 2 Cores Netcup: VPS nano G11s €2.58 $2.92 60 GB SSD
8 ذاكرة Redis الاحتياطية (Redis Replica) 2GB RAM / 2 Cores Netcup: VPS nano G11s €2.58 $2.92 60 GB SSD
9 سيرفر تتبع المواقع الحية (Location Server) 4GB RAM / 2 Cores Netcup: VPS 500 G12 €4.96 $5.61 128 GB NVMe
10 سيرفر حالة الرحلات (Passenger Socket) 2GB RAM / 2 Cores Netcup: VPS nano G11s €2.58 $2.92 60 GB SSD
11 سيرفر المدفوعات المستقل (Payments) 2GB RAM / 2 Cores Netcup: VPS nano G11s €2.58 $2.92 60 GB SSD
12 سيرفر الخرائط المخصص (SiroMaps) 64GB RAM / 16 Cores Contabo: Cloud VPS 50 €29.60 $33.45 300 GB NVMe

٣. ملخص التكلفة الشهرية الإجمالية:

البند التكلفة باليورو (€) التكلفة بالدولار ($)
إجمالي سيرفرات Netcup (9 سيرفرات) €65.99 $74.58
إجمالي سيرفرات Contabo (3 سيرفرات) €38.40 $43.39
الإجمالي الكلي للمنظومة (12 سيرفر) €104.39 $117.97

Note

سعر الصرف المستخدم: 1 يورو = 1.13 دولار أمريكي (تقريبي). الأسعار المذكورة هي أسعار الاشتراك الشهري فقط ولا تشمل رسوم الإعداد (Setup Fee) إن وجدت.


سادساً: تقييم الأداء — كم تستوعب هذه المنظومة؟ (Capacity Estimation)

Important

الجواب المختصر: هذه البنية كافية ومتينة جداً لمنصة نقل ركاب بحجم سوق سوريا ومصر في مراحل التشغيل والنمو الأولى والمتوسطة.

تقدير السعة حسب كل مكوّن:

المكوّن السعة التقديرية القصوى الشرح والمبرر
خوادم الـ API (Web A + B) ~2,000 - 3,000 طلب HTTP متزامن كل سيرفر PHP-FPM بـ 8GB يخدم حوالي 1,000-1,500 طلب متزامن. مع سيرفرين خلف اللود بلانسر، تتضاعف السعة.
سيرفر الموقع الجغرافي (Location WebSocket) ~10,000 - 15,000 سائق متصل في نفس اللحظة Workerman على 4GB DDR5 يدير اتصالات خفيفة جداً (إحداثيات GPS كل 3 ثوانٍ). القيد هنا هو عدد الـ File Descriptors وليس الرام.
سيرفر الرحلات (Passenger Socket) ~5,000 - 8,000 راكب متصل في نفس اللحظة خفيف جداً كونه relay. كل اتصال يستهلك ~50KB رام فقط.
قاعدة البيانات الرئيسية (MySQL Master) ~5,000 - 8,000 استعلام في الثانية 32GB مع innodb_buffer_pool_size=22GB يخدم ملايين الصفوف بسرعة فائقة. مع الـ Replica يتضاعف أداء القراءة.
Redis Master ~100,000+ عملية في الثانية Redis على 2GB يخدم مئات آلاف العمليات/ثانية. حجم البيانات المخزنة (جلسات + كاش + GEO) لن يتجاوز 500MB في الذروة.
سيرفر الخرائط (SiroMaps) ~500 - 1,000 طلب توجيه/ثانية OSRM على 64GB رام يحمّل خريطة سوريا ومصر بالكامل في الذاكرة لسرعة فائقة.

تقدير السعة الإجمالية للمنصة:

المقياس السعة التقديرية
عدد المستخدمين المسجلين (ركاب + سائقين) حتى 500,000+ مستخدم مسجل
عدد السائقين المتصلين في نفس اللحظة (أوقات الذروة) حتى 10,000 - 15,000 سائق
عدد الركاب النشطين في نفس اللحظة حتى 5,000 - 8,000 راكب
عدد الرحلات اليومية حتى 20,000 - 40,000 رحلة/يوم
عدد الرحلات المتزامنة في نفس اللحظة حتى 1,500 - 3,000 رحلة نشطة

Tip

للمقارنة: تطبيقات نقل ركاب كبرى في المنطقة مثل "كريم" و"بولت" في مراحلها الأولى كانت تعمل بمنظومات أصغر من هذه. هذه البنية تكفي لتغطية سوريا ومصر بالكامل حتى الوصول لعشرات الآلاف من الرحلات اليومية.

عوامل تحدد متى تحتاج للترقية:

المؤشر القيمة الحدّية التي توجب الترقية
استخدام CPU لخوادم الـ API يتجاوز 75% بشكل مستمر لأكثر من ساعة
استخدام الرام لقاعدة البيانات يتجاوز 85% من الـ Buffer Pool
عدد اتصالات السوكت يتجاوز 80% من حد الـ File Descriptors
زمن استجابة الـ API يتجاوز 500 ميلي ثانية كمتوسط
حجم قاعدة بيانات التتبع (Tracking) يتجاوز 50GB بدون سياسة تنظيف (TTL)

سابعاً: الشبكة الداخلية (Private Network / VLAN) — هل هي ضرورية؟

Caution

الجواب القاطع: نعم، الشبكة الداخلية (VLAN) إلزامية وليست اختيارية في هذا التصميم. بدونها أنت تعرّض قاعدة البيانات وخادم Redis للإنترنت العام مباشرة، وهذه كارثة أمنية.

لماذا الشبكة الداخلية ضرورية؟

السبب التفصيل
١. الأمان (Security) قاعدة البيانات MySQL وخادم Redis يجب أن يكونا معزولين تماماً عن الإنترنت العام. لا يجب أن يملك أي شخص خارج المنظومة القدرة على الوصول إليهما. الشبكة الداخلية تجعل هذين الخادمين مرئيين فقط لخوادم الـ API والسوكت.
٢. الأداء (Performance) الاتصال عبر الشبكة الداخلية أسرع بكثير (latency أقل بـ 5-10 أضعاف) من الاتصال عبر الإنترنت العام. استعلامات قاعدة البيانات ستستجيب بـ 0.1ms بدلاً من 1-5ms.
٣. التكلفة (Cost) الترافيك عبر الشبكة الداخلية مجاني بالكامل ولا يُحسب من حصة الباندويث. بينما الترافيك العام يُحسب ويُكلّف.
٤. عزل الخدمات (Isolation) لو تم اختراق أحد خوادم الـ API (لا سمح الله)، لن يتمكن المهاجم من الوصول لقاعدة البيانات عبر الإنترنت العام لأنها ببساطة غير مرئية من الخارج.

كيف يتم التطبيق عملياً؟

graph TD
    subgraph PublicZone["المنطقة العامة (Public Zone)"]
        LB[Load Balancer]
        LocationSocket[Location Server]
        RideSocket[Ride Server]
    end

    subgraph PrivateVLAN["الشبكة الداخلية الخاصة (Private VLAN)"]
        WebA[Web Server A]
        WebB[Web Server B]
        RedisMaster[Redis Master]
        RedisReplica[Redis Replica]
        DBMaster[(MySQL Master)]
        DBReplica[(MySQL Replica)]
        DBBackup[(Dump Server)]
        Payments[Payments Server]
    end

    subgraph MapsZone["منطقة الخرائط (Maps Zone)"]
        Maps[SiroMaps Server]
    end

    Internet([الإنترنت]) -->|HTTPS| LB
    Internet -->|WSS| LocationSocket
    Internet -->|WSS| RideSocket
    
    LB -->|Private IP| WebA
    LB -->|Private IP| WebB
    
    WebA -->|Private IP| RedisMaster
    WebA -->|Private IP| DBMaster
    WebB -->|Private IP| RedisMaster
    WebB -->|Private IP| DBMaster
    
    LocationSocket -->|Private IP| RedisMaster
    RideSocket -->|Private IP| RedisMaster
    
    WebA -->|Private IP| Maps

التطبيق العملي لكل شركة:

الشركة طريقة إنشاء الشبكة الداخلية الملاحظة
Netcup من لوحة التحكم SCP → "vLAN" → إنشاء شبكة افتراضية وربط السيرفرات بها Netcup يوفر VLAN مجاني بين سيرفراتك في نفس مركز البيانات (Datacenter). اختر جميع سيرفرات Netcup في نفس الموقع الجغرافي (مثلاً Nürnberg).
Contabo من لوحة التحكم → "Private Networking" → إضافة السيرفرات لنفس الشبكة Contabo يوفر شبكة خاصة مجانية. اختر جميع سيرفرات Contabo في نفس الموقع (مثلاً EU-Germany).

الربط بين الشركتين (Netcup ↔ Contabo):

Warning

سيرفرات Netcup وسيرفرات Contabo في مراكز بيانات مختلفة فيزيائياً، لذلك لا يمكن وضعها في نفس الـ VLAN. الحل:

الطريقة التفصيل
WireGuard VPN Tunnel إنشاء نفق VPN مشفّر بين سيرفر من Netcup وسيرفر من Contabo. هذا يجعلها تتصرف كأنها في نفس الشبكة الداخلية مع تشفير كامل. زمن الاتصال بين مراكز بيانات ألمانيا ≈ 1-3ms فقط.
التطبيق: تثبيت WireGuard على موزع الأحمال (Netcup) وعلى خوادم الـ API (Contabo)، وإنشاء نفق بينهما. كل السيرفرات الأخرى تتصل عبر الشبكة الداخلية لشركتها.

قواعد الجدار الناري (Firewall Rules):

السيرفر المنافذ المفتوحة للإنترنت العام المنافذ المفتوحة فقط للشبكة الداخلية
موزع الأحمال 80, 443 (HTTP/HTTPS) —
سيرفر الموقع (Location) منفذ WSS المحدد —
سيرفر الرحلات (Ride) منفذ WSS المحدد —
Web Server A & B ❌ لا شيء 80, 443 (يستقبل فقط من LB)
MySQL Master & Replica ❌ لا شيء 3306 (فقط من Web + Sockets)
Redis Master & Replica ❌ لا شيء 6379 (فقط من Web + Sockets)
سيرفر المدفوعات ❌ لا شيء المنفذ المحدد (فقط من Web)
سيرفر الخرائط ❌ لا شيء 5000, 8080 (فقط من Web)

ثامناً: التقييم النهائي

Tip

الحكم العام: تصميم سليم ومتزن وجاهز للتنفيذ.

السؤال الإجابة
هل التنظيم سليم؟ نعم. فصل المسؤوليات واضح: API منفصل، DB منفصل، Sockets منفصل، Redis منفصل، Maps منفصل. كل مكوّن يمكن ترقيته أو استبداله بشكل مستقل دون التأثير على البقية.
هل الموارد كافية؟ نعم وزيادة. هذه البنية تخدم حتى 15,000 سائق و8,000 راكب متصلين في نفس اللحظة، و40,000 رحلة يومياً. أكبر من حاجة السوق السوري والمصري في المرحلة الحالية.
كم عدد السيرفرات؟ 12 سيرفر موزعة بين 9 سيرفرات Netcup و3 سيرفرات Contabo.
كم التكلفة الشهرية؟ €104.39 يورو = $117.97 دولار أمريكي شهرياً
هل نحتاج شبكة داخلية؟ إلزامية بشكل قاطع. بدونها قاعدة البيانات و Redis مكشوفان على الإنترنت. الشبكة الداخلية مجانية من كلا الشركتين، ويتم ربطهما ببعض عبر WireGuard VPN.