خطای start request repeated too quickly یا وضعیت start-limit-hit معمولاً یعنی سرویس چند بار پشتسرهم Crash کرده و systemd برای جلوگیری از Crash-loop، شروع دوباره آن را موقتاً محدود کرده است. راهحل اصولی این است که اول علت Crash را با systemctl status و journalctl پیدا کنید، بعد سیاست Restart= و RestartSec= و محدودیتهای StartLimitBurst و StartLimitIntervalSec را بررسی کنید، علت اصلی را رفع کنید و فقط در پایان با systemctl reset-failed شمارنده خطا را پاک و سرویس را دوباره تست کنید.
مرحله ۱: وضعیت سرویس را با systemctl status بررسی کنید
وقتی سرویس بالا نمیآید، اولین قدم این است که وضعیت واقعی آن و آخرین خطا را ببینید. بهجای تکرار مداوم Restart، ابتدا این دستور را اجرا کنید:
sudo systemctl status myapp.service --no-pager -lدر خروجی به بخشهای Active، Result، کد خروج پردازش و آخرین پیامهای خطا دقت کنید. اگر عباراتی مثل start request repeated too quickly یا Result: start-limit-hit را میبینید، این پیام معمولاً علت اصلی خرابی نیست؛ بلکه نتیجه چند Crash متوالی است.
برای دیدن اطلاعات تکمیلی میتوانید این دستور را هم اجرا کنید:
sudo systemctl show myapp.service -p Result -p ExecMainStatus -p NRestartsمرحله ۲: علت Crash را با journalctl پیدا کنید
بعد از مشاهده وضعیت سرویس، لاگ همان Unit را بررسی کنید. مهمترین بخش عیبیابی همین مرحله است، چون تا علت Crash مشخص نشود، پاککردن محدودیت systemd فقط مشکل را موقتاً پنهان میکند.
sudo journalctl -u myapp.service -b --no-pager -n 100
sudo journalctl -u myapp.service -b -p warning..alert --no-pagerبهدنبال خطاهایی مثل کانفیگ نامعتبر، Permission denied، پورت اشغال، فایل Environment گمشده، مسیر اشتباه در ExecStart، کتابخانه یا Dependency در دسترسنبودن و خطای خود اپلیکیشن باشید. اگر سرویس بلافاصله بعد از اجرا Exit میکند، معمولاً همین لاگ مشخص میکند چرا وارد Crash-loop شده است. برای درک بهتر ساختار لاگها و نحوه کار journald و journalctl در systemd را هم ببینید.
مرحله ۳: علت واقعی Crash را از Unit و ExecStart مشخص کنید
اگر لاگ نشان میدهد مشکل از نحوه اجرای سرویس است، Unit و Overrideهای فعال را ببینید. اگر با ساختار Unitها آشنا نیستید، راهنمای آشنایی با systemd و مدیریت سرویسها مرجع مناسبی است:
sudo systemctl cat myapp.service
sudo systemctl show myapp.service -p FragmentPath -p DropInPaths -p ExecStartدر این مرحله بررسی کنید که مسیر فایل اجرایی، User سرویس، EnvironmentFile، آرگومانهای اجرای برنامه و Permissionها درست باشند. برای سرویسهای وب نیز قبل از هر تغییر در StartLimit، کانفیگ خود سرویس را تست کنید:
sudo nginx -t
sudo apachectl configtest
ss -lntpاگر سرویس اختصاصی دارید، دستور واقعی ExecStart را با همان کاربری که Unit استفاده میکند اجرا کنید تا خطای برنامه مستقیم دیده شود.
مرحله ۴: Restart و RestartSec را بررسی کنید
Crash-loop زمانی تشدید میشود که سرویس بعد از هر Failure خیلی سریع دوباره اجرا شود. تنظیمات مؤثر Restart را با این دستور ببینید:
systemctl show myapp.service -p Restart -p RestartUSecاگر Restart=always فعال است، مطمئن شوید واقعاً برای رفتار این سرویس مناسب است. برای بسیاری از Daemonها، Restart=on-failure انتخاب منطقیتری است. همچنین RestartSec نباید آنقدر کم باشد که سرویس خراب در چند ثانیه چند بار اجرا و دوباره Crash کند.
در صورت نیاز، Override بسازید:
sudo systemctl edit myapp.service[Service]
Restart=on-failure
RestartSec=5sهدف از این تغییر، مخفیکردن Crash نیست؛ فقط باید بین تلاشهای بازیابی فاصله منطقی ایجاد شود.
مرحله ۵: StartLimitBurst و StartLimitIntervalSec را بررسی کنید
systemd تعداد Startهای ناموفق را در یک بازه زمانی کنترل میکند. برای دیدن مقادیر مؤثر:
systemctl show myapp.service
-p StartLimitBurst
-p StartLimitIntervalUSecStartLimitBurst مشخص میکند چند تلاش Start در بازه مجاز است و StartLimitIntervalSec بازه زمانی این محاسبه را تعیین میکند. اگر سرویس در این بازه بیش از حد Fail شود، systemd آن را با start-limit-hit متوقف میکند. اگر اجرای این Unit توسط یک Timer انجام میشود، تنظیمات systemd Timer را هم بررسی کنید تا منبع Startهای تکراری اشتباه تشخیص داده نشود.
در صورت نیاز میتوانید این مقادیر را در Override تنظیم کنید:
sudo systemctl edit myapp.service[Unit]
StartLimitIntervalSec=60
StartLimitBurst=5
[Service]
Restart=on-failure
RestartSec=5sنکته مهم: زیادکردن StartLimitBurst یا غیرفعالکردن محدودیت، درمان Crash نیست. اگر برنامه در هر Start فوراً خطا میدهد، افزایش Limit فقط تعداد Crashها، حجم لاگ و مصرف منابع را بیشتر میکند.
مرحله ۶: علت اصلی را قبل از reset-failed اصلاح کنید
حالا خطایی را که در journalctl پیدا کردهاید واقعاً رفع کنید؛ مثلاً کانفیگ اشتباه را اصلاح کنید، Permission را درست کنید، پورت متعارض را آزاد کنید، مسیر فایل یا EnvironmentFile را تصحیح کنید یا Dependency موردنیاز برنامه را برگردانید.
اگر Override ساختهاید، پس از ذخیره تغییرات این دستور را اجرا کنید:
sudo systemctl daemon-reloadتا زمانی که علت اصلی Crash باقی است، اجرای reset-failed فقط شمارنده را صفر میکند و سرویس دوباره خیلی سریع به همان start-limit-hit میرسد.
مرحله ۷: systemctl reset-failed را اجرا و سرویس را دوباره تست کنید
بعد از رفع علت Crash، وضعیت Failed و شمارنده Start Limit را پاک کنید:
sudo systemctl reset-failed myapp.service
sudo systemctl start myapp.service
sudo systemctl status myapp.service --no-pager -lاگر سرویس دوباره بلافاصله Fail شد، Start را پشتسرهم تکرار نکنید؛ دوباره به journalctl برگردید و خطای جدید را بررسی کنید.
Verify: مطمئن شوید Crash-loop واقعاً متوقف شده است
فقط Active شدن لحظهای سرویس کافی نیست. چند وضعیت مهم را دوباره بررسی کنید:
systemctl is-active myapp.service
systemctl is-failed myapp.service
systemctl show myapp.service
-p Result
-p NRestarts
-p Restart
-p RestartUSec
-p StartLimitBurst
-p StartLimitIntervalUSecسرویس باید پایدار بماند، مقدار NRestarts بدون دلیل بالا نرود و در Journal دوباره چرخه سریع Start/Crash دیده نشود. برای چند دقیقه لاگ زنده را هم میتوانید کنترل کنید:
sudo journalctl -u myapp.service -fRollback: اگر Override مشکلساز شد
اگر تغییرات Restart یا StartLimit رفتار نامطلوبی ایجاد کرد، Override را برگردانید:
sudo systemctl revert myapp.service
sudo systemctl daemon-reload
sudo systemctl restart myapp.serviceدر سرویسهای Production قبل از تغییر Restart policy یا محدودیت Start، اثر Restart و Downtime را در نظر بگیرید و از تنظیمات فعلی یک نسخه نگه دارید.
اشتباهات رایج هنگام رفع start-limit-hit
فقط reset-failed زدن: اگر علت Crash باقی باشد، سرویس دوباره Fail میشود. زیادکردن StartLimitBurst بدون عیبیابی: فقط Crash-loop را طولانیتر میکند. قرار دادن Restart=always برای همه سرویسها: حتی Exit عمدی برنامه میتواند Restart ناخواسته ایجاد کند. ویرایش مستقیم فایل Vendor: بهتر است تغییرات محلی با systemctl edit انجام شوند تا آپدیت پکیج آنها را از بین نبرد.
اگر این عیبیابی را روی یک سرور مستقل انجام میدهید و به منابع اختصاصی برای اجرای پایدار سرویس نیاز دارید، میتوانید پلنهای VPS وانسرور را بررسی کنید.