يقودك هذا الدرس الختامي خطوةً بخطوة عبر نشر طبقة ويب احترافية وعالية التوافر على AWS من الصفر باستخدام AWS CLI. تجمع البنية بين موازن تحميل التطبيقات (ALB)، ومجموعة التحجيم التلقائي (ASG)، وقاعدة بيانات RDS متعددة نطاقات التوافر — وهو النموذج المرجعي الثلاثي الطبقات الذي ستجده في كل حمل عمل جاد على AWS. بنهاية هذا الدرس ستمتلك بنية تصمد أمام فشل مثيل واحد، وفشل نطاق توافر كامل، والارتفاع المفاجئ في حركة المرور، دون أي تدخل يدوي، وستفهم السبب الدقيق وراء كل قرار معماري.
البنية المستهدفة
يوضح المخطط أدناه ما ستبنيه. تدخل حركة المرور عبر ALB (الشبكات الفرعية العامة، نطاقا توافر)، فتُوزَّع على مثيلات EC2 داخل ASG (شبكات فرعية خاصة، نطاقا توافر)، التي تتصل بعد ذلك بمجموعة RDS متعددة نطاقات التوافر (شبكات فرعية للبيانات، نطاقا توافر). لا يمكن الوصول إلى أي مثيل EC2 أو RDS مباشرةً من الإنترنت — فقط ALB هو الذي يكون عاماً.
ALB + ASG + RDS متعدد نطاقات التوافر: البنية الثلاثية الطبقات عالية التوافر. جميع موارد EC2 وRDS تعيش في الشبكات الفرعية الخاصة وشبكات البيانات؛ ALB فقط يكون موجهاً للإنترنت.
الخطوة 1 — VPC والشبكات الفرعية
يعمل كل شيء داخل VPC مخصص يضم ثلاثة طبقات من الشبكات الفرعية لكل نطاق توافر: عامة (ALB)، وخاصة (EC2)، وللبيانات (RDS). يمنحك الفصل بين طبقات الشبكات الفرعية تحكماً مستقلاً في مجموعات الأمان وقوائم NACL عند كل حد.
شبكات البيانات الفرعية لا تملك أي مسار نحو الإنترنت — حتى عبر NAT. مثيلات RDS في شبكات البيانات يمكن الوصول إليها فقط من الموارد الداخلية في VPC. هذا هو الوضع الأمني الصحيح: قاعدة بياناتك لن تكون على بُعد قاعدة أمان واحدة مُعدَّة بشكل خاطئ من الإنترنت.
الخطوة 2 — مجموعات الأمان
تطبق ثلاث مجموعات أمان مبدأ الحد الأدنى من الصلاحيات على مستوى الشبكة. كل مجموعة تفتح فقط المنفذ والمصدر الضروريين — ولا يُستخدم 0.0.0.0/0 أبداً إلا لمستمع ALB.
# مجموعة أمان ALB — تقبل HTTPS من الإنترنت (وHTTP لإعادة التوجيه)
ALB_SG=$(aws ec2 create-security-group \
--group-name ha-alb-sg --description "ALB inbound" \
--vpc-id $VPC_ID --query 'GroupId' --output text)
aws ec2 authorize-security-group-ingress --group-id $ALB_SG \
--ip-permissions \
IpProtocol=tcp,FromPort=443,ToPort=443,IpRanges=[{CidrIp=0.0.0.0/0}] \
IpProtocol=tcp,FromPort=80,ToPort=80,IpRanges=[{CidrIp=0.0.0.0/0}]
# مجموعة أمان EC2 — تقبل فقط من مجموعة ALB على المنفذ 8080
APP_SG=$(aws ec2 create-security-group \
--group-name ha-app-sg --description "App tier inbound" \
--vpc-id $VPC_ID --query 'GroupId' --output text)
aws ec2 authorize-security-group-ingress --group-id $APP_SG \
--protocol tcp --port 8080 --source-group $ALB_SG
# مجموعة أمان RDS — تقبل فقط من مجموعة EC2 على المنفذ 5432 (PostgreSQL)
DB_SG=$(aws ec2 create-security-group \
--group-name ha-db-sg --description "DB tier inbound" \
--vpc-id $VPC_ID --query 'GroupId' --output text)
aws ec2 authorize-security-group-ingress --group-id $DB_SG \
--protocol tcp --port 5432 --source-group $APP_SG
الخطوة 3 — RDS متعدد نطاقات التوافر
أنشئ مجموعة شبكات فرعية لقاعدة البيانات تغطي كلتا شبكتي البيانات الفرعيتين، ثم شغِّل مثيل PostgreSQL متعدد نطاقات التوافر. يوفر خيار --multi-az نسخة احتياطية متزامنة في نطاق التوافر الثاني. RDS يتولى تحديث DNS تلقائياً خلال 60-120 ثانية في حال تعطل المثيل الأساسي — يُعيد تطبيقك الاتصال بنفس اسم المضيف.
يحدد قالب الإطلاق المواصفات الدقيقة لكل مثيل ينشئه ASG. تُقلِّع بيانات المستخدم التطبيقَ عند التشغيل. مرِّر نقطة نهاية RDS عبر SSM Parameter Store — لا تُضمِّن الأسرار أبداً في قالب الإطلاق أو في AMI.
اضبط "HttpTokens": "required" في MetadataOptions لكل قالب إطلاق. يُلزم هذا باستخدام IMDSv2، مما يمنع هجمات SSRF من قراءة بيانات اعتماد المثيل عبر نقطة نهاية البيانات الوصفية — وهو ناقل هجوم معروف ضد أعباء عمل EC2.
الخطوة 5 — ALB ومجموعة الأهداف
أنشئ ALB موجهاً للإنترنت في كلتا الشبكتين العامتين. أرفق مجموعة أهداف مع مسار فحص الصحة — يسجل ASG المثيلات الجديدة تلقائياً في هذه المجموعة، ولا يوجِّه ALB حركة المرور إلا للمثيلات التي تجتاز فحص الصحة.
تستند ASG إلى قالب الإطلاق، وتمتد على كلتا الشبكتين الخاصتين، وتسجل المثيلات الجديدة في مجموعة الأهداف تلقائياً. استخدم سياسة تتبع الهدف على متوسط CPU: يضبط AWS حجم الأسطول تلقائياً للحفاظ على CPU عند المستوى المستهدف. اجمع هذا مع حد أدنى من مثيلين (واحد لكل نطاق توافر) لضمان التسامح مع أعطال نطاق التوافر في جميع الأوقات.
# إنشاء ASG (الحد الأدنى 2 / المطلوب 2 / الحد الأقصى 10)
aws autoscaling create-auto-scaling-group \
--auto-scaling-group-name ha-web-asg \
--launch-template "LaunchTemplateId=$LT_ID,Version=\$Latest" \
--min-size 2 \
--max-size 10 \
--desired-capacity 2 \
--vpc-zone-identifier "$PRIV_A,$PRIV_B" \
--target-group-arns $TG_ARN \
--health-check-type ELB \
--health-check-grace-period 120 \
--default-instance-warmup 60 \
--tags "Key=Name,Value=ha-web-asg,PropagateAtLaunch=true"
# سياسة تتبع الهدف — التحجيم للحفاظ على متوسط CPU عند 60%
aws autoscaling put-scaling-policy \
--auto-scaling-group-name ha-web-asg \
--policy-name cpu-target-tracking \
--policy-type TargetTrackingScaling \
--target-tracking-configuration '{
"PredefinedMetricSpecification": {
"PredefinedMetricType": "ASGAverageCPUUtilization"
},
"TargetValue": 60.0,
"DisableScaleIn": false
}'
اضبط --health-check-type ELB وليس الافتراضي EC2. مع فحوصات صحة EC2، لا يستبدل ASG المثيل إلا حين يكون الجهاز الافتراضي غير قابل للوصول كلياً. أما مع فحوصات صحة ELB، فإذا تعطلت عملية تطبيقك أو بدأت بإرجاع أخطاء 5xx، يُعلن ALB عن المثيل غير سليم، ويُنهيه ASG ويُشغِّل بديلاً تلقائياً. هذا هو الفرق الجوهري بين "الخادم حي" و"التطبيق سليم".
التحقق من صحة البنية
بمجرد أن يصبح كلا المثيلين في ASG بحالة InService في مجموعة الأهداف، نفِّذ خطوات التحقق التالية لتأكيد عمل كل خاصية من خصائص التوافر العالي:
# 1. التحقق من سلامة المثيلات في مجموعة الأهداف
aws elbv2 describe-target-health --target-group-arn $TG_ARN \
--query 'TargetHealthDescriptions[*].{Instance:Target.Id,State:TargetHealth.State}'
# 2. التأكد من إرجاع ALB استجابة 200 من تطبيقك
curl -sI https://$ALB_DNS/health
# 3. محاكاة فشل المثيل — إنهاء مثيل ومراقبة ASG يستبدله
INSTANCE_ID=$(aws autoscaling describe-auto-scaling-instances \
--query 'AutoScalingInstances[0].InstanceId' --output text)
aws ec2 terminate-instances --instance-ids $INSTANCE_ID
# خلال دقيقتين تقريباً، يُشغِّل ASG مثيلاً بديلاً
# 4. مراقبة سجل نشاط ASG
aws autoscaling describe-scaling-activities \
--auto-scaling-group-name ha-web-asg \
--max-items 5
# 5. اختبار الفشل التلقائي لـ RDS (يُجبر على التبديل إلى Multi-AZ، ~60 ثانية توقف)
aws rds reboot-db-instance \
--db-instance-identifier ha-web-db \
--force-failover
# يجب أن يتعامل تطبيقك مع إعادة الاتصال — pool الاتصالات مع إعادة المحاولة ضروري
أنماط الفشل الإنتاجية الأساسية
البنية صامدة لكنها ليست محصنة ضد جميع أنواع الأعطال. يعرف مهندسو الشركات الكبرى هذه الحالات الطرفية:
قطيع الرعد عند التوسع: حين يُشغِّل ASG 6 مثيلات جديدة معاً خلال ارتفاع مفاجئ في حركة المرور، تضرب جميعها pool اتصالات RDS دفعةً واحدة. اضبط max_connections عبر مجموعة المعاملات واستخدم موزع اتصالات كـ PgBouncer أو RDS Proxy في وضع المعاملات لاستيعاب الموجة.
فترة التسامح مع فحص الصحة قصيرة جداً: إذا كانت --health-check-grace-period أقل من وقت تشغيل تطبيقك، سيُنهي ASG المثيل قبل أن يكون جاهزاً ويدخل في حلقة تشغيل-إنهاء. اضبطها على 1.5× وقت البدء البارد المُلاحَظ.
قالب الإطلاق المتقادم: إذا حدَّثت إصدار قالب الإطلاق لكنك نسيت تحديث مرجع ASG من $Latest إلى إصدار مثبت، قد يُشغِّل حدث توسع متزامن الإصدار الخطأ. ثبِّت إصداراً محدداً في بيئات الإنتاج الحرجة.
NAT Gateway واحد نقطة فشل وحيدة: الإعداد أعلاه يستخدم NAT Gateway واحداً في AZ-a. في حال تعطل جزئي لـ AZ-a، تفقد مثيلات AZ-b الوصول للإنترنت الخارجي. للتوافر الحقيقي، نشر NAT Gateway واحد لكل نطاق توافر وتوجيه كل شبكة فرعية خاصة إلى NAT المحلي الخاص بها.
نستخدم ملفات تعريف الارتباط لتشغيل هذا الموقع وتحليل الزيارات وعرض إعلانات مخصّصة. يمكنك قبول كل ملفات تعريف الارتباط أو رفض غير الأساسية منها.
سياسة الخصوصية