Dạo gần đây, sau khi được chuyển qua hoạt động trên nền WordPress Caddy Docker, blog Thuanbui.me này lâu lâu hay bị đơ đơ, các bài viết load mãi không xong. Mình phải thường xuyên truy cập vào VPS để khởi động lại dịch vụ bằng lệnh docker compose restart
thì mới hoạt động lại bình thường. Tuy nhiên sau vài ngày thì bệnh cũ lại tái phát.
Chú ý: Cách thiết lập trong bài viết này được dựa trên cách thiết lập WordPress trên Caddy Docker mình đã chia sẻ ở đây: [wordpress-caddy-docker] – Cài đặt WordPress nhanh gọn, tối ưu hiệu năng. Bạn cần phải điều chỉnh lại đôi chút nếu cài đặt WordPress bằng cách khác.
Mục Lục
1. Lỗi serve reached pm.max_children setting (5)
Khi kiểm tra log (bằng lệnh docker compose logs
) thì mới thấy cảnh báo như sau
WARNING: [pool www] server reached pm.max_children setting (5), consider raising it
Code language: CSS (css)
Định nghĩ từ ChatGPT: pm.max_children
là một thiết lập quan trọng trong cấu hình của PHP-FPM (PHP FastCGI Process Manager). Nó xác định số lượng tiến trình con (child processes) tối đa mà PHP-FPM có thể tạo ra để xử lý các yêu cầu từ web server.
Cảnh báo “server reached pm.max_children setting (5)” nghĩa là máy chủ đã đạt đến giới hạn số lượng tiến trình con (pm.max_children
) đang được thiết lập (đang là 5). Trong trường hợp, các lượt truy cập sau đó sẽ phải xếp hàng chờ hoặc bị từ chối nếu hàng đợi quá tải, dẫn đến website chậm hoặc có thể bị lỗi 502/503.
Một số nguyên nhân gây ra lỗi này:
- Lưu lượng truy cập cao: Số lượng yêu cầu đồng thời từ người dùng vượt quá khả năng xử lý hiện tại của PHP-FPM.
- Cấu hình PHP-FPM không tối ưu:
pm.max_children
được đặt quá thấp so với nhu cầu thực tế của website. - Thiếu tài nguyên hệ thống:
- RAM không đủ để tạo thêm tiến trình PHP, khiến server bị giới hạn.
- CPU quá tải, khiến các tiến trình hiện tại xử lý chậm.
- Script PHP không tối ưu: Các script hoặc truy vấn cơ sở dữ liệu mất nhiều thời gian để thực thi, dẫn đến các tiến trình PHP bị giữ lại lâu hơn, làm đầy
max_children
. - Tấn công DDoS hoặc bot traffic: Website bị tấn công hoặc bị truy cập bởi các bot có thể tạo ra lượng lớn yêu cầu cùng một lúc.
2. Khắc phục lỗi “server reached pm.max_children setting”
Việc đầu tiên mình cần làm là tăng giá trị pm.max_children
, hiện tại đang được thíet lập quá thấp: 5. Đây là thông số mặc định của PHP-FPM khi cài đặt WordPress bằng Docker.
Mình sẽ đổi lại thông số như sau:
pm = dynamic
pm.max_children = 50
pm.start_servers = 20
pm.min_spare_servers = 10
pm.max_spare_servers = 30
Code language: YAML (yaml)
Giải thích:
pm = dynamic
: Chế độ quản lý tiến trình sẽ được tùy biến linh hoạt tùy nhu cầupm.start_servers = 20
: Khi khởi động, PHP-FPM sẽ khởi tạo 20 tiến trình conpm.max_children = 50
: Nếu nhu cầu tăng lên, PHP-FPM sẽ tạo tạo thêm tiến trình, nhưng không vượt quá 50 tiến trình.pm.min_spare_servers = 10
&pm.max_spare_servers = 30
: Khi không có nhiều yêu cầu, PHP-FPM sẽ duy trì tối thiểu 10 tiến trình nhàn rỗi và tối đa 30 tiến trình nhàn rỗi.
Do WordPress đang được thiết lập bằng Docker, nên mình cần phải tạo thêm file Dockerfile
nằm trong cùng thư mục với file compose.yml
, với nội dung như sau và lưu lại
FROM wordpress:fpm-alpine
# SETUP PHP-FPM CONFIG SETTINGS (max_children / max_requests)
RUN echo 'pm = dynamic' >> /usr/local/etc/php-fpm.d/zz-docker.conf && \
echo 'pm.max_children = 25' >> /usr/local/etc/php-fpm.d/zz-docker.conf && \
echo 'pm.start_servers = 8' >> /usr/local/etc/php-fpm.d/zz-docker.conf && \
echo 'pm.min_spare_servers = 4' >> /usr/local/etc/php-fpm.d/zz-docker.conf && \
echo 'pm.max_spare_servers = 8' >> /usr/local/etc/php-fpm.d/zz-docker.conf && \
echo 'pm.max_requests = 200' >> /usr/local/etc/php-fpm.d/zz-docker.conf && \
echo 'request_terminate_timeout = 30s' >> /usr/local/etc/php-fpm.d/zz-docker.conf
Code language: Dockerfile (dockerfile)
Sau đó đổi lại khai báo trong file compose.yml
, loại bỏ phần khai báo image wordpress (thêm # vào phía trước), và thêm vào dòng build: .
website:
build: .
#image: wordpress:fpm-alpine
Code language: YAML (yaml)
Sau đó cho kích hoạt lại hệ thống
docker compose up -d --build
Code language: Nginx (nginx)
3. Tối ưu PHP Opcache
Để PHP-FPM hoạt động hiệu quả hơn, mình sẽ tối ưu thêm các thông số của Opcache.
Chỉnh sửa file php.user.ini
nằm trong thư mục conf, và thêm vào các dòng sau
[opcache]
opcache.enable=1
opcache.revalidate_freq=0
opcache.validate_timestamps=0
opcache.max_accelerated_files=10000
opcache.memory_consumption=128
opcache.max_wasted_percentage=10
opcache.interned_strings_buffer=16
opcache.fast_shutdown=1
Bạn nào quan tâm ý nghĩa các thông số, có thể tham khảo thông tin chi tiết ở đây:
https://www.scalingphpbook.com/best-zend-opcache-settings-tuning-config/
Sau đó khởi động lại hệ thống bằng lệnh docker compose restart
Sau khi thiết lập và theo dõi một thời gian, blog đã hoạt động mượt mà, không còn bị đơ đơ bất thình lình nữa. Kiểm tra docker logs bằng lệnh docker compose logs | grep max
thì không còn thấy hiện ra cảnh báo nào liên quan đến pm.max_children
.
Nhiệm vụ đã hoàn thành!
Tham khảo:
https://loadforge.com/guides/optimizing-caddy-for-high-performance-php-delivery
https://laravel-news.com/php-opcache-docker
https://www.scalingphpbook.com/best-zend-opcache-settings-tuning-config/
Lưu ý: Nếu bạn cần hỗ trợ kỹ thuật, vui lòng gửi câu hỏi trực tiếp ở phần Thảo luận bên dưới, mình sẽ trả lời sớm. Đừng vào hỏi trong fanpage Yêu Chạy Bộ, sẽ không có phản hồi đâu!