1. ספרייה
  2. HTTP והרשת
  3. קודי סטטוס HTTP

עודכן לפני חודש

503 Service Unavailable הוא אחד מקודי מצב HTTP הבודדים שהם באמת אופטימיים. הוא לא אומר "משהו השתבש." הוא אומר "משהו השתבש באופן זמני, אני מודע לכך, והנה מתי לנסות שוב."

זוהי גישה שונה לגמרי כלפי כישלון.

ההבטחה של 503

503 הוא חוזה בין השרת לבין הלקוח:

  1. השרת קיבל והבין את הבקשה שלך
  2. הוא אינו יכול לטפל בה כרגע
  3. זה זמני
  4. הנה מתי לחזור
HTTP/1.1 503 Service Unavailable
Retry-After: 3600
Content-Type: application/json

{
    "error": "Service Unavailable",
    "message": "We're performing scheduled maintenance. Service resumes in 1 hour.",
    "retryAfter": 3600
}

כותרת ה-Retry-After היא ההבטחה שהופכת למוחשית. בלעדיה, 503 הוא רק תלונה. איתה, 503 הוא תוכנית פעולה.

כשהשרתים אומרים "לא עכשיו"

תחזוקה מתוכננת

הדרך הכי כנה להשתמש ב-503 — אתה מכוון לרדת מהאוויר:

HTTP/1.1 503 Service Unavailable
Retry-After: Wed, 21 Oct 2024 16:00:00 GMT

{
    "error": "Maintenance in Progress",
    "message": "Scheduled maintenance until 4:00 PM.",
    "resumeTime": "2024-10-21T16:00:00Z"
}

עומס יתר

השרת מוצף בבקשות:

HTTP/1.1 503 Service Unavailable
Retry-After: 30

{
    "error": "Service Overloaded",
    "message": "Too many concurrent requests. Try again in 30 seconds."
}

כישלון תלות

תלות קריטית (מסד נתונים, מטמון, API חיצוני) אינה פעילה:

app.get('/api/data', async function(request, response) {
    try {
        const data = await database.query('SELECT * FROM data');
        response.json(data);
    }
    catch(error) {
        response.status(503)
            .set('Retry-After', '60')
            .json({
                error: 'Service Unavailable',
                message: 'Database temporarily unavailable'
            });
    }
});

הפעלה וכיבוי

האפליקציה עדיין לא מוכנה, או שהיא עוברת כיבוי מסודר:

let ready = false;
let shuttingDown = false;

app.use(function(request, response, next) {
    if(!ready || shuttingDown) {
        return response.status(503).json({
            error: ready ? 'Shutting Down' : 'Starting Up',
            message: 'Service temporarily unavailable'
        });
    }
    next();
});

כותרת ה-Retry-After

כותרת זו הופכת את 503 משדר מצב לשיחה של ממש.

פורמט שניות להמתנות קצרות:

Retry-After: 60

פורמט תאריך לתחזוקה מתוכננת:

Retry-After: Wed, 21 Oct 2024 16:00:00 GMT

בלי Retry-After, הלקוחות מנחשים. איתה, הם יודעים בדיוק מתי לחזור.

יישום מצב תחזוקה

הגישה הפשוטה ביותר — קובץ שקיים או לא:

const fs = require('fs');

app.use(function(request, response, next) {
    if(fs.existsSync('/var/www/maintenance.flag')) {
        const config = JSON.parse(fs.readFileSync('/var/www/maintenance.flag'));
        return response.status(503)
            .set('Retry-After', config.retryAfter)
            .json({
                error: 'Maintenance in Progress',
                message: config.message
            });
    }
    next();
});

הפעלת תחזוקה:

echo '{"retryAfter": 3600, "message": "Scheduled maintenance"}' > /var/www/maintenance.flag

ביטול:

rm /var/www/maintenance.flag

אין צורך בפריסה מחדש. אין צורך בהפעלה מחדש.

לקוחות שמכבדים את ההבטחה

לקוח שמכבד 503 ו-Retry-After:

async function fetchWithRetry(url, maxRetries = 3) {
    for(let attempt = 0; attempt < maxRetries; attempt++) {
        const response = await fetch(url);

        if(response.status !== 503) {
            return response;
        }

        const retryAfter = response.headers.get('Retry-After');
        let waitTime;

        if(retryAfter && /^\d+$/.test(retryAfter)) {
            waitTime = parseInt(retryAfter) * 1000;
        }
        else if(retryAfter) {
            waitTime = new Date(retryAfter).getTime() - Date.now();
        }
        else {
            waitTime = Math.pow(2, attempt) * 1000; // Exponential backoff
        }

        await new Promise(function(resolve) {
            setTimeout(resolve, waitTime);
        });
    }

    throw new Error('Service unavailable after retries');
}

בדיקות תקינות עם משמעות

נקודות קצה לבדיקת תקינות צריכות להחזיר 503 כשהשירות אינו תקין:

app.get('/health', async function(request, response) {
    const checks = {
        database: await pingDatabase(),
        cache: await pingCache()
    };

    const healthy = Object.values(checks).every(Boolean);

    response.status(healthy ? 200 : 503)
        .set(healthy ? {} : { 'Retry-After': '60' })
        .json({ status: healthy ? 'healthy' : 'unhealthy', checks });
});

מאזני עומס עוקבים אחר נקודות קצה אלו. כשהם רואים 503, הם מוציאים את השרת מהסבב ומפסיקים לנתב אליו תעבורה עד שיתאושש.

503 לעומת שכניו

סטטוסמשמעותלנסות שוב?
500משהו לא צפוי קרהאולי לעולם לא
502שרת upstream התנהג בצורה בעייתיתלא ידוע
503זמנית אינו זמיןכן, ב-Retry-After
429הגעת למגבלת הקצב שלךכן, השרת בסדר

503 הוא ייחודי: זה השרת מודה בחולשה זמנית תוך כדי הבטחת התאוששות. 500 הוא בלבול. 502 הוא האשמת אחרים. 429 הוא אשמת הלקוח. רק 503 אומר "זה עלי, ואני מטפל בזה."

משמעת ה-503

תמיד כלול Retry-After. 503 בלעדיו הוא הבטחה ללא לוח זמנים.

השתמש רק לתנאים זמניים. אם סכמת מסד הנתונים שגויה, זה 500. אם מסד הנתונים מתחיל מחדש, זה 503.

כשל מהיר. אם אתה יודע שאינך יכול לטפל בבקשה, החזר 503 מיד. אל תבזבז משאבים לגלות מה שכבר ידעת.

עקוב אחר שיעור ה-503 שלך. 503 תכופות חושפות בעיות קיבולת, תלויות לא יציבות, או תהליכי תחזוקה שרצים זמן רב מדי.

שאלות נפוצות על 503 Service Unavailable

מה ההבדל בין 503 ל-500?

500 אומר שמשהו לא צפוי קרה — באג, חריגה שלא טופלה, מצב פגום. השרת לא יודע מתי ואם יתאושש. 503 אומר שהשרת יודע שהוא זמנית אינו זמין ומצפה להתאושש. השתמש ב-503 כשאתה מבין את הבעיה והיא חולפת; השתמש ב-500 כשאינך מבין.

האם תמיד צריך לכלול Retry-After עם 503?

כן. בלי Retry-After, לקוחות צריכים לנחש מתי לנסות שוב, מה שמוביל לניסיונות חוזרים ונשנים אגרסיביים (שמעמיסים על השרת המתאושש) או לוויתור מוקדם מדי. Retry-After הופך "נסה מאוחר יותר" עמום לחוזה ברור.

מתי להשתמש ב-503 לעומת 429 להגבלת קצב?

429 אומר "אתה ספציפית הגעת למגבלה שלך, אבל השרת בסדר." 503 אומר "השרת לא יכול לטפל בבקשות של אף אחד כרגע." השתמש ב-429 להגבלות קצב לכל לקוח. השתמש ב-503 כשהשרת באמת עמוס ולא יכול לשרת אף לקוח.

כיצד מאזני עומס משתמשים ב-503?

רוב מאזני העומס עוקבים אחר נקודות קצה לבדיקת תקינות. כשרת מחזיר 503, מאזן העומס מוציא אותו מהסבב ומפסיק לנתב אליו תעבורה. ברגע שהשרת מתחיל להחזיר 200 שוב, התעבורה מתחדשת. מנגנון ה-failover האוטומטי הזה הוא הסיבה ש-503 חשוב כל כך לזמינות גבוהה.

האם דף זה היה מועיל?

😔
🤨
😃
503 שירות אינו זמין • ספרייה • Connected