Quantcast
Channel: Local Server Pentest » Nginx
Viewing all articles
Browse latest Browse all 2

Tối ưu hóa Nginx và PHP-FPM

$
0
0

Trong bài viết “Cài đặt Nginx và PHP-FPM trên CentOS 6” mình đã trình về những bước cài đặt và cấu hình cơ bản của Nginx + PHP-FPM. Trong bài viết tiếp theo này mình sẽ trình bày về một số cách tối ưu, giúp chúng ta dễ dàng hơn trong việc quản lý, cũng như duy trì hệ thống Web Server trên nền Nginx.

I – Tối ưu Nginx:

1) Bố trí lại các tệp tin cấu hình:

Thông thường thì các tệp tin cấu hình của Nginx sẽ được lưu trữ trong thư mục “/etc/nginx”. Một cách tổ chức lại việc lưu trữ  tốt hơn theo phong cách của Apache như sau

## Tệp tin cấu hình chính ##
/etc/nginx/nginx.conf

## Tệp tin cấu hình các virtual host ##
/etc/nginx/sites-available/
/etc/nginx/sites-enabled/

## Các tệp tin cấu hình khác... ##
/etc/nginx/conf.d/

Phần tệp tin cấu hình virtual host sẽ có 2 thư mục chính:

  • sites-available: Chứa danh sách các file cấu hình khác nhau như: file cấu hình hoàn chỉnh, file cấu hình tạm thời, file cấu hình lỗi,…Lưu trữ những tệp tin cấu hình mà ta hiện có.
  • sites-enabled: Chứa danh sách các symbolic link trỏ tới các tệp tin cấu hình hoàn chỉnh, đã tối ưu ở thư mục sites-available.

nginx-php-fpm-config-1

Vì chúng ta tách biệt phần file cấu hình của các virtual host ra lưu trữ riêng nên ta cần phải include dòng địa chỉ thư mục lưu trữ các file cấu hình này vào file cấu hình chính. Ở file nginx.conf ta thêm vào

## Tệp tin cấu hình virtual host. ##
include /etc/nginx/sites-enabled/*;

## Các tệp tin cấu hình khác.../ ##
include /etc/nginx/conf.d/*;

Chú ý: Việc tối ưu lại cách sắp xếp này giúp chúng ta dễ dàng quản lý hệ thống webserver hơn chứ không có tác dụng tới hiệu suất tới hiệu suất.

2) Tối ưu worker_processes:

Với cấu hình mặc định, Nginx sẽ sử dụng một CPU để xử lý các tác vụ của mình. Tùy theo mức độ hoạt động của web server mà chúng ta có thể thay đổi lại thiết lập này. Ví dụ với các web server hay sử dụng về SSL, gzip thì ta nên đặt chỉ số của worker_processes này lên cao hơn. Nếu website của bạn có số lượng các tệp tin tĩnh nhiều, và dung lượng của chúng lớn hơn bộ nhớ RAM thì việc tăng worker_processes sẽ tối ưu băng thông đĩa của hệ thống.

Để xác định số cores của CPU của hệ thống ta có thể thực hiện lệnh

# cat /proc/cpuinfo | grep processor

[root@server ~]# cat /proc/cpuinfo | grep processor
processor    : 0
processor    : 1
processor    : 2
processor    : 3

Như ở trên, CPU của chúng ta có 4 cores. Để thay đổi mức sử dụng CPU của nginx ta sửa tệp tin cấu hình chính

# vi /etc/nginx/nginx.conf

Tại dòng số 3 ta thay đổi giá trị của worker_processes là 4.

nginx-php-fpm-config-2

3) Tối ưu worker_connections:

worker_connections sẽ cho biết số lượng connection mà CPU sẽ xử lý. Mặc định, số lượng connection này được thiết lập là 1024. Để xem về mức giới hạn sử dụng của hệ thống bạn có thể dụng lệnh ulimit

# ulimit –n

nginx-php-fpm-config-3

Con số thiết lập của worker_connections nên nhỏ hơn hoặc bằng giới hạn này!

Nếu bạn đã điều chỉnh lại giá trị worker_processes giúp Nginx sử dụng nhiều cores để xử lý các tác vụ hơn thì có thể thêm dòng cấu hình sau để tăng số lượng clients lên cao nhất

max_clients = worker_processes * worker_connections


4) Tối ưu buffers (bộ nhớ đệm):

Một trong những cấu hình quan trọng để tối ưu Nginx là thiết đặt các giá trị buffer. Nếu bạn thiết lập bộ nhớ buffer quá nhỏ thì sẽ dễ dẫn tới tình trạng “thắt cỗ chai” khi web server của chúng ta tiếp nhận một lượng traffic lớn. Để thay đổi các giá trị buffer này, chúng ta có thể thêm vào các dòng cấu hình ở thẻ http của file cấu hình chínhnginx.conf

client_body_buffer_size 8K;
client_header_buffer_size 1k;
client_max_body_size 2m;
large_client_header_buffers 2 1k;

Trong đó:

  • client_body_buffer_size: Thiết đặt giá trị kích thước của body mà client yêu cầu. Nếu kích thước được yêu cầu lớn hơn giá trị buffer thì sẽ được lưu vào temporary file.
  • client_header_buffer_size: Thiết đặt giá trị kích thước của header mà client yêu cầu. Thông thường thì kích thước này 1K là đủ.
  • client_max_body_size: Thiết đặt giá trị kích thước tối đa của body mà client có thể yêu cầu được, xác định bởi dòng Conent-Length trong header. Nếu kích thước body yêu cầu vượt giới hạn nãy thì client sẽ nhận được thông báo lỗi “Request Entity Too Large” (413).
  • large_client_header_buffers: Thiết đặt giá trị kích về số lượng và kích thước lớn nhất của buffer dùng để đọc các headers có kích thước lớn từ các request của client. Nếu client gửi một header quá lớn Nginx sẽ trả về lỗi “Request URL too large” (414) hoặc “Bad request” (400) nếu header của request quá dài.

Ngoài ra chúng ta cũng cần thiết đặt lại các giá trị timeout để tối ưu hiệu suất hoạt động của web server với các client

client_body_timeout     10;
client_header_timeout   10;
keepalive_timeout       15;
send_timeout            10;

Trong đó:

  • client_body_timeout: Thiết đặt thời gian tải body của webpage từ client. Nếu quá thời gian này, client sẽ nhận thông báo trả về “Request time out” (408).
  • client_header_timeout: Thiết đặt thời gian tải title của webpage từ client. Nếu quá thời gian này, client sẽ nhận thông báo trả về “Request time out” (408).
  • keepalive_timeout: Thiết đặt thời gian sống của kết nối từ client, nếu quá thời gian này thì kết nối sẽ bị đóng.
  • send_timeout: Thiết đặt thời gian phản hồi dữ liệu giữa client và server, nếu quá thời gian này thì nginx sẽ tắt kết nối.

5) Tắt Access Logs:

Mặc định thì Nginx sẽ ghi lại các request lên một file trên đĩa cứng như là một việc ghi logs. Nêu bạn không sử dụng các access logs thì bạn có thể tắt tính năng này đi để giảm bớt thời gian nhập xuất. Để thực hiện điều này, trong thẻ server của file cấu hình chính nginx.conf bạn có thể đặt giá trị sau

access_logs off;

6) Nén các gói dữ liệu gửi đi bằng Gzip

Gzip sẽ giúp nén các dữ liệu trước khi chuyển chúng tới Client. Đây là một cách để tăng tốc độ tuy cập website của cúng ta. Trong thẻ http của file cấu hình chính nginx.conf  ta có thể thêm

gzip              on;
gzip_comp_level   2;
gzip_min_length   1000;
gzip_proxied      expired no-cache no-store private auth;
gzip_types        text/plain application/xml;
gzip_disable      "MSIE [1-6]\.";

7) Cache nội dung các tệp tin tĩnh:

Hầu hết các request từ client tới website của chúng ta để load các nôi dung như: hình ảnh, java script, css, flash,… Chúng ta nên thực hiện việc lưu cache lại các tệp tin có nội dung tĩnh này trên Nginx

location ~* "\.(js|ico|gif|jpg|png|css|html|htm|swf|htc|xml|bmp|cur)$" {
    root            /home/site/public_html;
    add_header      Pragma "public";
    add_header      Cache-Control "public";
    expires         3M;
    access_log      off;
    log_not_found   off;
}

8) Ẩn phiên bản của Nginx:

Việc ẩn đi phiên bản của Nginx từ Server Header sẽ giúp hệ thống webserver của chúng ta được bảo mật tốt hơn. Để thực hiện điều này, trong thẻ http của của tệp tin cấu hình chính nginx.conf ta thêm vào dòng sau

server_tokens off;

9) Thực thi các tệp tin PHP thông qua PHP-FPM:

Ở đây ta có thể sử dụng TCP/IP stack mặc định hoặc dùng trự tiếp Unix Socket Connection. Chúng ta cũng có thể sử dụng PHP-FPM để lắng nghe trên IP:Port (thường là 127.0.0.1:9000).

location ~* \.php$ {
    try_files       $uri /index.php;
    fastcgi_index   index.php;
    fastcgi_pass    127.0.0.1:9000;
    #fastcgi_pass   unix:/var/run/php-fpm/php-fpm.sock;
    include         fastcgi_params;
    fastcgi_param   SCRIPT_FILENAME    $document_root$fastcgi_script_name;
    fastcgi_param   SCRIPT_NAME        $fastcgi_script_name;
}

Chúng ta hoàn toàn có thể tách biệt PHP-FPM và Nginx chạy trên các server khác nhau.

10) Cấm các truy cập tới các tệp tin ẩn trên Nginx:

Đôi khi trên các thư mục web chúng ta có lưu những tệp tin ẩn (bắt đầu với dấu chấm “.”) như .svn, .htaccess. Đây là các tệp tin không mang tính  public đối với người dùng. Để ngăn chặn các truy xuất tới các tệp tin ẩn này ta có thể thêm vào đoạn cấu hình sau

location ~ /\. {
    access_log off;
    log_not_found off;
    deny all;
}

II – Tối ưu PHP-FPM

1) Bố trí lại các tệp tin cấu hình:

Thông thường thì các cấu hình của PHP-FPM được thiết lập trong file cấu hình /etc/php-fpm.conf và ở thư mục/etc/php-fpm.d. Các tệp tin cấu hình khác của PHP-FPM nên đặt trong cùng thư mục/etc/php-fpm.d. Chúng ta có thể thêm dòng cấu hình sau vào file php-fpm.conf để thực hiện điều này

include=/etc/php-fpm.d/*.conf

2) Cấu hình nhiều PHP-FPM Pool:

Đối với PHP-FPM ta có thể tạo ra nhiều pool khác nhau cho các website khác nhau có trên web server. Bằng cách này chúng ta có thể có được các cấu hình cấp phát tài nguyên và nhóm sở hữu khác nhau đối với từn website. Ví dụ ở đây mình tạo 3 pool cho 3 website khác nhau là

/etc/php-fpm.d/site.conf
/etc/php-fpm.d/blog.conf
/etc/php-fpm.d/forums.conf

Các cấu hình mẫu:

/etc/php-fpm.d/site.conf

[site]
listen = 127.0.0.1:9000
user = site
group = site
request_slowlog_timeout = 5s
slowlog = /var/log/php-fpm/slowlog-site.log
listen.allowed_clients = 127.0.0.1
pm = dynamic
pm.max_children = 5
pm.start_servers = 3
pm.min_spare_servers = 2
pm.max_spare_servers = 4
pm.max_requests = 200
listen.backlog = -1
pm.status_path = /status
request_terminate_timeout = 120s
rlimit_files = 131072
rlimit_core = unlimited
catch_workers_output = yes
env[HOSTNAME] = $HOSTNAME
env[TMP] = /tmp
env[TMPDIR] = /tmp
env[TEMP] = /tmp

/etc/php-fpm.d/blog.conf

[blog]
listen = 127.0.0.1:9001
user = blog
group = blog
request_slowlog_timeout = 5s
slowlog = /var/log/php-fpm/slowlog-blog.log
listen.allowed_clients = 127.0.0.1
pm = dynamic
pm.max_children = 4
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
pm.max_requests = 200
listen.backlog = -1
pm.status_path = /status
request_terminate_timeout = 120s
rlimit_files = 131072
rlimit_core = unlimited
catch_workers_output = yes
env[HOSTNAME] = $HOSTNAME
env[TMP] = /tmp
env[TMPDIR] = /tmp
env[TEMP] = /tmp

/etc/php-fpm.d/forums.conf

[forums]
listen = 127.0.0.1:9002
user = forums
group = forums
request_slowlog_timeout = 5s
slowlog = /var/log/php-fpm/slowlog-forums.log
listen.allowed_clients = 127.0.0.1
pm = dynamic
pm.max_children = 10
pm.start_servers = 3
pm.min_spare_servers = 2
pm.max_spare_servers = 4
pm.max_requests = 400
listen.backlog = -1
pm.status_path = /status
request_terminate_timeout = 120s
rlimit_files = 131072
rlimit_core = unlimited
catch_workers_output = yes
env[HOSTNAME] = $HOSTNAME
env[TMP] = /tmp
env[TMPDIR] = /tmp
env[TEMP] = /tmp

3) Cấu hình PHP-FPM Pool Process Manager (pm):

Trong việc quản lý các tiến trình của PHP-FPM ta nên sử dụng cách quản lý động để chỉ khởi động những tiến trình khi cần thiết. Các cấu hình ở đây cũng tương tự như là cấu hình các thông số của worker_porcess vàworker_connection của Nginx mà mình đã trình bày ở trên. Tùy theo lượng truy cập tới website của chúng ta và dung lượng bộ nhớ RAM của web server hiện có mà ta có các cách cấu hình cho phù hợp.

Giải sử Web Server của chúng ta có 512 MB ram, ở những lúc website có lượng truy cập cao, ta check dung lượng bộ nhớ RAM hiện đang dùng (bằng lệnh top chẳn hạn). Dung lượng RAM được cấp phát cho PHP-FPM là 220 MB, mỗi tiến trình của nó sử dụng 24 MB. Ta có thể tính được giá trị của max_children là 220/24 = 9.17.

Vậy giá trị pm.max_children ta nên thiết đặt cho web server là 9.

Trong file cấu hình pool của website ta có thể có cấu hình mẫu như sau:

pm.max_children = 9
pm.start_servers = 3
pm.min_spare_servers = 2
pm.max_spare_servers = 4
pm.max_requests = 200

Mặc định thì số lượng request ở mỗi tiến trình là không bị giới hạn. Tuy nhiên ta nên thiết đặt lại nó ở một giá trị xác định để tránh các vấn đề về bộ nhớ. Như ở ví dụ trên pm.max_requests được gán giá trị là 200.



Viewing all articles
Browse latest Browse all 2

Latest Images

Trending Articles





Latest Images