PerformanceData Centerعیب‌یابیJira

جیرا کند شده: چطور به‌جای حدس زدن، دقیقاً پیدا کنیم کجا کند است

محمد مهیار احمدی۱۰ دقیقه مطالعه

«Jira کند شده» رایج‌ترین تیکتی است که یک ادمین می‌گیرد و بی‌فایده‌ترین جملهٔ ممکن برای شروع کار است. کند برای چه کسی، روی کدام صفحه، چه ساعتی، و نسبت به چه چیزی؟ بدون این چهار جواب، هر کاری که بکنید حدس است — و معمولاً حدس اول این است که «سرور رم کم دارد»، رم اضافه می‌شود، و دو هفته بعد همان تیکت برمی‌گردد.

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

اول: «کند» را به یک جملهٔ قابل تست تبدیل کنید

قبل از باز کردن هر لاگی، این چهار چیز را از گزارش‌دهنده بگیرید. اگر نگیرید، بعداً نمی‌توانید بفهمید مشکل حل شده یا نه:

  • کدام صفحه — باز کردن یک Issue؟ جست‌وجوی JQL؟ لود Board؟ داشبورد؟ این‌ها مسیرهای کاملاً متفاوتی در کد دارند.
  • چه ساعتی — همیشه، یا فقط صبح که همه هم‌زمان وارد می‌شوند؟
  • برای چه کسی — یک نفر، یک تیم، یا همه؟ اگر یک نفر است، شبکه یا مرورگر او هم مظنون است.
  • چند ثانیه — «کند» برای یکی سه ثانیه است و برای دیگری سی ثانیه.

access log تامکت: جایی که جواب واقعاً هست

Jira روی Tomcat اجرا می‌شود و تامکت می‌تواند برای هر درخواست، زمان پردازش را بنویسد. این تنها منبعی است که بدون ابزار جانبی به شما می‌گوید کدام درخواست چقدر طول کشیده. مسیر پیش‌فرضش:

$JIRA_INSTALL/logs/access_log.YYYY-MM-DD

اگر فایل وجود ندارد، AccessLogValve در server.xml غیرفعال است. الگوی مفید برای عیب‌یابی، الگوی پیش‌فرض به‌علاوهٔ زمان پردازش است:

pattern="%h %l %u %t "%r" %s %b %D "%{Referer}i""

دو تله‌ای که ساعت‌ها وقت می‌گیرند

هر دوی این‌ها را خودم اول بار اشتباه خواندم. اگر ندانیدشان، از روی داده‌های درست نتیجهٔ کاملاً غلط می‌گیرید.

تلهٔ اول: خط تیره یعنی «خالی»، نه بخشی از مسیر

در فرمت استاندارد access log، هر فیلدی که مقدار ندارد با - نوشته می‌شود. وقتی یک درخواست query string ندارد، چیزی شبیه این می‌بینید:

/rest/api/2/issue/ABC-123-

آن - آخر بخشی از آدرس نیست؛ یعنی «این درخواست پارامتر نداشت». اگر موقع گروه‌بندی مسیرها این را در نظر نگیرید، یک endpoint واحد به دو گروه جدا تقسیم می‌شود و آمارتان بی‌معنی می‌شود.

تلهٔ دوم: %D در Tomcat 10 میکروثانیه است، نه میلی‌ثانیه

این مهم‌ترین نکتهٔ این نوشته است. تا Tomcat 9، متغیر %D زمان پردازش را به میلی‌ثانیه می‌نوشت. از Tomcat 10 به بعد واحدش میکروثانیه شده تا با رفتار httpd یکی باشد. مستند خود تامکت این را صریح گفته است.

یعنی عدد 250000 در لاگ Jira روی تامکت ۱۰:

اگر فکر کنید میلی‌ثانیه استواقعیت روی Tomcat 10
۲۵۰ ثانیه — فاجعه۰.۲۵ ثانیه — کاملاً سالم
دنبال مشکلی می‌گردید که وجود نداردباید جای دیگری را نگاه کنید

Jira نسخهٔ ۱۰ به بعد روی Tomcat ۱۰.۱ اجرا می‌شود. پس اگر روی نسخهٔ جدید هستید و اعداد لاگ ترسناک به نظر می‌رسند، اول تقسیم بر هزار کنید و بعد نگران شوید. برای اجتناب از این ابهام می‌توانید از %F (زمان تا نوشتن اولین بایت) هم در کنارش استفاده کنید.

جدا کردن یک بار لود صفحه

لاگ زنده صدها خط در دقیقه دارد. ترفند این است که قبل و بعد از یک hard refresh تعداد خط‌ها را بشمارید و فقط تفاضل را نگاه کنید:

LOG=/opt/atlassian/jira/logs/access_log.$(date +%F)
BEFORE=$(wc -l < "$LOG")

# حالا صفحه را با Cmd+Shift+R یا Ctrl+F5 لود کنید

tail -n +$((BEFORE + 1)) "$LOG" \
  | grep '/rest/' \
  | awk -F'"' '{print $2}' \
  | sed 's/?.*//; s/ HTTP.*//' \
  | sort | uniq -c | sort -rn | head -20

خروجی به شما می‌گوید باز کردن آن صفحه چند درخواست REST زده و کدام‌ها تکراری بوده‌اند. اگر لاگ شلوغ است، به‌جای شمارش خط می‌توانید بر اساس فیلد یوزرنیم یا هدر Referer فیلتر کنید.

برای مرتب کردن بر اساس کندترین درخواست‌ها — با فرض اینکه %D فیلد یکی مانده به آخر باشد — این کافی است:

awk '{print $(NF-1), $0}' "$LOG" | sort -rn | head -20

چیزی که معمولاً پیدا می‌شود

وقتی این کار را روی یک محیط واقعی انجام می‌دهید، الگوی تکرارشونده این است: باز کردن یک Issue ده‌ها endpoint متمایز صدا می‌زند، ولی تنها بخش کوچکی از آن‌ها مربوط به خود Jira است. بقیه از افزونه‌ها می‌آید.

این خودش بد نیست — افزونه‌ها کار می‌کنند. ولی وقتی صفحه کند است، معنی‌اش این است که مظنون اول افزونه است، نه هستهٔ Jira. و این را بدون لاگ نمی‌شد فهمید.

  1. کندترین درخواست‌ها را از لاگ دربیاورید.
  2. ببینید مسیرشان به کدام افزونه تعلق دارد (معمولاً از نام plugin key در مسیر معلوم است).
  3. آن افزونه را در یک محیط تست موقتاً غیرفعال کنید و همان صفحه را دوباره اندازه بگیرید.
  4. اگر فرق کرد، با فروشندهٔ افزونه صحبت کنید یا جایگزینش کنید.

اگر Data Center دارید: سه مظنون دیگر

در نصب چندنودی، سه چیز اضافه می‌شود که در نصب تک‌نودی وجود ندارد — و هر سه به شکل «کندی» خودشان را نشان می‌دهند نه به شکل خطا.

۱. session affinity خراب

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

تشخیص سریعش ساده است: یک یوزرنیم مشخص را روی access log هر نود بگیرید. اگر در بازهٔ یک دقیقه روی بیش از یک نود دیده شد، affinity خراب است:

grep ' someuser ' /path/to/access_log.$(date +%F) | tail -20

۲. تاخیر روی shared home

همهٔ نودها یک shared home مشترک دارند — معمولاً روی NFS. پیوست‌ها، ایندکس و بکاپ آنجاست. اگر تاخیر آن استوریج بالا برود، Jira کند می‌شود بدون اینکه CPU یا رم هیچ نودی بالا برود. این دقیقاً همان حالتی است که آدم‌ها را به اشتباه سراغ اضافه کردن رم می‌فرستد.

۳. health check‌ای که دروغ می‌گوید

لودبالانسر باید /status را چک کند و بدنهٔ پاسخ را ببیند، نه فقط کد وضعیت را. یک نود می‌تواند HTTP 200 بدهد ولی هنوز در حال بالا آمدن باشد. بدنهٔ سالم این است:

{"state":"RUNNING"}

اگر لودبالانسر فقط کد ۲۰۰ را ببیند، ترافیک را به نودی می‌فرستد که هنوز آماده نیست — و کاربر «کندی» را تجربه می‌کند. اطلسین نمونهٔ پیکربندی رسمی فقط برای Apache mod_proxy_balancer و HAProxy دارد؛ برای بقیهٔ لودبالانسرها باید همین چهار الزام را دستی پیاده کنید.

ترتیب عیب‌یابی

این ترتیب را رعایت کنید. هر مرحله ارزان‌تر از مرحلهٔ بعدی است و اگر جواب داد، لازم نیست جلوتر بروید:

مرحلهکاری که می‌کنیدچه چیزی رد می‌شود
۱کدام صفحه، چه ساعتی، برای چه کسیمشکل موضعی یک کاربر
۲access log را برای همان صفحه جدا کنیدحدس زدن
۳کندترین endpointها را مرتب کنیدکل بودن مشکل
۴افزونهٔ مظنون را در محیط تست خاموش کنیدهستهٔ Jira
۵در DC: affinity و تاخیر shared homeمعماری
۶تازه حالا: منابع سرور—
اضافه کردن رم آخرین کاری است که باید بکنید، نه اولین. اگر مشکل یک کوئری سنگین یا یک افزونهٔ کند باشد، سرور بزرگ‌تر فقط همان مشکل را گران‌تر می‌کند.

جمع‌بندی

«Jira کند است» را می‌شود در یک بعدازظهر به یک جملهٔ دقیق تبدیل کرد: «باز کردن Issue در پروژهٔ فلان، ۴ ثانیه طول می‌کشد که ۳ ثانیه‌اش صرف یک endpoint از فلان افزونه می‌شود.» با جملهٔ دوم می‌شود کاری کرد؛ با جملهٔ اول نمی‌شود.

دو چیزی که بیشترین وقت را هدر می‌دهند هم همان دو تله بودند: - که مقدار خالی است، و %D که از Tomcat 10 میکروثانیه شده. هر دو باعث می‌شوند از دادهٔ درست، نتیجهٔ غلط بگیرید.

اگر محیط شما Data Center است و می‌خواهید این تحلیل روی نصب خودتان انجام شود و معماری‌اش هم بازبینی شود، پشتیبانی و نگهداری Jira دقیقاً همین کار است. اگر هم گزارش‌هایتان کند و غیرقابل‌اتکا هستند، ریشه معمولاً در کوئری‌هاست: راهنمای عملی JQL.

سؤالی دربارهٔ همین موضوع دارید؟

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

پرسیدن در واتساپ

خواندن بعدی

درخواست جلسهتماس