Website được thiết kế tối ưu cho thành viên chính thức. Hãy Đăng nhập hoặc Đăng ký để truy cập đầy đủ nội dung và chức năng. Nội dung bạn cần không thấy trên website, có thể do bạn chưa đăng nhập. Nếu là thành viên của website, bạn cũng có thể yêu cầu trong nhóm Zalo "CNTT" các nội dung bạn quan tâm.

30. Kiểm tra và debug lỗi PHP thường gặp

ICT

1. Tư duy xử lý lỗi: phân lớp và khoanh vùng nhanh

Khi gặp lỗi PHP, hãy xác định ngay lỗi thuộc lớp nào:

  1. Lớp HTTP/Nginx: 404/403/502/504, lỗi upstream, timeout, body too large…

  2. Lớp PHP-FPM: process chết, pool bão hòa (pm.max_children), slowlog, segfault, permission socket…

  3. Lớp ứng dụng: fatal error, memory exhausted, autoload, composer, Drupal bootstrap…

  4. Lớp dữ liệu: MariaDB slow query/lock, Redis down, connection refused, DNS…

  5. Lớp hệ điều hành: OOM kill, file descriptor, disk full, inode, permission SELinux/AppArmor (nếu có).

Nguyên tắc: đọc log đúng chỗ trước, không đoán.


2. “Bộ 3” log bắt buộc phải xem đầu tiên

2.1. Nginx error log

 
sudo tail -n 200 /var/log/nginx/error.log

2.2. PHP-FPM log

Tùy cấu hình, thường ở:

 
sudo tail -n 200 /var/log/php8.3-fpm.log sudo journalctl -u php8.3-fpm --since "2 hours ago" --no-pager

2.3. Log ứng dụng

  • Drupal: sites/default/files/php hoặc syslog tùy cấu hình

  • Nếu bạn bật logging qua syslog:

 
sudo journalctl --since "2 hours ago" | grep -i php

Tip: Khi xử lý sự cố, dùng grep theo request id, URI, hoặc timestamp.


3. Lỗi 502 Bad Gateway (Nginx ↔ PHP-FPM)

3.1. Dấu hiệu thường gặp trong Nginx error log

  • connect() to unix:/run/php/php8.3-fpm.sock failed

  • upstream prematurely closed connection

  • recv() failed (104: Connection reset by peer)

3.2. Checklist chẩn đoán nhanh

  1. PHP-FPM có chạy không?

 
sudo systemctl status php8.3-fpm --no-pager
  1. Socket/tcp upstream đúng chưa?

  • Kiểm tra file cấu hình site:

 
sudo nginx -T | sed -n '1,200p' | grep -n "fastcgi_pass" -n
  1. Quyền truy cập socket:

 
ls -l /run/php/php8.3-fpm.sock

Nếu Nginx chạy user www-data, socket phải cho phép www-data truy cập.

  1. PHP-FPM pool bão hòa (pm.max_children quá thấp):

 
grep -R "pm.max_children" /etc/php/8.3/fpm/pool.d/ grep -R "server reached pm.max_children" /var/log/php8.3-fpm.log

3.3. Fix phổ biến

  • Tăng pm.max_children (có kiểm chứng bằng log bão hòa).

  • Tối ưu timeout:

    • Nginx: fastcgi_read_timeout

    • PHP: max_execution_time, request_terminate_timeout (FPM)

  • Bật slowlog để xem request nào kéo dài.


4. Lỗi 504 Gateway Timeout (timeout khi xử lý PHP)

4.1. Nguyên nhân phổ biến

  • PHP xử lý quá lâu (query nặng, API treo, deadlock DB).

  • Nginx timeout ngắn hơn thời gian xử lý.

  • PHP-FPM thiếu worker hoặc worker kẹt.

4.2. Kiểm tra nhanh

  1. Nhìn lỗi timeout trong Nginx:

 
sudo tail -n 200 /var/log/nginx/error.log | grep -i timeout 
  1. Kiểm tra slow requests trong PHP-FPM (khuyến nghị bật):

  • Mở pool config:

 
sudo nano /etc/php/8.3/fpm/pool.d/www.conf

Bổ sung:

 
request_slowlog_timeout = 5s slowlog = /var/log/php8.3-fpm.slow.log

Reload:

 
sudo systemctl reload php8.3-fpm

Xem slowlog:

 
sudo tail -n 200 /var/log/php8.3-fpm.slow.log

5. Lỗi “Allowed memory size exhausted” (PHP memory)

5.1. Dấu hiệu

  • Trả 500, trong log có: Allowed memory size of ... exhausted

5.2. Kiểm tra memory limit thực tế

CLI và FPM có thể khác nhau:

 
php -i | grep -i memory_limit php-fpm8.3 -i 2>/dev/null | grep -i memory_limit

5.3. Fix đúng cách

  • Tăng memory_limit cho FPM:

    • /etc/php/8.3/fpm/php.ini

  • Nhưng quan trọng hơn: xác định đoạn nào “phình”:

    • Query trả quá nhiều dữ liệu

    • Export/report không phân trang

    • Cache không hợp lý

    • Drupal views/batch xử lý sai

Nếu lỗi xuất hiện khi chạy cron/import, nên tách job sang CLI (cron system) với cấu hình memory riêng.


6. Lỗi “Maximum execution time exceeded”

6.1. Phân biệt 2 timeout

  • PHP: max_execution_time

  • FPM: request_terminate_timeout (nếu set)

  • Nginx: fastcgi_read_timeout

6.2. Hướng xử lý

  • Nếu là tác vụ nặng (export/import), ưu tiên:

    • Chạy job nền (queue/batch)

    • Tăng timeout có kiểm soát

    • Tối ưu query / thêm index DB


7. Lỗi “No input file specified” (path/script mapping)

7.1. Nguyên nhân hay gặp

  • SCRIPT_FILENAME trong fastcgi params sai

  • root/alias trong Nginx cấu hình lệch

  • Sai try_files

7.2. Kiểm tra trong Nginx site config

Đảm bảo có dạng (ví dụ phổ biến):

 
location ~ \.php$ {  include snippets/fastcgi-php.conf;  fastcgi_pass unix:/run/php/php8.3-fpm.sock; }

root trỏ đúng vào webroot thực tế.


8. Lỗi permission (upload, cache, session, files)

8.1. Dấu hiệu

  • Permission denied

  • Drupal không ghi được sites/default/files

8.2. Checklist

  • User chạy Nginx/PHP-FPM là gì?

 
ps -eo user,comm | egrep 'nginx|php-fpm' | head 
  • Quyền thư mục:

 
namei -l /srv/www/your_site/web/sites/default/files
  • Với Drupal, thường dùng:

    • owner/group: www-data:www-data

    • quyền: thư mục 775 (tùy mô hình bảo mật)

Không nên “chmod 777” để chữa cháy; phải sửa theo user/group đúng.


9. PHP-FPM bão hòa: server reached pm.max_children

9.1. Dấu hiệu

  • Nginx trả 502/504 lúc peak

  • PHP-FPM log có dòng “reached pm.max_children”

9.2. Xử lý theo thứ tự ưu tiên

  1. Xác nhận có bão hòa:

 
grep -R "reached pm.max_children" /var/log/php8.3-fpm.log
  1. Đo memory mỗi process (bạn đã làm đúng):

 
ps --no-headers -o "rss,cmd" -C php-fpm8.3 | awk '{sum+=$1} END {print sum/NR}' 
  1. Tăng pm.max_children có kiểm soát, đồng thời:

  • Bật slowlog để biết request nào giữ worker lâu

  • Giảm “độ nặng” của request (cache, DB index, page cache, opcode cache)


10. Bật chế độ debug an toàn (không phá production)

10.1. PHP error log tách riêng cho pool

Trong pool config:

 
php_admin_value[error_log] = /var/log/php8.3-fpm.www-error.log php_admin_flag[log_errors] = on

10.2. Không bật display_errors trên production

Nếu cần debug hiển thị, chỉ bật tạm thời theo IP nội bộ hoặc môi trường staging.


11. Kiểm tra sự cố hệ điều hành: OOM, disk, file descriptor

11.1. OOM Kill

 
dmesg -T | grep -i -E "oom|killed process" journalctl -k --since "6 hours ago" | grep -i oom

11.2. Disk full / inode full

 
df -h df -ih

11.3. Too many open files

 
sudo lsof | wc -l sudo cat /proc/$(pgrep -o php-fpm8.3)/limits | grep "open files" 

12. “Playbook” 5 phút khi web lỗi bất ngờ

  1. Xác định mã lỗi (502/504/500/403)

  2. tail -n 200 Nginx error log

  3. journalctl -u php8.3-fpm --since "1 hour ago"

  4. Tìm dấu vết: pm.max_children, timeout, memory exhausted, permission denied

  5. Nếu nghi DB: xem slow query / trạng thái MariaDB

  6. Nếu nghi OOM/disk: kiểm tra kernel log và dung lượng

  7. Chỉ sau khi có bằng chứng mới chỉnh config