Tối ưu hóa PHP-FPM cho hiệu suất cao

PHP ở khắp mọi nơi và được cho là ngôn ngữ được triển khai rộng rãi nhất trên Internet Web.


Tuy nhiên, nó không được biết đến chính xác với khả năng hiệu suất cao, đặc biệt là khi nói đến các hệ thống đồng thời cao. Và đó là lý do mà đối với các trường hợp sử dụng chuyên biệt như vậy, các ngôn ngữ như Node (vâng, tôi biết, nó không phải là ngôn ngữ), Go và Elixir đang chiếm lĩnh.

Điều đó nói rằng, có rất nhiều bạn có thể làm để cải thiện hiệu suất PHP trên máy chủ của bạn. Bài viết này tập trung vào khía cạnh php-fpm của mọi thứ, đây là cách tự nhiên để định cấu hình trên máy chủ của bạn nếu bạn sử dụng Nginx.

Trong trường hợp bạn biết php-fpm là gì, hãy chuyển sang phần tối ưu hóa.

Php-fpm là gì?

Không có nhiều nhà phát triển quan tâm đến DevOps mặt trái của mọi thứ, và ngay cả trong số những người làm, rất ít người biết những gì đang diễn ra dưới mui xe. Thật thú vị, khi trình duyệt gửi yêu cầu đến một máy chủ đang chạy PHP, nó không phải là PHP tạo thành điểm tiếp xúc đầu tiên; thay vào đó, nó là máy chủ HTTP, máy chủ chính là Apache và Nginx. Sau đó, các máy chủ web của Wikipedia này phải quyết định cách kết nối với PHP và truyền loại yêu cầu, dữ liệu và tiêu đề cho nó.

Chu trình phản hồi yêu cầu trong trường hợp PHP (Tín dụng hình ảnh: ProinerTech)

Trong các ứng dụng PHP hiện đại, tập tin tìm kiếm trên mạng Phần trên là tệp index.php, máy chủ được cấu hình để ủy thác tất cả các yêu cầu.

Bây giờ, chính xác thì máy chủ web kết nối với PHP đã phát triển như thế nào và bài viết này sẽ bùng nổ về chiều dài nếu chúng ta đi sâu vào tất cả các nitty-gritty. Nhưng đại khái, trong thời gian mà Apache thống trị là máy chủ web được lựa chọn, PHP là một mô-đun được bao gồm trong máy chủ.

Vì vậy, bất cứ khi nào nhận được yêu cầu, máy chủ sẽ bắt đầu một quy trình mới, nó sẽ tự động bao gồm PHP và thực hiện nó. Phương thức này được gọi là mod_php, viết tắt của php php là một mô-đun. Cách tiếp cận này có những hạn chế, mà Nginx đã vượt qua với php-fpm.

Trong php-fpm, trách nhiệm quản lý PHP, các quy trình nằm trong chương trình PHP trong máy chủ. Nói cách khác, máy chủ web (Nginx, trong trường hợp của chúng tôi), không quan tâm đến việc PHP đang ở đâu và nó được tải như thế nào, miễn là nó biết cách gửi và nhận dữ liệu từ nó. Nếu bạn muốn, bạn có thể coi PHP trong trường hợp này là một máy chủ khác, nó quản lý một số quy trình PHP con cho các yêu cầu đến (vì vậy, chúng tôi có yêu cầu đến một máy chủ, được máy chủ nhận và chuyển đến máy chủ – khá điên! :-P).

Nếu bạn đã thực hiện bất kỳ thiết lập Nginx nào, hoặc thậm chí chỉ cần sử dụng chúng, bạn sẽ bắt gặp một cái gì đó như thế này:

vị trí ~ \ .php $ {
thử_files $ uri = 404;
fastcgi_split_path_info ^ (. + \. php) (/.+) $;
fastcgi_pass unix: /run/php/php7.2-fpm.sock;
fastcgi_index index.php;
bao gồm fastcgi_params;
fastcgi_param SCRIPT_FILENAME $ document_root $ fastcgi_script_name;
}

Dòng mà chúng tôi quan tâm là đây: fastcgi_pass unix: /run/php/php7.2-fpm.sock;, cho biết Nginx giao tiếp với quy trình PHP thông qua ổ cắm có tên php7.2-fpm.sock. Vì vậy, đối với mỗi yêu cầu đến, Nginx ghi dữ liệu qua tệp này và khi nhận được đầu ra, hãy gửi lại cho trình duyệt.

Một lần nữa, tôi phải nhấn mạnh rằng đây không phải là bức tranh đầy đủ nhất hoặc chính xác nhất về những gì đang diễn ra, nhưng nó hoàn toàn chính xác cho hầu hết các nhiệm vụ DevOps.

Bên cạnh đó, hãy để lại tóm tắt những gì chúng ta đã học được cho đến nay:

  • PHP không trực tiếp nhận các yêu cầu được gửi bởi trình duyệt. Các máy chủ web như Nginx trước tiên chặn chúng.
  • Máy chủ web biết cách kết nối với quy trình PHP và truyền tất cả dữ liệu yêu cầu (nghĩa đen là dán mọi thứ) vào PHP.
  • Khi PHP hoàn thành xong phần của nó, nó sẽ gửi phản hồi trở lại máy chủ web, nó sẽ gửi lại cho máy khách (hoặc trong trình duyệt, trong hầu hết các trường hợp).

Hoặc đồ họa:

Cách thức PHP và Nginx phối hợp với nhau (Tín dụng hình ảnh: DataDog)

Tuyệt vời cho đến nay, nhưng bây giờ đến câu hỏi đáng giá triệu đô la: chính xác thì PHP-FPM là gì?

Phần của phần mềm FPMM trong PHP là viết tắt của phần mềm quản lý quy trình nhanh của Windows tắt bởi trình quản lý quy trình FPM này. Chính trình quản lý quy trình này mà máy chủ web chuyển các yêu cầu tới.

Bản thân PHP-FPM là toàn bộ lỗ thỏ, vì vậy hãy thoải mái khám phá nếu bạn muốn, nhưng với mục đích của chúng tôi, nhiều lời giải thích này sẽ làm được. ��

Tại sao tối ưu hóa php-fpm?

Vậy tại sao phải lo lắng về tất cả các điệu nhảy này khi mọi thứ đang hoạt động tốt? Tại sao không để mọi thứ như chúng là.

Trớ trêu thay, đó chính xác là lời khuyên tôi đưa ra cho hầu hết các trường hợp sử dụng. Nếu thiết lập của bạn hoạt động tốt và không có trường hợp sử dụng đặc biệt, hãy sử dụng mặc định. Tuy nhiên, nếu bạn đang tìm cách mở rộng ra ngoài một máy duy nhất, thì việc vắt tối đa từ một máy là điều cần thiết vì nó có thể cắt giảm một nửa hóa đơn máy chủ (hoặc thậm chí nhiều hơn!).

Một điều khác để nhận ra là Nginx được xây dựng để xử lý khối lượng công việc khổng lồ. Nó có khả năng xử lý hàng ngàn kết nối cùng một lúc, nhưng nếu điều đó không đúng với thiết lập PHP của bạn, thì bạn sẽ lãng phí tài nguyên vì Nginx sẽ phải chờ PHP kết thúc quy trình hiện tại và chấp nhận tiếp theo, kết luận phủ định bất kỳ lợi thế nào mà Nginx được xây dựng để cung cấp!

Vì vậy, ngoài ý muốn đó, hãy để Lôi xem chính xác những gì chúng tôi thay đổi khi cố gắng tối ưu hóa php-fpm.

Cách tối ưu hóa PHP-FPM?

Vị trí tệp cấu hình cho php-fpm có thể khác nhau trên máy chủ, do đó, bạn sẽ cần thực hiện một số nghiên cứu để định vị nó. Bạn có thể sử dụng lệnh find nếu trên UNIX. Trên Ubuntu của tôi, đường dẫn là /etc/php/7.2/fpm/php-fpm.conf. Phiên bản 7.2 dĩ nhiên là phiên bản PHP mà tôi đang chạy.

Ở đây, một vài dòng đầu tiên của tập tin này trông như thế nào:

;;;;;;;;;;;;;;;;;;;;;;;
; Cấu hình FPM;
;;;;;;;;;;;;;;;;;;;;;;;

; Tất cả các đường dẫn tương đối trong tệp cấu hình này đều liên quan đến cài đặt của PHP
; tiền tố (/ usr). Tiền tố này có thể được thay đổi linh hoạt bằng cách sử dụng
; Đối số ‘-p’ từ dòng lệnh.

;;;;;;;;;;;;;;;;;;;;
; Tùy chọn toàn cầu;
;;;;;;;;;;;;;;;;;;;;

[toàn cầu]
; Tập tin Pid
; Lưu ý: tiền tố mặc định là / var
; Giá trị mặc định: không có
pid = /run/php/php7.2-fpm.pid

; Tệp nhật ký lỗi
; Nếu nó được đặt thành "nhật ký hệ thống", Nhật ký được gửi đến syslogd thay vì được viết
; vào một tập tin cục bộ.
; Lưu ý: tiền tố mặc định là / var
; Giá trị mặc định: log / php-fpm.log
error_log = /var/log/php7.2-fpm.log

Một vài điều cần được làm rõ ngay lập tức: dòng pid = /run/php/php7.2-fpm.pid cho chúng ta biết tệp nào chứa id tiến trình của quy trình php-fpm.

Chúng ta cũng thấy rằng /var/log/php7.2-fpm.log là nơi php-fpm sẽ lưu trữ nhật ký của nó.

Trong tệp này, thêm ba biến như thế này:

khẩn cấp_restart_thrưỡng 10
khẩn cấp_restart_interval 1m
process_control_timeout 10s

Hai cài đặt đầu tiên rất thận trọng và đang nói với quy trình php-fpm rằng nếu mười quy trình con không thành công trong vòng một phút, quy trình php-fpm chính sẽ tự khởi động lại.

Điều này nghe có vẻ không mạnh mẽ, nhưng PHP là một quá trình tồn tại trong thời gian ngắn mà bộ nhớ bị rò rỉ, do đó, khởi động lại quy trình chính trong trường hợp thất bại cao có thể giải quyết được rất nhiều vấn đề.

Tùy chọn thứ ba, process_control_timeout, yêu cầu các tiến trình con chờ đợi trong thời gian này trước khi thực hiện tín hiệu nhận được từ tiến trình cha. Điều này rất hữu ích trong trường hợp các tiến trình con nằm ở giữa một thứ gì đó khi các tiến trình cha gửi tín hiệu KILL chẳng hạn. Với mười giây trong tay, họ sẽ có cơ hội hoàn thành nhiệm vụ tốt hơn và thoát ra một cách duyên dáng.

Đáng ngạc nhiên, đây không phải là thịt của cấu hình php-fpm! Điều đó vì để phục vụ các yêu cầu web, php-fpm tạo ra một nhóm các quy trình mới, sẽ có một cấu hình riêng. Trong trường hợp của tôi, tên nhóm hóa ra là www và tệp tôi muốn chỉnh sửa là /etc/php/7.2/fpm/pool.d/www.conf.

Hãy để xem các tập tin này bắt đầu như thế nào:

; Bắt đầu một nhóm mới có tên ‘www’.
; biến $ pool có thể được sử dụng trong bất kỳ lệnh nào và sẽ được thay thế bằng
; tên hồ bơi (‘www’ tại đây)
[www]

; Tiền tố mỗi hồ bơi
; Nó chỉ áp dụng cho các chỉ thị sau:
; – ‘access.log’
; – ‘làm chậm’
; – ‘lắng nghe’ (unixsocket)
; – ‘chroot’
; – ‘chirir’
; – ‘php_values’
; – ‘php_admin_values’
; Khi không được đặt, tiền tố toàn cầu (hoặc / usr) sẽ áp dụng thay thế.
; Lưu ý: Lệnh này cũng có thể liên quan đến tiền tố toàn cầu.
; Giá trị mặc định: không có
; tiền tố = / đường dẫn / đến / pool / $ pool

; Người dùng / nhóm quy trình Unix
; Lưu ý: Người dùng là bắt buộc. Nếu nhóm không được đặt, nhóm người dùng mặc định
; sẽ được sử dụng.
người dùng = dữ liệu www
nhóm = dữ liệu www

Một cái nhìn nhanh về phần cuối của đoạn trích trên giải quyết câu đố tại sao quá trình máy chủ chạy dưới dạng dữ liệu www. Nếu bạn gặp phải các vấn đề về quyền của tệp khi thiết lập trang web của mình, thì bạn có thể đã thay đổi chủ sở hữu hoặc nhóm thư mục thành dữ liệu www, do đó cho phép quy trình PHP có thể ghi vào tệp nhật ký và tải lên tài liệu, v.v..

Cuối cùng, chúng tôi đến nguồn của vấn đề, cài đặt trình quản lý quy trình (chiều). Nói chung, bạn sẽ thấy các mặc định là như thế này:

chiều = năng động
pm.max_children = 5
pm.start_servers = 3
pm.min_spare_servers = 2
pm.max_spare_servers = 4
pm.max_Vquests = 200

Vậy, những gì làm đượcnăng độngCó nghĩa là gì? Tôi nghĩ rằng các tài liệu chính thức giải thích rõ nhất điều này (ý tôi là, đây đã là một phần của tập tin bạn chỉnh sửa, nhưng tôi đã sao chép nó ở đây chỉ trong trường hợp nó không phải là)):

; Chọn cách trình quản lý quy trình sẽ kiểm soát số lượng tiến trình con.
; Những giá trị khả thi:
; tĩnh – một số cố định (pm.max_children) của các tiến trình con;
; động – số lượng tiến trình con được thiết lập động dựa trên
; theo chỉ thị. Với quy trình quản lý này, sẽ có
; luôn có ít nhất 1 con.
; pm.max_children – số lượng trẻ em tối đa có thể
; được sống cùng một lúc.
; pm.start_servers – số lượng trẻ em được tạo khi khởi động.
; pm.min_spare_servers – số lượng trẻ em tối thiểu trong ‘nhàn rỗi’
; nhà nước (chờ xử lý). Nếu số
; các quá trình ‘nhàn rỗi’ ít hơn thế này
; số sau đó một số trẻ em sẽ được tạo ra.
; pm.max_spare_servers – số lượng trẻ em tối đa trong ‘nhàn rỗi’
; nhà nước (chờ xử lý). Nếu số
; các quá trình ‘nhàn rỗi’ lớn hơn quá trình này
; số sau đó một số trẻ em sẽ bị giết.
; ondemand – không có trẻ em nào được tạo ra khi khởi động. Trẻ em sẽ bị ngã ba khi
; yêu cầu mới sẽ kết nối. Tham số sau được sử dụng:
; pm.max_children – số lượng trẻ em tối đa
; có thể sống cùng một lúc.
; pm. process_idle_timeout – Số giây sau đó
; một quá trình nhàn rỗi sẽ bị giết.
; Lưu ý: Giá trị này là bắt buộc.

Vì vậy, chúng tôi thấy rằng có ba giá trị có thể:

  • Tĩnh: Một số quy trình PHP cố định sẽ được duy trì bất kể là gì.
  • Năng động: Chúng tôi có thể chỉ định mức tối thiểu và số lượng tối đa của quy trình mà php-fpm sẽ duy trì ở bất kỳ thời điểm nào.
  • yêu thích: Quá trình được tạo ra và phá hủy, tốt, theo yêu cầu.

Vì vậy, làm thế nào để các cài đặt này quan trọng?

Nói một cách đơn giản, nếu bạn có một trang web có lưu lượng truy cập thấp, thì cài đặt năng động trên cơ sở trực tuyến là một sự lãng phí tài nguyên. Giả sử rằng bạn có pm.min_spare_servers được đặt thành 3, ba quy trình PHP sẽ được tạo và duy trì ngay cả khi không có lưu lượng truy cập trên trang web. Trong những trường hợp như vậy, ondemand và là một lựa chọn tốt hơn, cho phép hệ thống quyết định khi nào sẽ khởi chạy các quy trình mới.

Mặt khác, các trang web xử lý lưu lượng lớn hoặc phải phản hồi nhanh chóng sẽ bị trừng phạt trong cài đặt này. Tạo một quy trình PHP mới, biến nó thành một phần của nhóm và giám sát nó, là chi phí bổ sung tốt nhất nên tránh.

Sử dụng pm = static sửa số lượng tiến trình con, cho phép sử dụng tài nguyên hệ thống tối đa trong việc phục vụ các yêu cầu thay vì quản lý PHP. Nếu bạn đi theo con đường này, hãy cẩn thận rằng nó có hướng dẫn và cạm bẫy của nó. Một bài viết khá dày đặc nhưng rất hữu ích về nó là đây.

Từ cuối cùng

Vì các bài viết về hiệu suất web có thể châm ngòi cho các cuộc chiến hoặc phục vụ gây nhầm lẫn cho mọi người, tôi cảm thấy rằng một vài từ được sắp xếp trước khi chúng tôi đóng bài viết này. Điều chỉnh hiệu suất cũng nhiều về phỏng đoán và nghệ thuật bóng tối vì nó là kiến ​​thức hệ thống.

Ngay cả khi bạn biết tất cả các cài đặt php-fpm, thành công vẫn được đảm bảo. Nếu bạn không biết gì về sự tồn tại của php-fpm, thì bạn không cần phải lãng phí thời gian để lo lắng về nó. Chỉ cần tiếp tục làm những gì bạn đã làm và tiếp tục.

Đồng thời, tránh kết thúc là một người nghiện hiệu suất. Có, bạn có thể có được hiệu năng thậm chí tốt hơn bằng cách biên dịch lại PHP từ đầu và loại bỏ tất cả các mô-đun mà bạn đã giành được bằng cách sử dụng, nhưng cách tiếp cận này không đủ mạnh trong môi trường sản xuất. Toàn bộ ý tưởng tối ưu hóa một cái gì đó là xem xét xem nhu cầu của bạn có khác với mặc định hay không (mà chúng hiếm khi làm!), Và thực hiện các thay đổi nhỏ khi cần thiết.

Nếu bạn chưa sẵn sàng dành thời gian để tối ưu hóa các máy chủ PHP của mình, thì bạn có thể xem xét tận dụng một nền tảng đáng tin cậy như Kinsta người chăm sóc tối ưu hóa hiệu suất và bảo mật.

Jeffrey Wilson Administrator
Sorry! The Author has not filled his profile.
follow me
    Like this post? Please share to your friends:
    Adblock
    detector
    map