Redis والتخزين المؤقت المتقدم

CDN والتخزين المؤقت الطرفي

20 دقيقة الدرس 18 من 30

CDN والتخزين المؤقت الطرفي

تخزن شبكات توصيل المحتوى (CDN) المحتوى في مواقع طرفية حول العالم، لخدمة المستخدمين من أقرب خادم. هذا يقلل بشكل كبير من زمن الوصول ويحسن أوقات تحميل الصفحة عالميًا.

ما هي شبكة CDN؟

CDN هي شبكة موزعة من الخوادم التي تخزن وتقدم المحتوى من مواقع أقرب جغرافيًا للمستخدمين. بدلاً من أن يسافر كل طلب إلى خادم المنشأ الخاص بك، تقدم CDN المحتوى المخزن مؤقتًا من خوادم الحافة.

الفوائد: تقليل زمن الوصول (أسرع بنسبة 50-90%)، تكاليف نطاق ترددي أقل، حماية من هجمات DDoS، وقابلية توسع محسّنة.

كيف تعمل شبكات CDN

عندما يطلب مستخدم محتوى، يفحص خادم حافة CDN ذاكرته المؤقتة. إذا كان المحتوى موجودًا وحديثًا، يتم تقديمه على الفور. إذا لم يكن كذلك، تجلب CDN من المنشأ وتخزنه مؤقتًا وتقدمه.

تدفق طلب المستخدم:\n1. يطلب المستخدم https://cdn.example.com/logo.png\n2. يحل DNS إلى أقرب خادم حافة CDN\n3. يفحص خادم الحافة الذاكرة المؤقتة\n4. إذا كان مخزنًا مؤقتًا: تقديم فوري (نجاح الذاكرة المؤقتة)\n5. إذا لم يكن مخزنًا مؤقتًا: جلب من المنشأ، التخزين المؤقت، التقديم (فشل الذاكرة المؤقتة)\n6. الطلبات اللاحقة: تقديم من الذاكرة المؤقتة

موفرو CDN الشائعون

يقدم موفرو CDN الرئيسيون شبكات حافة عالمية بميزات ونماذج تسعير مختلفة.

أفضل شبكات CDN: Cloudflare (200+ موقع، طبقة مجانية)، AWS CloudFront (450+ موقع)، Fastly (صديق للمطورين)، Akamai (للمؤسسات)، BunnyCDN (ميسور التكلفة).

إعداد Cloudflare CDN

يوفر Cloudflare خدمات CDN مجانية مع تخزين مؤقت تلقائي للأصول الثابتة.

// يخزن Cloudflare تلقائيًا:\n// - الصور (.jpg, .png, .gif, .webp)\n// - ملفات CSS و JavaScript\n// - الخطوط (.woff, .woff2, .ttf)\n// - ملفات الفيديو والصوت\n\n// قواعد التخزين المؤقت المخصصة عبر قواعد الصفحة:\n// مستوى الذاكرة المؤقتة: قياسي، قوي، أو تجاوز\n// TTL الذاكرة المؤقتة الطرفية: تجاوز رؤوس الذاكرة المؤقتة للمنشأ\n// TTL ذاكرة المتصفح المؤقتة: التحكم في التخزين المؤقت من جانب العميل\n\n// مثال على قاعدة الصفحة:\n// URL: *.example.com/assets/*\n// الإعدادات:\n//   مستوى الذاكرة المؤقتة: تخزين كل شيء مؤقتًا\n//   TTL الذاكرة المؤقتة الطرفية: شهر واحد\n//   TTL ذاكرة المتصفح المؤقتة: 4 ساعات

إعداد AWS CloudFront

يتكامل CloudFront مع خدمات AWS ويوفر عناصر تحكم تخزين مؤقت متقدمة.

// تكوين توزيع CloudFront\n{\n  "Origins": [{\n    "DomainName": "origin.example.com",\n    "Id": "myOrigin"\n  }],\n  "DefaultCacheBehavior": {\n    "TargetOriginId": "myOrigin",\n    "ViewerProtocolPolicy": "redirect-to-https",\n    "AllowedMethods": ["GET", "HEAD", "OPTIONS"],\n    "CachedMethods": ["GET", "HEAD"],\n    "ForwardedValues": {\n      "QueryString": false,\n      "Cookies": { "Forward": "none" }\n    },\n    "MinTTL": 0,\n    "DefaultTTL": 86400,  // يوم واحد\n    "MaxTTL": 31536000     // سنة واحدة\n  }\n}
نصيحة: استخدم سلوكيات تخزين مؤقت مختلفة لأنماط URL مختلفة (الأصول الثابتة مقابل نقاط نهاية API).

رؤوس الذاكرة المؤقتة لـ CDN

تتحكم رؤوس الذاكرة المؤقتة HTTP في كيفية تخزين شبكات CDN والمتصفحات للمحتوى مؤقتًا. حدد الرؤوس المناسبة على خادم المنشأ الخاص بك.

// رؤوس الذاكرة المؤقتة في Express.js\napp.use('/assets', (req, res, next) => {\n  // تخزين الأصول الثابتة مؤقتًا لمدة سنة\n  res.setHeader('Cache-Control', 'public, max-age=31536000, immutable');\n  next();\n});\n\napp.use('/api', (req, res, next) => {\n  // عدم تخزين استجابات API مؤقتًا\n  res.setHeader('Cache-Control', 'no-store, no-cache, must-revalidate');\n  next();\n});\n\n// رأس Vary للتفاوض على المحتوى\nres.setHeader('Vary', 'Accept-Encoding, Accept-Language');\n\n// ETag للتحقق\nres.setHeader('ETag', generateETag(content));

توجيهات Cache-Control

فهم توجيهات Cache-Control أمر بالغ الأهمية للتخزين المؤقت الصحيح لـ CDN.

// توجيهات Cache-Control:\n\n// public - يمكن تخزينه مؤقتًا بواسطة CDN والمتصفحات\nCache-Control: public, max-age=3600\n\n// private - ذاكرة المتصفح المؤقتة فقط، وليس CDN\nCache-Control: private, max-age=3600\n\n// no-cache - يجب إعادة التحقق قبل التقديم\nCache-Control: no-cache\n\n// no-store - عدم التخزين المؤقت أبدًا (بيانات حساسة)\nCache-Control: no-store\n\n// immutable - المحتوى لا يتغير أبدًا (أصول ذات إصدارات)\nCache-Control: public, max-age=31536000, immutable\n\n// s-maxage - CDN cache TTL (يتجاوز max-age لـ CDN)\nCache-Control: public, max-age=3600, s-maxage=86400
أفضل ممارسة: استخدم عناوين URL ذات إصدارات للأصول الثابتة (app.v123.js) وحدد immutable مع max-age طويل.

حماية المنشأ

تضيف حماية المنشأ طبقة تخزين مؤقت إضافية بين خوادم الحافة والمنشأ لتقليل حمل المنشأ.

// بدون حماية المنشأ:\nخادم الحافة 1 (فشل الذاكرة المؤقتة) → المنشأ\nخادم الحافة 2 (فشل الذاكرة المؤقتة) → المنشأ\nخادم الحافة 3 (فشل الذاكرة المؤقتة) → المنشأ\n// 3 طلبات للمنشأ لنفس المحتوى\n\n// مع حماية المنشأ:\nخادم الحافة 1 (فشل الذاكرة المؤقتة) → خادم الحماية (فشل الذاكرة المؤقتة) → المنشأ\nخادم الحافة 2 (فشل الذاكرة المؤقتة) → خادم الحماية (نجاح الذاكرة المؤقتة)\nخادم الحافة 3 (فشل الذاكرة المؤقتة) → خادم الحماية (نجاح الذاكرة المؤقتة)\n// طلب واحد فقط للمنشأ\n\n// تكوين حماية منشأ CloudFront:\n{\n  "OriginShield": {\n    "Enabled": true,\n    "OriginShieldRegion": "us-east-1"\n  }\n}

مسح ذاكرة CDN المؤقتة

أبطل المحتوى المخزن مؤقتًا عندما تنشر التحديثات أو تحتاج إلى إزالة البيانات القديمة.

// مسح Cloudflare API\nconst cloudflare = require('cloudflare')({\n  token: 'your-api-token'\n});\n\n// مسح ملفات محددة\nawait cloudflare.zones.purgeCache(zoneId, {\n  files: [\n    'https://example.com/style.css',\n    'https://example.com/app.js'\n  ]\n});\n\n// المسح حسب علامة الذاكرة المؤقتة\nawait cloudflare.zones.purgeCache(zoneId, {\n  tags: ['product-images']\n});\n\n// مسح كل شيء (استخدم بحذر!)\nawait cloudflare.zones.purgeCache(zoneId, {\n  purge_everything: true\n});
// إبطال AWS CloudFront\nconst AWS = require('aws-sdk');\nconst cloudfront = new AWS.CloudFront();\n\nconst params = {\n  DistributionId: 'E1234567890ABC',\n  InvalidationBatch: {\n    CallerReference: Date.now().toString(),\n    Paths: {\n      Quantity: 2,\n      Items: [\n        '/assets/style.css',\n        '/assets/app.js'\n      ]\n    }\n  }\n};\n\nawait cloudfront.createInvalidation(params).promise();
تحذير: يمكن أن تكون عمليات مسح CDN مكلفة وبطيئة. استخدم عناوين URL ذات إصدارات بدلاً من عمليات المسح المتكررة.

التخزين المؤقت الثابت مقابل الديناميكي

تتطلب أنواع المحتوى المختلفة استراتيجيات تخزين مؤقت مختلفة.

// المحتوى الثابت (الصور، CSS، JS):\n// - أوقات تخزين مؤقت طويلة (شهر إلى سنة)\n// - استخدم أسماء ملفات ذات إصدارات (app.v123.js)\n// - Cache-Control: public, max-age=31536000, immutable\napp.use('/static', express.static('public', {\n  maxAge: '1y',\n  immutable: true\n}));\n\n// المحتوى الديناميكي (صفحات HTML):\n// - أوقات تخزين مؤقت قصيرة (5 دقائق إلى ساعة)\n// - استخدم ETag للتحقق\n// - Cache-Control: public, max-age=300, must-revalidate\napp.get('/blog/:slug', async (req, res) => {\n  const post = await getPost(req.params.slug);\n  const etag = generateETag(post);\n  \n  if (req.get('If-None-Match') === etag) {\n    return res.status(304).end();\n  }\n  \n  res.set({\n    'Cache-Control': 'public, max-age=300, must-revalidate',\n    'ETag': etag\n  });\n  res.render('post', { post });\n});

الحوسبة الطرفية مع Cloudflare Workers

شغّل التعليمات البرمجية في الحافة لتخصيص سلوك التخزين المؤقت وتوصيل المحتوى.

// مثال على Cloudflare Worker\naddEventListener('fetch', event => {\n  event.respondWith(handleRequest(event.request));\n});\n\nasync function handleRequest(request) {\n  const url = new URL(request.url);\n  \n  // منطق تخزين مؤقت مخصص\n  if (url.pathname.startsWith('/api/')) {\n    // عدم تخزين API مؤقتًا\n    return fetch(request);\n  }\n  \n  // فحص الذاكرة المؤقتة\n  const cache = caches.default;\n  let response = await cache.match(request);\n  \n  if (!response) {\n    // جلب من المنشأ\n    response = await fetch(request);\n    \n    // التخزين المؤقت لمدة ساعة\n    const headers = new Headers(response.headers);\n    headers.set('Cache-Control', 'public, max-age=3600');\n    \n    response = new Response(response.body, {\n      status: response.status,\n      headers\n    });\n    \n    event.waitUntil(cache.put(request, response.clone()));\n  }\n  \n  return response;\n}
نصيحة: استخدم الحوسبة الطرفية لاختبار A/B، والتوجيه القائم على الموقع الجغرافي، وتوصيل المحتوى المخصص.

مراقبة أداء CDN

تتبع معدلات نجاح الذاكرة المؤقتة، واستخدام النطاق الترددي، ومقاييس الأداء.

// مقاييس CDN الرئيسية:\n\n// معدل نجاح الذاكرة المؤقتة: (نجاحات الذاكرة المؤقتة / إجمالي الطلبات) * 100\n// الهدف: >90% للأصول الثابتة، >70% للمحتوى الديناميكي\n\n// معدل نجاح حماية المنشأ: نجاحات ذاكرة الحماية المؤقتة / طلبات الحماية\n// الهدف: >80%\n\n// النطاق الترددي المحفوظ: نطاق المنشأ الترددي مقابل النطاق الترددي الإجمالي\n// CDN جيد يجب أن يوفر 60-90% من النطاق الترددي\n\n// وقت الاستجابة P95: زمن الوصول للطلب في المئوية 95\n// الهدف: <100 مللي ثانية عالميًا\n\n// معدل فشل الذاكرة المؤقتة: عمليات البحث الفاشلة في الذاكرة المؤقتة\n// معدل فشل مرتفع يشير إلى مشاكل في التخزين المؤقت
تمرين: قم بإعداد CDN لتطبيق ويب. قم بتكوين قواعد التخزين المؤقت للأصول الثابتة (سنة واحدة) وصفحات HTML (5 دقائق). نفّذ حماية المنشأ لتقليل حمل المنشأ. أضف رؤوس التخزين المؤقت إلى تطبيقك. انشر تحديثًا باستخدام عناوين URL للأصول ذات الإصدارات (style.v2.css) دون مسح. راقب معدلات نجاح الذاكرة المؤقتة وحسّن بناءً على المقاييس.