Một ngày đẹp trời, bài viết trên blog bất ngờ viral. Traffic tăng từ 200 visitors/giờ lên 2000. OpenLiteSpeed đang chạy ngon lành bỗng dưng bắt đầu trả lỗi 503. CPU nhảy lên 95%. PHP workers cạn kiệt. MySQL connection pool đầy. Và bạn thì cuống lên vì không biết chuyện gì đang xảy ra.
Đó là lý do mình viết bài này. Sau hơn 2 năm vận hành WordPress trên OpenLiteSpeed, trải qua không biết bao nhiêu lần traffic spike — từ chiến dịch affiliate, bài bị share viral trên Facebook, đến những đợt Google bot crawl ác liệt — mình nhận ra một điều: monitoring và troubleshooting không phải chuyện chỉ làm khi có vấn đề, mà là thứ phải setup từ ngày đầu.
Bài này là phần 5 trong series OpenLiteSpeed WordPress, nối tiếp bài tối ưu hình ảnh, CDN và database và bảo mật toàn diện. Nếu bạn chưa đọc bài so sánh OpenLiteSpeed vs Nginx vs Apache hoặc hướng dẫn cài đặt. Khuyến khích ghé qua trước để có đủ context.
Nội dung chính
- Monitoring OpenLiteSpeed: Real-Time Stats và Server Status
- Phân Tích Log: error.log, access.log, Log Rotation
- Monitoring Tools: Prometheus + Grafana, Netdata, htop/atop/iotop
- Tối Ưu Khi Traffic Tăng: Worker, PHP, Connection, Keep-Alive
- PHP Tuning Cho High Traffic: OPcache, Memory, Process Manager
- MySQL/MariaDB Tuning Cho High Traffic
- Troubleshooting: 503, 504, High CPU, High Memory, Slow Queries
- Auto-Scaling: Khi Nào Nâng Cấp VPS
- Load Testing: wrk, ab, hey — Benchmark Trước Khi Launch
Monitoring OpenLiteSpeed: Real-Time Stats và Server Status
Real-Time Stats trong Admin Panel
OpenLiteSpeed Admin Panel (mặc định tại https://your-server:7080) có một trang Real-Time Statistics khá tiện lợi. Nó hiển thị ngay trên dashboard:
- Số request đang xử lý (in-progress requests)
- Số connection đang active
- Bandwidth usage theo thời gian thực
- Thống kê từng Virtual Host
- SSL connection count
Cá nhân mình check trang này khá thường xuyên, đặc biệt khi có chiến dịch chạy ads hoặc bài viết đang được share nhiều. Cách truy cập: đăng nhập Admin Panel, vào Actions > Real-Time Stats. Refresh mỗi 5 giây.
Một con số mình luôn theo dõi là Idle Workers. Nếu con số này chạm 0 thường xuyên, nghĩa là server đang quá tải — bạn cần tăng worker hoặc tối ưu PHP. Mình sẽ nói chi tiết hơn ở phần tuning bên dưới.
server-status và apachectl status
OpenLiteSpeed hỗ trợ module mod_status tương thích Apache, cho phép xem trạng thái server qua browser hoặc command line.
Trước tiên, bật server-status trong Admin Panel:
# Vào Admin Panel > Server > General
# Tìm "Enable Server Status" → bật On
# Hoặc thêm vào httpd_config.conf:
<Location /server-status>
SetHandler server-status
Order deny,allow
Deny from all
Allow from 127.0.0.1
Allow from YOUR_IP
</Location>
Sau đó truy cập http://your-server/server-status để xem chi tiết: mỗi worker đang làm gì, request nào đang xử lý, bao lâu rồi, PID bao nhiêu. Rất hữu ích khi cần debug xem request nào đang treo.
Từ command line:
# Xem tổng quan curl -s http://127.0.0.1/server-status?auto # Xem chi tiết từng worker curl -s http://127.0.0.1/server-status # Dùng apachectl (nếu cài) apachectl status
Mình thường pipe output của server-status?auto vào script monitoring tự viết để gửi alert khi idle workers dưới ngưỡng nhất định.
Phân Tích Log: error.log, access.log, Log Rotation
Vị trí log files
Mặc định, OpenLiteSpeed lưu log tại:
- Error log:
/usr/local/lsws/logs/error.log - Access log:
/usr/local/lsws/logs/access.log - Virtual Host error log:
/usr/local/lsws/logs/YOUR_DOMAIN/error.log - Virtual Host access log:
/usr/local/lsws/logs/YOUR_DOMAIN/access.log
Phân tích error.log
Error log là người bạn thân nhất khi troubleshooting. Các lỗi mình gặp thường xuyên nhất:
# Xem 100 dòng error gần nhất tail -100 /usr/local/lsws/logs/error.log # Theo dõi real-time tail -f /usr/local/lsws/logs/error.log # Lọc lỗi 503 grep "503" /usr/local/lsws/logs/error.log | tail -50 # Lỗi PHP fatal grep "Fatal error" /usr/local/lsws/logs/YOUR_DOMAIN/error.log # Lỗi connection refused (PHP workers hết) grep "Connection refused" /usr/local/lsws/logs/error.log # Lỗi timeout grep "timed out" /usr/local/lsws/logs/error.log
Một pattern mình hay thấy: khi PHP workers cạn kiệt, error log sẽ xuất hiện hàng loạt dòng [ERROR] [lsphp] Connection refused hoặc [ERROR] Failed to create LSAPI connection. Đây là dấu hiệu rõ ràng nhất cần tăng PHP_LSAPI_CHILDREN hoặc tối ưu code.
Phân tích access.log
Access log cho bạn biết chính xác ai đang truy cập cái gì, bao nhiêu request, mất bao lâu:
# Top 10 IP truy cập nhiều nhất
awk '{print $1}' /usr/local/lsws/logs/YOUR_DOMAIN/access.log | sort | uniq -c | sort -rn | head -10
# Top 10 URL được request nhiều nhất
awk '{print $7}' /usr/local/lsws/logs/YOUR_DOMAIN/access.log | sort | uniq -c | sort -rn | head -10
# Request trả mã 503
grep " 503 " /usr/local/lsws/logs/YOUR_DOMAIN/access.log | wc -l
# Request chậm (>2 giây)
awk '$NF > 2 {print $0}' /usr/local/lsws/logs/YOUR_DOMAIN/access.log | tail -50
# Bandwidth theo giờ (để detect traffic spike)
awk '{print $4}' /usr/local/lsws/logs/YOUR_DOMAIN/access.log | cut -d: -f2 | sort | uniq -c
Mình có một tips nhỏ: tạo alias trong .bashrc cho những lệnh này, đỡ phải gõ lại mỗi lần:
alias ols-error='tail -50 /usr/local/lsws/logs/error.log'
alias ols-access='tail -50 /usr/local/lsws/logs/YOUR_DOMAIN/access.log'
alias ols-topip='awk "{print \$1}" /usr/local/lsws/logs/YOUR_DOMAIN/access.log | sort | uniq -c | sort -rn | head -20'
alias ols-slow='awk "\$NF > 2" /usr/local/lsws/logs/YOUR_DOMAIN/access.log | tail -30'
Cấu hình Log Rotation
Log files có thể phình to rất nhanh khi traffic cao. Mình từng thấy access.log tăng 2GB/ngày trên một site có 50K visitors/ngày. Nếu không cấu hình rotation, disk sẽ đầy.
OpenLiteSpeed hỗ trợ log rotation built-in. Cấu hình trong Admin Panel:
# Vào Virtual Host > YOUR_DOMAIN > Log
# Access Log > Rotation:
# - Rotate Size: 100M (rotate khi file đạt 100MB)
# - Keep Days: 30 (giữ log 30 ngày)
# - Compress: Yes (gzip tiết kiệm disk)
# Hoặc dùng logrotate của hệ thống
# Tạo file /etc/logrotate.d/openlitespeed:
/usr/local/lsws/logs/*.log /usr/local/lsws/logs/*/*.log {
daily
rotate 30
compress
delaycompress
missingok
notifempty
sharedscripts
postrotate
/usr/local/lsws/bin/lswsctrl refresh
endscript
}
Mình dùng cách thứ hai (logrotate hệ thống) vì nó linh hoạt hơn và tích hợp tốt với các monitoring tool. Đừng quên lswsctrl refresh ở postrotate, không thì OpenLiteSpeed sẽ tiếp tục ghi vào file cũ đã rename.
Monitoring Tools: Prometheus + Grafana, Netdata, htop/atop/iotop
Bây giờ đến phần thú vị — tool monitoring. Mình sẽ chia làm 2 nhóm: lightweight (chạy nhanh, ít tài nguyên) và full-stack (setup nhiều nhưng mạnh hơn).
Nhóm Lightweight: htop, atop, iotop
Nhóm này không cần cài đặt gì phức tạp, mở terminal lên là dùng ngay.
htop — xem CPU, RAM, process real-time:
sudo apt install htop htop # Tips: press F5 để tree view, F6 để sort, F9 để kill process # Filter theo lsphp để xem PHP processes # Press F4, gõ "lsphp"
Khi dùng htop, mình chú ý mấy thứ sau:
- Số lượng
lsphpprocess — nếu liên tục bằngPHP_LSAPI_CHILDRENthì cần tăng - CPU usage của mỗi
lsphp— nếu tất cả đều cao thì code cần tối ưu - Memory usage tổng — để xem có bị OOM không
- Load average — nếu cao hơn số CPU core thì server đang quá tải
atop — ghi lại lịch sử resource usage, rất hữu ích khi muốn xem lại “1 tiếng trước chuyện gì đã xảy ra”:
sudo apt install atop sudo systemctl enable atop # Xem lại log tại thời điểm cụ thể atop -r /var/log/atop/atop_20260525 # Trong atop: press 'm' cho memory, 'd' cho disk, 'n' cho network # Press 't' để đi tới snapshot tiếp theo, 'T' để lùi lại
iotop — xem process nào đang đọc/ghi disk nhiều nhất:
sudo apt install iotop sudo iotop -o # chỉ hiển thị process đang I/O active
iotop đặc biệt hữu ích khi bạn thấy server chậm nhưng CPU và RAM vẫn thấp — rất có thể disk I/O là bottleneck (thường gặp với VPS dùng HDD hoặc SSD rẻ).
Netdata: Monitoring Đầy Đủ, Cài Đặt Nhanh
Nếu bạn muốn một dashboard monitoring đẹp mà không tốn công setup, Netdata là lựa chọn số 1. Nó tự detect gần như mọi service đang chạy trên server.
# Cài đặt (1 lệnh) bash <(curl -Ss https://my-netdata.io/kickstart.sh) # Truy cập dashboard # http://your-server:19999 # Netdata tự detect: CPU, RAM, disk, network, processes, containers # Và cả: nginx, apache, mysql/mariadb, php-fpm (và LSAPI với config thêm)
Netdata consume khoảng 1-3% CPU và 100-200MB RAM — hoàn toàn chấp nhận được cho VPS 2GB trở lên. Dashboard real-time cập nhật mỗi giây, có chart đẹp, có alerting built-in.
Mình đặc biệt thích tính năng alarm của Netdata. Có thể cấu hình alert khi:
- CPU usage > 80% trong 5 phút
- RAM usage > 90%
- Disk I/O latency > 100ms
- Số TCP connection > 1000
- Process count bất thường
Alert gửi qua email, Slack, Telegram, Discord — tùy bạn cấu hình. Mình dùng Telegram cho tiện vì bot đã có sẵn trên điện thoại.
Prometheus + Grafana: Monitoring Chuyên Nghiệp
Nếu bạn quản lý nhiều server hoặc cần dashboard tùy chỉnh, Prometheus + Grafana là bộ đôi kinh điển. Setup phức tạp hơn nhưng bù lại cực kỳ mạnh mẽ.
Kiến trúc đơn giản: Node Exporter (thu thập metrics từ server) → Prometheus (lưu trữ time-series data) → Grafana (visualize dashboard).
# 1. Cài Node Exporter (trên server cần monitor)
wget https://github.com/prometheus/node_exporter/releases/latest/download/node_exporter-*.linux-amd64.tar.gz
tar xvfz node_exporter-*.tar.gz
sudo mv node_exporter-*/node_exporter /usr/local/bin/
# Tạo systemd service
sudo tee /etc/systemd/system/node_exporter.service <<EOF
[Unit]
Description=Node Exporter
After=network.target
[Service]
User=node_exporter
ExecStart=/usr/local/bin/node_exporter
[Install]
WantedBy=multi-user.target
EOF
sudo useradd -rs /bin/false node_exporter
sudo systemctl daemon-reload
sudo systemctl enable --now node_exporter
# Node Exporter chạy ở port 9100
# 2. Cài Prometheus (trên server monitoring hoặc cùng server)
wget https://github.com/prometheus/prometheus/releases/latest/download/prometheus-*.linux-amd64.tar.gz
tar xvfz prometheus-*.tar.gz
# Cấu hình prometheus.yml
scrape_configs:
- job_name: 'openlitespeed'
static_configs:
- targets: ['YOUR_SERVER_IP:9100']
# 3. Cài Grafana
sudo apt install -y apt-transport-https software-properties-common
sudo wget -q -O /usr/share/keyrings/grafana.key https://apt.grafana.com/gpg.key
echo "deb [signed-by=/usr/share/keyrings/grafana.key] https://apt.grafana.com stable main" | sudo tee /etc/apt/sources.list.d/grafana.list
sudo apt update && sudo apt install grafana
sudo systemctl enable --now grafana-server
# Grafana chạy ở port 3000
Sau khi kết nối Prometheus với Grafana, bạn có thể import dashboard có sẵn (tìm “Node Exporter Full” trên Grafana marketplace — dashboard ID 1860). Dashboard này hiển thị gần như mọi metric bạn cần.
Để monitor OpenLiteSpeed cụ thể, mình viết thêm một script nhỏ export OLS stats ra format Prometheus:
#!/bin/bash
# /usr/local/bin/ols_metrics.sh
# Chạy qua cron mỗi 15 giây
STATUS=$(curl -s http://127.0.0.1/server-status?auto)
echo "# HELP ols_idle_workers Number of idle workers"
echo "# TYPE ols_idle_workers gauge"
IDLE=$(echo "$STATUS" | grep "IdleWorkers" | awk '{print $2}')
echo "ols_idle_workers $IDLE"
echo "# HELP ols_busy_workers Number of busy workers"
echo "# TYPE ols_busy_workers gauge"
BUSY=$(echo "$STATUS" | grep "BusyWorkers" | awk '{print $2}')
echo "ols_busy_workers $BUSY"
echo "# HELP ols_total_accesses Total accesses"
echo "# TYPE ols_total_accesses counter"
ACCESSES=$(echo "$STATUS" | grep "Total Accesses" | awk '{print $3}')
echo "ols_total_accesses $ACCESSES"
echo "# HELP ols_bytes_per_sec Bytes per second"
echo "# TYPE ols_bytes_per_sec gauge"
BPS=$(echo "$STATUS" | grep "BytesPerSec" | awk '{print $2}')
echo "ols_bytes_per_sec $BPS"
Nói thật, cho một VPS đơn lẻ chạy 1-2 site WordPress thì Netdata đủ dùng rồi. Prometheus + Grafana chỉ thực sự cần thiết khi bạn có nhiều server hoặc cần alerting phức tạp. Mình dùng Netdata cho VPS nhỏ và Prometheus cho cụm server lớn hơn.
Tối Ưu Khi Traffic Tăng: Worker, PHP, Connection, Keep-Alive
Đây là phần quan trọng nhất. Khi traffic tăng, bạn cần điều chỉnh nhiều thông số. Mình sẽ đi qua từng cái một, kèm theo con số thực tế từ kinh nghiệm.
Worker và Process Tuning
OpenLiteSpeed sử dụng event-driven architecture tương tự Nginx, nên mỗi worker có thể xử lý hàng ngàn connection đồng thời. Không giống Apache phải spawn process cho mỗi request.
Cấu hình worker trong Admin Panel: Server > General > Worker Processes
- Number of Workers: Mặc định 1. Mình set bằng số CPU core. VPS 2 core = 2 workers, 4 core = 4 workers. Không nên set quá số core vì context switching sẽ làm chậm.
- Max Connections: Mặc định 10000. Với VPS 2GB RAM, mình set 5000. Với 4GB, set 10000. Mỗi connection tiêu tốn khoảng 4-8KB memory, nên 10000 connections chỉ tốn ~80MB — rất nhẹ.
- Max SSL Connections: Set bằng Max Connections vì phần lớn traffic hiện tại là HTTPS.
Cấu hình qua file httpd_config.conf:
# /usr/local/lsws/conf/httpd_config.conf workerProcesses 2 # = số CPU core maxConnections 5000 # VPS 2GB RAM maxSSLConnections 5000 maxReqBodySize 100M # upload limit # Connection timeout connTimeout 300 # 5 phút keepAliveTimeout 5 # 5 giây (quan trọng - xem bên dưới)
Keep-Alive Tuning
Keep-Alive cho phép client tái sử dụng TCP connection cho nhiều request, giảm overhead tạo connection mới. Nhưng nếu set quá cao, connection sẽ nằm im và tiêu tốn resource.
Mình recommend:
keepAliveTimeout: 5 giây — đủ cho browser load assets (CSS, JS, images) trên cùng connection, nhưng không giữ quá lâumaxKeepAliveReq: 1000 — giới hạn số request trên mỗi keep-alive connection
Một sai lầm mình từng thấy: set keepAliveTimeout quá cao (30-60 giây). Với traffic cao, hàng ngàn connection keep-alive sẽ ngốn hết worker. 5 giây là sweet spot cho phần lớn trường hợp.
Connection Limits và Throttling
OpenLiteSpeed có built-in connection throttling, rất hữu ích để chống DDoS nhẹ và bot crawl quá mức:
# Vào Virtual Host > YOUR_DOMAIN > General > Throttling # Hoặc thêm vào vhost config: <VirtualHost YOUR_DOMAIN> # Giới hạn mỗi IP tối đa 20 connection đồng thời ConnLimit 20 # Giới hạn bandwidth mỗi IP: 500KB/s Bandwidth 500K # Rate limiting: 30 request/giây/IP RateLimit 30 </VirtualHost>
Mình set ConnLimit 20 cho site WordPress bình thường. Nếu site có download file lớn thì tăng lên. RateLimit 30 request/giây là hợp lý — bot crawl ác liệt thường gửi 50-100 request/giây, nên 30 sẽ chặn được phần lớn mà không ảnh hưởng user thật.
PHP Tuning Cho High Traffic: OPcache, Memory, Process Manager
PHP thường là bottleneck lớn nhất trên WordPress. Một request WordPress gốc (không cache) có thể load 50-100 file PHP, query database 20-30 lần. May mà OpenLiteSpeed dùng LSAPI — giao thức kết nối PHP nhanh hơn PHP-FPM khoảng 20-30% theo benchmark của chính LiteSpeed.
LSAPI Process Tuning
Biến môi trường quan trọng nhất:
# Trong Admin Panel > Server > LSAPI App > lsphp8x # Hoặc thêm vào /usr/local/lsws/conf/httpd_config.conf # Số PHP process tối đa PHP_LSAPI_CHILDREN=40 # Số request mỗi process xử lý trước khi restart # (tránh memory leak) PHP_LSAPI_MAX_REQUESTS=500 # Idle timeout: kill process nếu idle quá lâu LSAPI_MAX_IDLE=300 # Keep connection alive LSAPI_PKEEP_CONN=1
Bảng tham khảo PHP_LSAPI_CHILDREN theo RAM:
- 1GB RAM: 10-15 children (mỗi process WordPress ~40-60MB)
- 2GB RAM: 20-30 children
- 4GB RAM: 40-60 children
- 8GB RAM: 80-120 children
Lưu ý: con số trên là tối đa. Thực tế WordPress với LSCache enabled, phần lớn request được serve từ cache (không chạm PHP). Chỉ những request miss cache (admin page, dynamic content, first visit) mới cần PHP process. Nên bạn không cần quá nhiều children nếu cache được cấu hình tốt.
Trên site mình, với 2GB RAM và LSCache enabled, 20 PHP children xử lý thoải mái 500 concurrent visitors. Không cache thì 20 children chỉ chịu nổi khoảng 50 concurrent.
OPcache Cấu Hình
OPcache cache compiled PHP bytecode vào shared memory, bỏ qua bước parse và compile. Kết quả: giảm CPU 30-50% và tăng throughput đáng kể.
# Thêm vào php.ini hoặc /usr/local/lsws/lsphp8x/etc/php/8.x/litespeed/php.ini [opcache] opcache.enable=1 opcache.enable_cli=0 opcache.memory_consumption=256 # 256MB cho OPcache (site lớn cần 512MB) opcache.interned_strings_buffer=32 # 32MB strings pool opcache.max_accelerated_files=60000 # WordPress có rất nhiều file opcache.validate_timestamps=0 # Tắt auto-revalidate trong production opcache.save_comments=1 # Cần cho annotations opcache.fast_shutdown=1 # Shutdown nhanh hơn opcache.jit_buffer_size=128M # JIT cho PHP 8.x
Lưu ý quan trọng về validate_timestamps=0: khi tắt, OPcache sẽ không tự detect file PHP thay đổi. Bạn cần restart LSAPI process sau khi update code (update plugin, theme, hoặc WordPress core). Mình làm điều này qua script:
#!/bin/bash # /usr/local/bin/lsphp-restart # Restart tất cả LSAPI process để reload OPcache kill -9 $(pgrep -f lsphp) echo "LSAPI processes killed. OpenLiteSpeed sẽ tự spawn lại."
Nếu bạn hay update code thường xuyên và không muốn restart thủ công, set validate_timestamps=1 và revalidate_freq=60 (kiểm tra mỗi 60 giây). Nhưng đánh đổi bằng performance giảm khoảng 5-10%.
memory_limit và max_execution_time
# php.ini memory_limit = 256M # WordPress gốc cần 40-60MB, WooCommerce cần 256MB max_execution_time = 30 # 30 giây đủ cho phần lớn request max_input_time = 60 # 60 giây cho upload lớn post_max_size = 64M # POST data limit upload_max_filesize = 64M # Upload limit max_file_uploads = 20 # Số file upload đồng thời
Một sai lầm phổ biến: set memory_limit quá cao (512M, 1G) vì nghĩ rằng “càng nhiều càng tốt”. Sai. Nếu mỗi PHP process được phép dùng 512MB và bạn có 40 children, worst case là 20GB RAM. VPS 2GB của bạn sẽ OOM ngay lập tức.
Set memory_limit vừa đủ. WordPress thông thường 128MB là thừa. WooCommerce 256MB. Chỉ tăng nếu bạn thấy Fatal error: Allowed memory size exhausted trong log.
MySQL/MariaDB Tuning Cho High Traffic
Database thường là bottleneck thứ hai sau PHP. WordPress gửi trung bình 15-30 query mỗi page load (không cache). Với traffic cao, database có thể trở thành nút thắt chính.
InnoDB Buffer Pool
Đây là thông số quan trọng nhất. Buffer Pool là nơi MySQL cache data và index trong RAM. Truy cập data từ RAM nhanh hơn từ disk khoảng 100-1000 lần.
# /etc/mysql/mariadb.conf.d/50-server.cnf (hoặc /etc/my.cnf) [mysqld] # InnoDB Buffer Pool: 50-70% tổng RAM # VPS 2GB → 1GB cho MySQL, 1GB cho OS + PHP + OLS innodb_buffer_pool_size = 1G # VPS 4GB → 2GB # innodb_buffer_pool_size = 2G # VPS 8GB → 5GB # innodb_buffer_pool_size = 5G # Số instance (1 instance cho mỗi 1GB buffer pool) innodb_buffer_pool_instances = 1 # Log file size (25% buffer pool) innodb_log_file_size = 256M # Flush method (O_DIRECT tránh double buffering) innodb_flush_method = O_DIRECT # Flush mỗi giây thay vì mỗi transaction (nhanh hơn, rủi ro mất data rất thấp) innodb_flush_log_at_trx_commit = 2
Cách kiểm tra Buffer Pool hit rate:
# Vào MySQL/MariaDB console
mysql -u root -p
# Xem Buffer Pool statistics
SHOW STATUS LIKE 'Innodb_buffer_pool_read%';
# Innodb_buffer_pool_read_requests: số lần đọc từ pool (RAM)
# Innodb_buffer_pool_reads: số lần phải đọc từ disk
# Tính hit rate:
# Hit Rate = 1 - (reads / read_requests) * 100
# Mục tiêu: > 95%
# Xem nhanh
SELECT
ROUND(100 - (
(SELECT VARIABLE_VALUE FROM performance_schema.global_status
WHERE VARIABLE_NAME='Innodb_buffer_pool_reads') /
(SELECT VARIABLE_VALUE FROM performance_schema.global_status
WHERE VARIABLE_NAME='Innodb_buffer_pool_read_requests')
) * 100, 2) AS 'Buffer Pool Hit Rate %';
Nếu hit rate dưới 95%, bạn cần tăng innodb_buffer_pool_size hoặc tối ưu query để đọc ít data hơn.
Connection Pooling và Max Connections
# [mysqld] trong my.cnf # Số connection tối đa max_connections = 100 # Mặc định 151, giảm xuống cho VPS nhỏ # Connection timeout (kill connection idle) wait_timeout = 600 # 10 phút interactive_timeout = 600 # Thread cache (tái sử dụng thread cho connection mới) thread_cache_size = 50 # Table cache (giảm mở/đóng file) table_open_cache = 4000 table_definition_cache = 2000 # Sort buffer (cho ORDER BY, GROUP BY) sort_buffer_size = 2M # Không set quá cao! join_buffer_size = 2M
Một lỗi mình thường thấy: set max_connections quá cao (500, 1000) trên VPS nhỏ. Mỗi MySQL connection tiêu tốn khoảng 2-5MB RAM. 500 connections = 1-2.5GB RAM chỉ cho connections. Trên VPS 2GB, set 100-150 connections là tối đa.
Query Cache (MariaDB) hoặc Tắt Query Cache (MySQL 8+)
MariaDB vẫn hỗ trợ query cache, và nó hữu ích cho WordPress:
# MariaDB only query_cache_type = 1 query_cache_size = 64M # Không quá 128M query_cache_limit = 2M # Không cache query kết quả lớn hơn 2MB
Nhưng nếu bạn dùng LSCache (như đã hướng dẫn trong bài 3), phần lớn page load không chạm database. Query cache chỉ hữu ích cho admin page và page miss cache. Nên 64MB là đủ.
Slow Query Log
# Bật slow query log để bắt query chậm slow_query_log = 1 slow_query_log_file = /var/log/mysql/slow.log long_query_time = 2 # Log query chậm hơn 2 giây log_queries_not_using_indexes = 1 # Log query không dùng index # Phân tích slow query sudo mysqldumpslow -s t /var/log/mysql/slow.log | head -20 # Hoặc dùng pt-query-digest (nếu cài Percona Toolkit) sudo pt-query-digest /var/log/mysql/slow.log
Mình thường bật slow query log khi đang troubleshoot, rồi tắt sau khi xong. Log liên tục sẽ tiêu tốn disk I/O.
Troubleshooting: 503, 504, High CPU, High Memory, Slow Queries
Đây là phần “thực chiến” — những vấn đề mình đã gặp và cách xử lý.
Nguyên nhân phổ biến nhất: PHP workers hết.
OpenLiteSpeed trả 503 khi không thể kết nối đến LSAPI process (PHP). Điều này xảy ra khi:
- Tất cả PHP workers đang bận xử lý request khác
- PHP process bị crash
- LSAPI socket bị lỗi
- Timeout kết nối đến PHP process
Cách chẩn đoán:
# 1. Kiểm tra error log tail -100 /usr/local/lsws/logs/error.log | grep "503\|Connection refused\|LSAPI" # 2. Đếm số PHP process đang chạy pgrep -c lsphp # 3. So với max children grep PHP_LSAPI_CHILDREN /usr/local/lsws/conf/httpd_config.conf # 4. Xem memory usage của PHP processes ps -ylC lsphp --sort:rss | head -20
Cách xử lý:
- Tăng
PHP_LSAPI_CHILDRENnếu RAM còn dư - Kiểm tra có plugin/theme nào chạy query chậm gây block PHP process
- Bật LSCache nếu chưa bật (giảm 90% request đến PHP)
- Tăng
LSAPI_CONN_TIMEOUTtừ 30 lên 60 giây (tạm thời) - Kiểm tra có bot crawl quá mức không (xem access log)
Mình từng gặp một case: plugin WooCommerce gửi email notification mỗi đơn hàng, và email gửi qua SMTP bị timeout 30 giây. Mỗi đơn hàng chiếm 1 PHP process 30 giây. 20 đơn hàng đồng thời = hết workers. Fix bằng cách chuyển sang email queue (WP Mail SMTP với API) thay vì gửi đồng bộ.
504 Gateway Timeout
Nguyên nhân: PHP xử lý quá lâu, vượt quá timeout của LiteSpeed.
# Kiểm tra timeout hiện tại grep "LSAPI_MAX_PROCESS_TIME\|connTimeout" /usr/local/lsws/conf/httpd_config.conf # Tăng timeout (tạm thời, phải fix root cause) # Trong Admin Panel > Server > LSAPI App LSAPI_MAX_PROCESS_TIME=300 # 5 phút (mặc định 300 giây) # Nhưng KHÔNG nên set quá cao — request treo 5 phút là dấu hiệu code có vấn đề
Root cause thường gặp:
- Database query cực chậm (bảng wp_options quá lớn, query không có index)
- External API call bị timeout (payment gateway, email service, social API)
- Plugin encode/giải mã data lớn
- Theme render phức tạp (nhiều template part, shortcode lồng nhau)
High CPU Usage
Khi CPU nhảy lên 90-100%, cách chẩn đoán:
# 1. Xem process nào ăn CPU nhiều nhất top -c -o %CPU | head -20 # 2. Nếu lsphp chiếm CPU cao strace -p $(pgrep -f lsphp | head -1) -c # Chạy vài giây rồi Ctrl+C để xem system call summary # 3. Kiểm tra PHP OPcache có đang hoạt động không php -r "var_dump(opcache_get_status()['opcache_statistics']);" # 4. Kiểm tra cache hit rate php -r " \$s = opcache_get_status(); echo 'Hit rate: ' . \$s['opcache_statistics']['opcache_hit_rate'] . '%\n'; echo 'Cached scripts: ' . \$s['opcache_statistics']['num_cached_scripts'] . '\n'; "
Nếu OPcache hit rate dưới 90%, có thể opcache.memory_consumption quá nhỏ hoặc max_accelerated_files quá ít. Tăng lên và restart.
Nếu MySQL chiếm CPU cao:
# Xem query đang chạy mysql -u root -p -e "SHOW FULL PROCESSLIST;" # Xem query chậm nhất mysqldumpslow -s c /var/log/mysql/slow.log | head -10
High Memory Usage / OOM
# Kiểm tra memory usage tổng free -h # Xem process nào dùng nhiều RAM nhất ps aux --sort=-%mem | head -20 # Kiểm tra swap usage swapon --show vmstat 1 5 # si/so column = swap in/out # Kiểm tra OOM killer log dmesg | grep -i "out of memory\|oom-kill" | tail -20 # Kiểm tra MySQL memory mysql -u root -p -e "SHOW ENGINE INNODB STATUS\G" | grep -A 20 "BUFFER POOL"
Nguyên nhân high memory phổ biến:
- PHP memory_limit quá cao × quá nhiều children = OOM
- MySQL buffer pool quá lớn so với RAM khả dụng
- Plugin WordPress leak memory (wp-cron chạy liên tục, transient không cleanup)
- Log file phình to (quên log rotation)
- Backup chạy cùng lúc với traffic cao
Slow Queries — Query WordPress Chậm
WordPress có một số query “infamous” chạy chậm khi database lớn:
# Query phổ biến chạy chậm trên WordPress:
# 1. wp_options autoload = yes (load mỗi page request)
SELECT option_name, option_value FROM wp_options WHERE autoload = 'yes';
# Fix: xoá transient, xoá option rác
# Xem bài 4 trong series: /toi-uu-hinh-anh-cdn-database-wordpress-litespeed/
# 2. Count posts query (chạy trên admin, archive page)
SELECT COUNT(*) FROM wp_posts WHERE post_type='post' AND post_status='publish';
# Fix: index post_type, post_status nếu chưa có
# 3. Meta query phức tạp (WooCommerce, ACF)
SELECT * FROM wp_postmeta WHERE meta_key='_price' AND meta_value BETWEEN 100 AND 500;
# Fix: index meta_key, meta_value; dùng ElasticSearch nếu cần search phức tạp
# Kiểm tra table cần optimize
mysql -u root -p -e "
SELECT table_name,
ROUND(data_length/1024/1024, 2) AS 'Data (MB)',
ROUND(index_length/1024/1024, 2) AS 'Index (MB)',
table_rows
FROM information_schema.tables
WHERE table_schema='YOUR_DB_NAME'
ORDER BY data_length DESC;"
Mình thường chạy database cleanup mỗi tuần như đã hướng dẫn trong bài tối ưu database. Phần lớn vấn đề slow query đến từ bảng wp_options phình to do transient và autoload rác.
Auto-Scaling: Khi Nào Cần Nâng Cấp VPS
Một câu hỏi thường gặp: “Khi nào mình cần nâng cấp VPS?” Đây là câu trả lời dựa trên kinh nghiệm:
Dấu hiệu cần nâng cấp
- CPU load average liên tục > 70% số core (ví dụ: VPS 2 core, load average > 1.4 liên tục)
- RAM > 85% sử dụng, swap active thường xuyên
- Disk I/O wait > 10% (chạy
iostat -x 1để kiểm tra) - PHP workers liên tục full (idle workers = 0 trong Real-Time Stats)
- 503 errors xuất hiện thường xuyên trong giờ cao điểm
- Response time tăng rõ rệt (TTFB > 500ms thường xuyên)
Vertical Scaling (Nâng Cấp VPS Hiện Tại)
Đây là cách dễ nhất — tăng RAM, CPU của VPS hiện tại. Phù hợp cho:
- Site đơn lẻ trên 1 VPS
- Traffic tăng dần đều, không đột biến
- Budget hạn chế
Bảng tham khảo:
- 1 vCPU, 1GB RAM: 500-1000 visitors/ngày, LSCache enabled
- 2 vCPU, 2GB RAM: 5000-10000 visitors/ngày
- 4 vCPU, 4GB RAM: 20000-50000 visitors/ngày
- 4 vCPU, 8GB RAM: 50000-100000 visitors/ngày
- 8 vCPU, 16GB RAM: 100000+ visitors/ngày
Con số trên áp dụng cho WordPress + OpenLiteSpeed + LSCache. Không cache, giảm xuống khoảng 1/5.
Horizontal Scaling (Nhiều Server)
Khi 1 VPS không đủ, bạn cần chia ra nhiều server:
- Web server + Database server riêng: Tách MySQL ra VPS riêng, giảm tải cho web server. Đây là bước đầu tiên mình recommend.
- Load balancer + nhiều web server: Dùng Nginx hoặc LiteSpeed làm load balancer, chia request cho nhiều web server phía sau. Phức tạp hơn vì cần đồng bộ file (glusterFS, rsync) và session (Redis).
- CDN cho static assets: Cloudflare, QUIC.cloud CDN (như đã nói trong bài 4) giảm tải cho origin server đáng kể.
Thành thật mà nói, cho site WordPress cá nhân hoặc doanh nghiệp nhỏ, vertical scaling + CDN + cache tốt sẽ đủ cho hàng trăm ngàn visitors mỗi ngày. Horizontal scaling chỉ thực sự cần khi bạn chạy site lớn kiểu báo điện tử hoặc WooCommerce store cực kỳ đông khách.
Load Testing: wrk, ab, hey — Benchmark Trước Khi Launch
Không bao giờ launch campaign hay chạy ads mà chưa load test trước. Đây là bước “test áp lực” để biết server của bạn chịu được bao nhiêu traffic trước khi vỡ.
wrk — HTTP Benchmarking Hiệu Năng Cao
# Cài wrk sudo apt install wrk # Hoặc compile từ source cho version mới nhất # Test cơ bản: 100 connections, 4 threads, 30 giây wrk -t4 -c100 -d30s https://your-domain.com/ # Output mẫu: # Running 30s test @ https://your-domain.com/ # 4 threads and 100 connections # Thread Stats Avg Stdev Max +/- Stdev # Latency 23.45ms 15.67ms 210.34ms 78.91% # Req/Sec 1.08k 201.34 2.10k 69.50% # 128456 requests in 30.01s, 1.25GB read # Requests/sec: 4280.12 # Transfer/sec: 42.67MB # Test với latency detail wrk -t4 -c100 -d30s --latency https://your-domain.com/ # Test cụ thể page (không cache) wrk -t4 -c50 -d30s https://your-domain.com/a-heavy-page/
ab (Apache Benchmark) — Đơn Giản, Dễ Dùng
# Cài ab sudo apt install apache2-utils # 10000 request, 100 concurrent ab -n 10000 -c 100 https://your-domain.com/ # Output quan trọng: # Requests per second: 4280.12 [#/sec] (mean) # Time per request: 23.362 [ms] (mean) # Time per request: 0.234 [ms] (mean, across all concurrent requests) # Failed requests: 0 # PHẢI = 0 # Non-2xx responses: 0 # PHẢI = 0 # Test với keep-alive ab -n 10000 -c 100 -k https://your-domain.com/
hey — Modern HTTP Load Generator
# Cài hey sudo apt install hey # Hoặc download binary từ GitHub # 200 requests/giây trong 30 giây hey -z 30s -q 200 https://your-domain.com/ # 5000 request, 50 concurrent hey -n 5000 -c 50 https://your-domain.com/ # hey có output đẹp hơn ab, kèm histogram latency
Quy Trình Load Test Mình Dùng
Đây là quy trình mình áp dụng trước mỗi lần launch quan trọng:
- Test homepage (cached): Mục tiêu > 3000 RPS với latency trung bình < 50ms
- Test single post (cached): Mục tiêu > 2000 RPS, latency < 50ms
- Test page miss cache (thêm query string ngẫu nhiên): Mục tiêu > 100 RPS, latency < 500ms
- Test admin page (wp-admin): Mục tiêu > 50 RPS, latency < 1s
- Tăng dần concurrent: 10 → 50 → 100 → 200 → 500, dừng khi bắt đầu có failed requests
- Monitor resource trong lúc test: dùng htop + MySQL processlist để xem bottleneck ở đâu
#!/bin/bash # /usr/local/bin/load-test.sh # Quick load test script DOMAIN="https://your-domain.com" echo "=== Load Test: $DOMAIN ===" echo "" echo "--- Homepage (cached) ---" wrk -t4 -c100 -d10s --latency "$DOMAIN/" echo "" echo "--- Single Post (cached) ---" wrk -t4 -c100 -d10s --latency "$DOMAIN/sample-post/" echo "" echo "--- Miss Cache (random query string) ---" wrk -t4 -c50 -d10s --latency "$DOMAIN/?nocache=$(date +%s)" echo "" echo "--- Admin Login Page ---" wrk -t2 -c20 -d10s --latency "$DOMAIN/wp-login.php" echo "" echo "=== Test Complete ===" echo "Monitor during test: htop, tail -f /usr/local/lsws/logs/error.log"
Chạy script này, mở thêm 2 terminal: 1 cho htop và 1 cho tail -f /usr/local/lsws/logs/error.log. Bạn sẽ thấy rõ server phản ứng thế nào khi có áp lực.
Kinh Nghiệm Thực Tế: Những Bài Học Sau 2 Năm Vận Hành
Nói chung quan, đây là những điều mình đúc kết được sau hơn 2 năm chạy WordPress trên OpenLiteSpeed:
1. Cache Là Vua
Không có tối ưu nào hiệu quả bằng cache đúng cách. LSCache server-level (như đã hướng dẫn trong bài 3) giảm tải PHP và MySQL xuống 90%. Nếu bạn chỉ có thời gian làm 1 việc, hãy đảm bảo LSCache đang hoạt động tốt.
2. Monitor Từ Ngày Đầu
Đừng đợi đến khi có vấn đề mới setup monitoring. Cài Netdata mất 5 phút nhưng sẽ cứu bạn rất nhiều lần. Mình từng mất 3 tiếng debug một đợt sập server chỉ vì không có monitoring, không biết chuyện gì đã xảy ra.
3. Plugin WordPress Là Nguyên Nhân Thường Gặp Nhất
Trong 2 năm, 80% các đợt sập server của mình đều do plugin. Plugin SEO gửi quá nhiều request external, plugin contact form bị spam floods, plugin backup chạy ngốn CPU, plugin tracking ghi log quá nhiều. Hãy audit plugin định kỳ và dùng Query Monitor plugin để phát hiện plugin nặng.
4. Database Cleanup Định Kỳ
Như đã nói trong bài tối ưu database, bảng wp_options phình to là nguyên nhân phổ biến của slow query. Mình chạy cleanup mỗi tuần bằng cron job và chưa bao giờ gặp lại vấn đề database chậm từ đó.
5. Backup Trước Khi Thay Đổi Gì
Nghe hiển nhiên nhưng mình đã từng phá nát server vì chỉnh httpd_config.conf sai một dòng mà không có backup. Giờ mình luôn cp file config trước khi sửa và tag backup với ngày tháng. Chiến lược backup tự động như mình hướng dẫn trong bài bảo mật là bắt buộc.
Tóm Tắt: Checklist Monitoring và Troubleshooting
Setup một lần (ngày đầu)
- Cài Netdata hoặc Prometheus + Grafana
- Bật server-status trong OpenLiteSpeed
- Cấu hình log rotation
- Bật slow query log trong MySQL (tạm thời, tắt sau khi xong)
- Tạo bash alias cho các lệnh log thường dùng
- Setup alerting (Telegram, email) cho CPU/RAM/disk
Kiểm tra hàng ngày
- Check error log:
tail -50 /usr/local/lsws/logs/error.log - Check Real-Time Stats trong Admin Panel (idle workers > 0?)
- Check CPU/RAM/disk qua Netdata dashboard
- Check 503/504 error trong access log
Kiểm tra hàng tuần
- Review slow query log
- Check OPcache hit rate
- Check Buffer Pool hit rate
- Run database cleanup (transients, revisions, autoload)
- Review traffic pattern — có bot nào crawl quá mức không
Kiểm tra hàng tháng
- Load test — chạy benchmark so sánh với tháng trước
- Review resource usage trend — có cần nâng cấp VPS không
- Audit WordPress plugins — có plugin nào nặng, không dùng, hoặc outdated
- Update OpenLiteSpeed, PHP, MariaDB nếu có bản mới
- Kiểm tra backup restore — đảm bảo backup hoạt động
Với bài này, series OpenLiteSpeed WordPress đã khá đầy đủ: từ chọn web server, cài đặt, cấu hình cache, tối ưu hình ảnh/CDN/database, bảo mật, đến monitoring và troubleshooting. Hy vọng series này giúp bạn vận hành WordPress trên OpenLiteSpeed một cách suôn sẻ và tự tin hơn.