Amirali Yaghoutiمهندس ارشد نرم‌افزار

مطالعه موردی مهندسی

A2 لاگ عملکرد

مسئله‌ی کارایی‌ای که فقط در پروداکشن خودش را نشان می‌دهد، جای دیگری حل نمی‌شود. Xdebug و Query Monitor روی یک فروشگاه زنده با ترافیک واقعی گزینه نیستند، پس لاگری نوشتم که همان‌جا دائم اجرا می‌شود و روی یک درخواست سریع تقریباً هیچ هزینه‌ای ندارد.

مسئله تجاری

درخواست‌های سبد، جست‌وجو و افزودن به سبد گاه‌به‌گاه کند می‌شدند، و همین «گاه‌به‌گاه» سخت‌ترین قسمت ماجراست. استیجینگ بازتولیدش نمی‌کرد، چون ماشه‌اش ترافیک واقعی روی کاتالوگ واقعی بود. پروفایلری هم که همه‌ی درخواست‌ها را ثبت کند، خودش می‌شود مسئله‌ی کارایی. پس لاگر باید روی درخواست‌های سالم ارزان می‌بود و فقط روی کندها پرجزئیات.

آنچه تحویل دادم

  • a2-perf-logger.php، یک افزونه‌ی MU ۴۵۸ خطی روی نسخه‌ی ۱.۲.۰ که در یک فایل لاگ چرخشی با سقف ۵ مگابایت می‌نویسد.
  • سیاست ثبت پله‌ای: هر چیزی بالای ۸۰۰ms لاگ می‌شود، بالای ۲٫۵ ثانیه ثبت عمیق می‌گیرد، و از بقیه ۵٪ نمونه برداشته می‌شود.
  • انتساب کوئری کند: کوئری بالای ۲۵۰ms همراه استک فراخوان ثبت می‌شود، تا به افزونه‌ای که صادرش کرده گره بخورد و فقط یک رشته‌ی SQL خشک گزارش نشود.
  • دسته‌بندی درخواست: سبد و جست‌وجو و افزودن به سبد بی‌توجه به زمانشان همیشه لاگ می‌شوند، و اسِت‌ها و ۴۰۴ها اصلاً ثبت نمی‌شوند.
  • خروجی کران‌دار در هر سطح: حداکثر ۶ کوئری کند، ۱۰ مالک کوئری، ۸ فراخوان، ۱۰ جدول، ۸ فریم استک و ۱۲ خطا در هر رکورد.
  • ثبت کوکی و هدر و نشانه‌های بات؛ همین است که درخواست کندِ یک مشتری واردشده را از درخواست کندِ یک خزنده جدا می‌کند.
  • یک هندلر خطا و استثنای PHP که هرچه اشتباه پیش رفته را به همان رکورد لاگ می‌چسباند.

رویکرد فنی

  • تصمیم به لاگ‌کردن در shutdown گرفته می‌شود، وقتی مدت واقعی معلوم شده؛ پس درخواست سریع هیچ هزینه‌ای بابت دستگاه ثبت نمی‌دهد.
  • لاگ کوئری در اولین هوکی که اجرا می‌شود روشن می‌شود تا کوئری افزونه‌های MU دیگر از دست نرود، و در چند هوک بعدی دوباره تلاش می‌شود تا اگر چیزی خاموشش کرد جبران شود.
  • مسیر لاگ اول محل اصلی را امتحان می‌کند و بعد به uploads برمی‌گردد، و اگر دایرکتوری نباشد ساخته می‌شود؛ لاگری که روی نصب تازه بی‌صدا شکست بخورد، از نبودنش بدتر است.
  • سقف هر فهرست با یک ثابت صریح تعیین شده، نه با بریدن موقع نوشتن. همین جلوی درخواستی را می‌گیرد که می‌خواهد یک مگابایت لاگ تولید کند.
  • کلاس‌های حساس حتی وقتی سریع‌اند هم ثبت می‌شوند، چون تا ندانی «عادی» روی مسیر پرداخت چه شکلی است، نقطه‌ی پرت هم خوانا نیست.

نتیجه و شواهد

کندی صاحب پیدا کرد. همین لاگر بود که کندی گاه‌به‌گاه سبد و جست‌وجو را به کوئری‌های مشخص با فراخوان‌های مشخص تبدیل کرد، و هر اصلاح کارایی دیگری روی این فروشگاه از همین ورودی شروع شد. از آن موقع پیوسته در پروداکشن اجرا شده، و همین پله‌بندی است که نگه‌داشتنش را مقرون‌به‌صرفه می‌کند.

اهمیت برای کارفرما

بیشتر توصیه‌های کارایی ووکامرس کلی است، چون بیشتر آدم‌ها دارند حدس می‌زنند. شواهد درخواست‌به‌درخواست از سایت زنده بود که کار را محدود نگه داشت، و اصلاح محدود همان است که حادثه نمی‌سازد.

خلاصه-اجرایی-پروژه

خلاصه اجرایی خوانا

خلاصه_اجرایی {
  پروژه: "A2 Perf Logger"
  فایل: "mu-plugins/a2-perf-logger.php (۴۵۸ خط، v1.2.0)"
  آستانه: "لاگ > ۸۰۰ms، ثبت عمیق > ۲۵۰۰ms"
  نمونه‌برداری: "۵٪ از بقیه؛ کلاس‌های حساس همیشه"
  انتساب: "کوئری > ۲۵۰ms با استک فراخوان + جدول‌ها"
  سقف‌ها: "۶ کوئری / ۱۰ مالک / ۸ فراخوان / ۱۰ جدول /
           ۸ فریم / ۱۲ خطا در هر رکورد"
  نادیده: "اسِت‌های ایستا و ۴۰۴"
  خروجی: "فایل چرخشی، ۵MB، فالبک uploads"
  نقطه_تصمیم: "shutdown، وقتی مدت واقعی معلوم است"
}

ارزش حرفه‌ای این پروژه

ثابت‌های بالای این فایل خودِ طراحی‌اند. آستانه‌ها، نرخ نمونه‌برداری و هر سقف طوری انتخاب شده که لاگر روی فروشگاهی با ترافیک واقعی مقرون‌به‌صرفه بماند.

ابزاری که امن باشد روشن بماند برایم ارزشمندتر از ابزاری است که همه‌چیز را ثبت کند. پروفایلری که مجبوری خاموشش کنی، همان پروفایلری است که وقتی لازمش داری خاموش است.