Mahsulotlarni import qilayotgan skript, katta hisobotni yaratayotgan sahifa yoki zaxira nusxa oluvchi plagin bir muddat ishlab, keyin Fatal error: Maximum execution time of 30 seconds exceeded xatosi bilan to'xtab qolishi mumkin. Bu PHP'ning max_execution_time sozlamasi ishga tushganini bildiradi. Bu sozlama bitta skript qancha vaqt ishlashi mumkinligini cheklaydi va standart qiymati 30 soniya. Quyida bu chegara qanday hisoblanishi, uni qachon oshirish o'rinli ekani va qachon vazifaning o'zini boshqacha tashkil qilish kerakligini ko'rib chiqamiz.
Chegara qanday hisoblanadi
Ko'pchilik bu chegarani soat bo'yicha o'tgan vaqt deb o'ylaydi, lekin Linux serverlarda bunday emas. PHP hujjatlariga ko'ra, max_execution_time faqat skriptning o'zi bajarilishiga ketgan vaqtni hisoblaydi. Bazaga yuborilgan so'rov javobini kutish, tashqi API'dan ma'lumot yuklab olish, sleep() yoki system() orqali chaqirilgan buyruqlar bu hisobga kirmaydi. Windows serverlarda esa haqiqiy o'tgan vaqt hisoblanadi. Shuning uchun Linux'da sekin tashqi API bilan ishlaydigan skript bir necha daqiqa ishlab tursa ham PHP xatosini bermasligi, lekin boshqa joyda uzilib qolishi mumkin.
Buyruq qatoridan (CLI) ishga tushirilgan skriptlar uchun standart qiymat 0, ya'ni vaqt bo'yicha cheklov yo'q. Aynan shu sababli cron orqali ishlaydigan og'ir vazifalar brauzer orqali ochilgan sahifadan ancha barqaror ishlaydi.
PHP xatosi va 504 Gateway Timeout farqi
Uzoq ishlaydigan sahifada ikki xil xato uchrashi mumkin va ularni farqlash muhim. Agar log faylida "Maximum execution time" yozuvi bo'lsa, skriptni PHP'ning o'zi to'xtatgan. Agar brauzerda 504 Gateway Timeout sahifasi chiqsa-yu, PHP logida hech narsa bo'lmasa, PHP'ning oldida turgan veb-server (masalan Nginx) javobni kutishdan charchagan. Nginx'da buni fastcgi_read_timeout yoki proxy_read_timeout sozlamalari boshqaradi va ularning standart qiymati 60 soniya. PHP-FPM'da esa request_terminate_timeout parametri jarayonni majburan to'xtatishi mumkin. Umumiy hostingda bu server sozlamalari mijoz uchun ochiq emas, shuning uchun max_execution_time ni 300 soniyaga oshirsangiz ham, sahifa baribir 60 soniyada 504 bilan uzilishi mumkin.
Chegarani oshirish usullari
Agar vazifa haqiqatan ham 30 soniyadan biroz ko'proq vaqt talab qilsa, chegarani oshirish oddiy va to'g'ri yechim. Buning bir nechta yo'li bor va ular memory_limit bilan bir xil tartibda ishlaydi.
Hosting panelida PHP sozlamalari bo'limida max_execution_time qiymatini o'zgartirish mumkin. ISPmanager panelida bu har bir sayt uchun alohida qilinadi, sayt.uz mijozlari panelga sayt.uz kabinetidagi hosting sahifasidan kiradi. PHP FPM yoki CGI rejimida ishlasa, sayt papkasidagi .user.ini fayli ham ishlaydi. Faqat Apache moduli rejimida esa .htaccess ga php_value qo'shish mumkin, boshqa rejimlarda bu qator 500 xatoga olib keladi.
; .user.ini
max_execution_time = 120
Kod ichida esa set_time_limit() funksiyasi ishlatiladi. Uning o'ziga xos xususiyati bor: chaqirilgan paytdan boshlab hisoblagich noldan qayta boshlanadi. Shuning uchun uzun siklning har bir qadamida uni chaqirish skriptga amalda cheksiz vaqt beradi. Bu qulay ko'rinadi, lekin xato yozilgan sikl ham shu tarzda abadiy ishlab qolishi mumkin, shuning uchun bu usulni ehtiyotkorlik bilan ishlating:
set_time_limit(120); // shu paytdan boshlab 120 soniya
foreach ($rows as $row) {
importRow($row);
set_time_limit(30); // har qator uchun hisoblagich qayta boshlanadi
}
Yana bir bog'liq parametr max_input_time. U so'rov ma'lumotlarini (masalan, yuklanayotgan faylni) qabul qilish va qayta ishlashga ajratilgan vaqtni cheklaydi. Sekin internet orqali katta fayl yuklanayotganda aynan shu parametr muammo tug'dirishi mumkin.
Og'ir vazifalarni brauzerdan olib chiqish
Agar vazifa bir necha daqiqa yoki undan ko'p davom etsa, uni veb-sahifa orqali bajarish noto'g'ri yondashuv. Brauzer yopilishi, internet uzilishi yoki veb-server taymauti vazifani yarim yo'lda to'xtatib qo'yadi va ma'lumot qisman yozilgan holatda qoladi. To'g'ri yo'l vazifani cron orqali, buyruq qatoridan ishga tushirishdir. ISPmanager panelida rejalashtirilgan vazifalar uchun alohida bo'lim bor, u yerda buyruq va jadvalni ko'rsatasiz:
# har kuni soat 03:30 da importni ishga tushirish
30 3 * * * /usr/bin/php /var/www/example_user/data/www/example.uz/cron/import.php >> /var/www/example_user/data/logs/import.log 2>&1
Buyruqdagi PHP yo'li va papka yo'li serverga qarab farq qiladi, ayniqsa sayt uchun boshqa PHP versiyasi tanlangan bo'lsa. To'g'ri yo'lni panelning o'zidan yoki texnik yordamdan aniqlab oling. Natijani log faylga yo'naltirish ham muhim, aks holda vazifa xato bilan tugaganini bilmay qolasiz.
Ishni bo'laklarga bo'lish
Cron imkoni bo'lmasa yoki vazifa foydalanuvchi tugmani bosganda boshlanishi kerak bo'lsa, ishni kichik bo'laklarga bo'ling. Har bir so'rov, masalan, 200 ta yozuvni qayta ishlaydi, qayerda to'xtaganini bazaga yoki faylga yozadi va keyingi so'rov shu joydan davom etadi. Brauzerdagi JavaScript bu so'rovlarni ketma-ket yuborib, foydalanuvchiga jarayon foizini ko'rsatib turishi mumkin. Ko'plab WordPress plaginlari (import, zaxira, rasm optimizatsiyasi) aynan shu usulda ishlaydi va shuning uchun oddiy hostingda ham katta hajm bilan ishlay oladi.
Misol: Namangandagi ulgurji savdo kompaniyasi
Namangandagi qurilish mollari ulgurji savdo kompaniyasi misol.uz saytidagi narxlarni har kuni hisob dasturidan eksport qilingan XML fayl orqali yangilaydi. Dastlab menejer admin paneldagi "Import" tugmasini bosgan, 8 ming mahsulotlik faylning yarmi yangilangach esa sahifa xato bilan to'xtagan. Natijada saytdagi narxlarning yarmi yangi, yarmi eski bo'lib qolgan. Dasturchi import skriptini CLI'dan ishlaydigan qilib qayta yozdi, uni har kuni ertalab 06:00 da cron orqali ishga tushadigan qildi va har 500 mahsulotdan keyin natijani log faylga yozadigan qildi. Endi import vaqt chegarasiga bog'liq emas, menejer esa ertalab log orqali hammasi to'g'ri yangilanganini tekshiradi.
Qaysi yechimni tanlash kerak
- Vazifa 30-120 soniya oralig'ida bo'lsa, panel yoki
.user.iniorqalimax_execution_timeni oshirish yetarli. - Vazifa bir necha daqiqa davom etsa yoki muntazam takrorlansa, uni cron va CLI'ga o'tkazing.
- Vazifa foydalanuvchi harakati bilan boshlanishi kerak bo'lsa, ishni bo'laklarga bo'lib, ketma-ket so'rovlar bilan bajaring.
- Sahifa 504 bilan uzilsa, PHP sozlamasini emas, vazifa arxitekturasini o'zgartirish haqida o'ylang.
Chegarani juda katta qiymatga ko'tarish muammoni yashiradi xolos: sekin skript serverda resurs egallab turadi, bir vaqtda bir nechta foydalanuvchi ishga tushirsa esa sayt umuman sekinlashadi. Shuning uchun avval vazifa nima uchun sekin ishlayotganini (indekssiz so'rovlar, keraksiz tashqi chaqiruvlar) tekshirish foydali.