وبلاگ نت‌آرامآموزش، تجربه و راهکارهای زیرساخت

پردازش Zombie در لینوکس چیست و چطور علت زیاد شدن آن را برطرف کنیم؟

روش تشخیص پردازش defunct، پیدا کردن والد، رفع امن مشکل و بررسی دوباره وضعیت در سرور لینوکس.

انتشار:
توسط تیم فنی نت‌آرام
۵ دقیقه زمان مطالعه
۰ دیدگاه
محتوای تخصصی، ساده و کاربردی
هماهنگ با هویت حرفه‌ای نت‌آرام
بازگشت به لیست مقالات
تصویر شاخص مقاله پردازش Zombie در لینوکس چیست و چطور علت زیاد شدن آن را برطرف کنیم؟ در وبلاگ نت‌آرام
محتوای آموزشی وبلاگ نت‌آرام
در گزارش سرور، کنار یک پردازش علامت Z یا کلمه defunct می‌بینید. این پردازش دیگر در حال اجرای کار نیست؛ اجرای آن تمام شده، اما هنوز والدش نتیجه پایان آن را دریافت نکرده است. سیستم تا آن زمان اطلاعات کوچکی مانند شناسه و وضعیت خروج را نگه می‌دارد. وجود یک مورد کوتاه‌مدت لزوماً خرابی نیست، ولی انباشته‌شدن مداوم می‌تواند جدول پردازش‌ها را پر کند و مانع ایجاد پردازش جدید شود.
فرستادن kill -9 به خود Zombie معمولاً آن را پاک نمی‌کند، چون فرایند قبلاً پایان یافته است. باید ببینیم کدام برنامه والد نتیجه فرزندها را جمع نمی‌کند و چرا. فرمان‌های زیر برای لینوکس و با دسترسی ترمینال سرور هستند؛ پیش از تغییر سرویس زنده، تأثیر توقف آن و راه بازگشت را مشخص کنید.

۱. تعداد و روند را ببینید

در SSH سرور اجرا کنید:
کد / دستورps -eo pid,ppid,stat,etime,comm | awk '$3 ~ /^Z/ {print}'
ستون‌ها به ترتیب شناسه پردازش، شناسه والد، وضعیت، زمان سپری‌شده و نام کوتاه برنامه را نشان می‌دهند. حرف Z در ابتدای وضعیت یعنی Zombie. اگر چیزی نمایش داده نشد، در همان لحظه موردی با این وضعیت پیدا نشده است. ممکن است خروجی در سیستم‌های مختلف تفاوت جزئی داشته باشد.
برای شمارش، دستور زیر را چند بار با فاصله زمانی اجرا کنید و نتیجه را یادداشت کنید:
کد / دستورps -eo stat= | awk '$1 ~ /^Z/ {n++} END {print n+0}'
عدد ثابت و کم با عددی که مدام بالا می‌رود یکسان نیست. اگر تعداد رو به افزایش است، نام‌ها و شناسه والدهای مشترک را ثبت کنید. این دستورها فقط وضعیت را می‌خوانند و پردازشی را نمی‌بندند.

۲. والد را دقیق شناسایی کنید

فرض کنید ستون PPID مقدار 1234 را نشان می‌دهد. به جای عدد نمونه، عدد واقعی را بگذارید:
کد / دستورps -p 1234 -o pid,ppid,stat,etime,user,args ps --ppid 1234 -o pid,ppid,stat,etime,comm
فرمان اول مشخصات والد و فرمان دوم فرزندهای فعلی همان والد را نشان می‌دهد. نام برنامه و کاربر اجراکننده کمک می‌کند بفهمید مربوط به کدام سرویس است. خروجی args ممکن است اطلاعات حساس داشته باشد؛ پیش از ارسال به دیگران آن را از رمز و توکن پاک کنید.
شناسه‌های پردازش قابل استفاده مجدد هستند. قبل از هر اقدام، بار دیگر خروجی را ببینید و مطمئن شوید PID همچنان متعلق به همان برنامه است. اگر ابزار pstree موجود باشد، pstree -ap 1234 هم نمای درختی می‌دهد؛ نبودن آن مانع تشخیص با ps نیست.

۳. راه‌حل را با توجه به مالک والد انتخاب کنید

اگر والد برنامه‌ای است که خودتان نوشته‌اید، محل ساخت فرایند فرزند را پیدا کنید. برنامه باید نتیجه پایان هر فرزند را با سازوکار مناسب زبان خود دریافت کند؛ در سطح سیستم، خانواده wait و waitpid برای این کار استفاده می‌شوند. کپی‌کردن یک signal handler ناشناس بدون هماهنگی با کتابخانه‌ها می‌تواند رفتار برنامه را خراب کند؛ راهنمای زبان و روش اجرای فرزند همان پروژه را دنبال کنید. کد اصلاح‌شده را با چند اجرای هم‌زمان در محیط آزمایشی امتحان کنید و ببینید تعداد Z پایدار می‌ماند.
اگر والد یک سرویس تحت مدیریت systemd است، ابتدا سرویس و گزارش آن را شناسایی کنید:
کد / دستورsystemctl status example.service journalctl -u example.service --since '30 minutes ago' --no-pager
example.service فقط نمونه است. خطاهای تکراری فرزند، کمبود منابع و زمان شروع افزایش Zombieها را با گزارش تطبیق دهید. اگر سرویس شناخته‌شده است و توقف کوتاه آن مجاز است، می‌توانید پس از اطلاع کاربران، داشتن نسخه سالم و امکان بازگشت، آن را با روش مستند همان سرویس به‌صورت کنترل‌شده restart کنید:
کد / دستورsudo systemctl restart example.service sudo systemctl status example.service
این کار ممکن است ارتباط‌ها و کارهای در حال اجرا را قطع کند و دلیل اصلی باگ را درمان نمی‌کند. نام سرویس را دقیق تأیید کنید؛ روی هاست اشتراکی یا جایی که دسترسی مدیریت ندارید، خروجی بدون اطلاعات محرمانه را برای پشتیبانی بفرستید. هرگز سرویس ناشناس یا مهمی مانند پایگاه داده را صرفاً به دلیل یک Zombie بی‌برنامه متوقف نکنید.
وقتی والد پایان می‌یابد، فرزندهای یتیم معمولاً به init یا یک subreaper سپرده می‌شوند تا نتیجه‌شان جمع شود. در کانتینر، رفتار به برنامه PID 1 و تنظیمات محیط بستگی دارد؛ اگر PID 1 مسئول جمع‌کردن فرزندها نباشد، باید تنظیم و برنامه همان کانتینر اصلاح شود. به PID 1 سیگنال تصادفی نفرستید.

۴. نتیجه و علت را دوباره بررسی کنید

همان دستور شمارش مرحله اول را بعد از اقدام و چند بار در بازه فعالیت واقعی اجرا کنید. کاهش موقت خوب است، اما اگر عدد دوباره رشد کند، علت در برنامه یا نحوه مدیریت فرزند باقی مانده است. خروجی گزارش و نسخه نرم‌افزار را نگه دارید و تغییر کد یا به‌روزرسانی تأییدشده را در محیط آزمایشی بررسی کنید.
اگر سرویس پس از راه‌اندازی مکرر دیگر شروع نمی‌شود، راهنمای start-limit-hit مسیر تشخیص جداگانه‌ای دارد. برای بررسی و رسیدگی تخصصی می‌توانید مدیریت سرور نت‌آرام را ببینید. شرح فنی دریافت وضعیت فرزند در راهنمای waitpid لینوکس آمده است.
اشتراک‌گذاری:
لینکدینتلگرامایکس

دیدگاه‌ها (۰)

دیدگاه‌های تاییدشده و پاسخ‌های تیم نت‌آرام