Hồ sơ không có lợi nhuận php. Lập hồ sơ và gỡ lỗi các ứng dụng PHP bằng xhprof & FirePHP. Tối ưu hóa mã dựa trên dữ liệu hồ sơ

Một phần mở rộng cho PHP có tên Xdebug có sẵn để hỗ trợ lập hồ sơ các ứng dụng PHP, cũng như gỡ lỗi thời gian chạy. Khi chạy trình lược tả, đầu ra được ghi vào một tệp ở định dạng nhị phân gọi là "cachegrind". Các ứng dụng có sẵn trên mỗi nền tảng để phân tích các tệp này. Không cần thay đổi mã ứng dụng để thực hiện việc lập hồ sơ này.

Để bật tính năng lập hồ sơ, hãy cài đặt tiện ích mở rộng và điều chỉnh cài đặt php.ini. Một số bản phân phối Linux đi kèm với các gói tiêu chuẩn (ví dụ: gói php-xdebug của Ubuntu). Trong ví dụ của chúng tôi, chúng tôi sẽ chạy cấu hình tùy chọn dựa trên tham số yêu cầu. Điều này cho phép chúng tôi giữ cài đặt ở trạng thái tĩnh và chỉ bật trình cấu hình khi cần.

# cài đặt php.ini # Đặt thành 1 để bật nó cho mọi yêu cầu xdebug.profiler_enable = 0 # Hãy sử dụng tham số GET/POST để bật profiler xdebug.profiler_enable_trigger = 1 # Giá trị GET/POST chúng ta sẽ chuyển ; trống với mọi giá trị xdebug.profiler_enable_trigger_value = "" # Xuất các tệp cachegrind thành /tmp để hệ thống của chúng tôi xóa chúng sau xdebug.profiler_output_dir = "/tmp" xdebug.profiler_output_name = "cachegrind.out.%p"

Tiếp theo, hãy sử dụng ứng dụng khách web để đưa ra yêu cầu tới URL ứng dụng của bạn mà bạn muốn lập hồ sơ, ví dụ:

Http://example.com/article/1?XDEBUG_PROFILE=1

Khi trang xử lý, nó sẽ ghi vào một tệp có tên tương tự như

/tmp/cachegrind.out.12345

Theo mặc định, số trong tên tệp là id tiến trình đã viết nó. Điều này có thể được cấu hình bằng cài đặt xdebug.profiler_output_name.

Lưu ý rằng nó sẽ ghi một tệp cho mỗi yêu cầu/quy trình PHP được thực thi. Vì vậy, ví dụ: nếu bạn muốn phân tích một bài đăng trên biểu mẫu, một hồ sơ sẽ được viết cho yêu cầu GET để hiển thị biểu mẫu HTML. Tham số XDEBUG_PROFILE sẽ cần được chuyển vào yêu cầu POST tiếp theo để phân tích yêu cầu thứ hai xử lý biểu mẫu. Do đó, khi lập hồ sơ, đôi khi việc chạy Curl để POST trực tiếp một biểu mẫu sẽ dễ dàng hơn.

Phân tích đầu ra

Sau khi ghi, ứng dụng như Webgrind có thể đọc bộ đệm hồ sơ. PHPStorm, một IDE PHP phổ biến, cũng có thể hiển thị dữ liệu lược tả này.

Ví dụ: KCachegrind sẽ hiển thị thông tin bao gồm:

  • Các hàm được thực thi
  • Thời gian gọi, cả chính nó và bao gồm các lệnh gọi hàm tiếp theo
  • Số lần mỗi hàm được gọi
  • Biểu đồ cuộc gọi
  • Liên kết đến mã nguồn

Bạn cần tìm gì

Rõ ràng việc điều chỉnh hiệu suất rất cụ thể đối với từng trường hợp sử dụng của ứng dụng. Nói chung, bạn nên tìm kiếm:

  • Các cuộc gọi lặp đi lặp lại đến cùng một chức năng mà bạn không mong đợi sẽ thấy. Đối với các chức năng xử lý và truy vấn dữ liệu, đây có thể là cơ hội chính để ứng dụng của bạn lưu vào bộ nhớ đệm.
  • Các chức năng chạy chậm. Ứng dụng dành phần lớn thời gian ở đâu? lợi ích tốt nhất trong việc điều chỉnh hiệu suất là tập trung vào những phần tiêu tốn nhiều thời gian nhất của ứng dụng.

Ghi chú: Xdebug, và đặc biệt là các tính năng định hình của nó, rất tốn tài nguyên và làm chậm quá trình thực thi PHP. Bạn không nên chạy những thứ này trong môi trường máy chủ sản xuất.

Bằng cách sử dụng hệ thống định hình, bạn có thể thu thập thông tin về những chức năng nào trong mã PHP tiêu tốn nhiều thời gian CPU và RAM hơn, nghĩa là xác định những vị trí chậm nhất và đòi hỏi nhiều bộ nhớ nhất trong chương trình PHP.

xhprof

XHProf - Trình lược tả PHP được phát triển bởi Facebook.

Cài đặt:

Aptitude install php-pear pecl install xhprof-0.9.4 echo "extension=xhprof.so" > /etc/php5/mods-available/xhprof.ini ln -s /etc/php5/mods-available/xhprof.ini /etc /php5/conf.d/xhprof.ini khởi động lại apachectl

Các tập tin cần thiết cho công việc đều nằm trong thư mục /usr/chia sẻ/php. Tuy nhiên, không phải tất cả mọi thứ mà chỉ với mã PHP. Để hiển thị báo cáo bình thường, cần có jquery và css. Chúng có thể được lấy từ kho github:

Bản sao Git https://github.com/facebook/xhprof.git

Sau đó, thêm dòng này vào mã tập lệnh PHP ở nơi bắt đầu thu thập dữ liệu:

Xhprof_enable(XHPROF_FLAGS_CPU + XHPROF_FLAGS_MEMORY);

Các thông số để thu thập dữ liệu được chỉ định trong ngoặc đơn. Trong trường hợp này, dữ liệu sẽ được thu thập về tải bộ xử lý và mức sử dụng RAM. Có thể có thêm một lựa chọn nữa XHPROF_FLAGS_NO_BUILTINS khi sử dụng, dữ liệu về các chức năng tích hợp sẽ không được thu thập.

$xhprof_data = xhprof_disable(); include_once "xhprof_lib/utils/xhprof_lib.php"; include_once "xhprof_lib/utils/xhprof_runs.php"; $xhprof_runs = XHProfRuns_Default mới(); $run_id = $xhprof_runs->save_run($xhprof_data, "xhprof_test"); echo "Báo cáo: http://domain.tld/xhprof_html/index.php?run=$run_id&source=xhprof_test"; tiếng vang "\n";

Trong dòng $run_id Dấu ngoặc kép cho biết tên của hồ sơ, có thể được đặt tùy ý.

Kết quả được xử lý trông như thế này:

Nếu bạn chỉ định tham số XHPROF_FLAGS_NO_BUILTINS, rõ ràng là số lượng lệnh gọi hàm giảm đáng kể:

Bảng cung cấp các thông tin sau:

Cuộc gọi- số lượng lệnh gọi hàm,
Giờ tường- tổng thời gian hoạt động của chức năng, bao gồm cả thời gian chờ đợi phản hồi từ các nguồn lực bên ngoài,
CPU- mất bao nhiêu thời gian để xử lý các chức năng,
Ghi nhớSử dụng- bao nhiêu RAM đã được sử dụng,
PeakMemSử dụng- mức tiêu thụ bộ nhớ cao nhất.

Các sửa đổi là:

Bao gồm- bao gồm - có tính đến các cuộc gọi đến các chức năng khác từ chức năng này,
Loại trừ.- độc quyền - không bao gồm các cuộc gọi chức năng.

Ngoài ra, phía trên bảng còn có thông tin về tổng thời gian xử lý, bộ nhớ đã sử dụng và số lần gọi hàm.

Cũng XProf cho phép bạn tạo báo cáo khác biệt giữa hai lần chạy, được biểu thị bằng màu đỏ và xanh lục. Với những báo cáo này, bạn có thể có được bức tranh rõ ràng về những cải tiến sau mỗi lần thay đổi mã.

Để có được báo cáo như vậy, bạn cần sử dụng liên kết như thế này:

http://domain.tld/xhprof_html/index.php?run1=run_id1&run2=run_id2&source=xhprof_test

Ở đâu run_id1run_id2- khởi động định danh.

Nếu bạn cài đặt Đồ thị:

Năng khiếu cài đặt đồ thị

Ngoài ra còn có giao diện web của bên thứ ba dành cho php profiler xhprof sử dụng cơ sở dữ liệu:

xDebug

xDebug- Trình gỡ lỗi mã PHP có khả năng định hình, được viết bởi Derick Rethans.

Cài đặt:

Yum cài đặt php5-xdebug

Sau đó chúng ta chỉnh sửa cấu hình:

Nano /etc/php5/mods-available/xdebug.ini

thêm các dòng vào nó:

Xdebug.profiler_enable = 1 xdebug.profiler_aggregate = Trên xdebug.profiler_output_dir = /tmp

Ở đây chúng tôi kích hoạt trình lược tả PHP và chỉ định thư mục lưu trữ các cấu hình. Hồ sơ được tạo với tên như cachegrind.out.*

Có một ứng dụng web webgrind: https://github.com/jokkedk/webgrind. Nó hoạt động không nhanh lắm nhưng cho phép bạn xem nhanh các cấu hình nhỏ. Trên thực tế, đây là mã PHP cần được sao chép từ github:

Bản sao Git https://github.com/jokkedk/webgrind.git

một thư mục sẽ được tạo webgrind, bạn cần sao chép vào thư mục của bất kỳ trang web nào và truy cập nó từ trình duyệt. Tiếp theo, để vẽ đồ thị trong tệp cấu hình hoạt động trong Debian config.php bạn cần sửa đường dẫn đến tệp thực thi đồ thị. Nó sẽ giống như thế này:

Tĩnh $dotExecutable = "/usr/bin/dot";

Ngoài ra, bạn có thể điều chỉnh múi giờ:

Tĩnh $defaultTimezone = "Châu Âu/Moscow";

Trong tiêu đề, bạn có thể chọn một cấu hình và chọn hộp để tính đến các chức năng tích hợp sẵn. Bản thân bảng hiển thị các chức năng, số lượng cuộc gọi, thời gian hoạt động của chính chức năng và thời gian bao gồm cả thời gian chờ. Để đi sâu hơn vào các chức năng, chỉ cần nhấp vào mũi tên hình tam giác. Trong trường hợp của tôi, với các cấu hình khá lớn (từ vài megabyte), thời gian chờ đợi kết quả cao một cách không cần thiết. Có lẽ tốt hơn nên sử dụng các chương trình xem cục bộ cho các cấu hình khá lớn.

Biểu đồ có thể trông như thế này:

lưu ý rằng webgrind không nên được sử dụng trên các máy chủ sản xuất vì không có ủy quyền nào được cung cấp nhưng có quyền truy cập vào mã tệp php. Nếu cần, hãy sử dụng ít nhất ủy quyền cơ bản của Apache.

Ngoài ra còn có các chương trình phân tích hồ sơ cho Linux:

Về hồ sơ

Dữ liệu hồ sơ có thể giúp bạn cải thiện ứng dụng của mình, tức là đạt được các mục tiêu nhất định, chẳng hạn như giảm mức tiêu thụ bộ nhớ, giảm thời gian tạo trang, v.v.

Thông tin trong hồ sơ là điểm khởi đầu để tối ưu hóa: nó cho biết mất bao lâu để tạo ra kết quả, lượng bộ nhớ được sử dụng và số lượng lệnh gọi hàm được thực hiện. Với dữ liệu chi tiết hơn, bạn có thể cải thiện các số liệu này.

Ví dụ: nếu bạn đang sử dụng một khung thì việc sử dụng một số chức năng của khung đó có thể dẫn đến lệnh gọi đến một số chức năng cơ bản. Nếu bạn đang đọc một số dữ liệu nhiều lần, có thể nên lưu trữ kết quả vào một biến.

Trình lược tả cũng có thể giúp bạn hiểu nơi sử dụng bộ nhớ đệm mã PHP, ví dụ: sử dụng APCu hoặc memcached.

Trước hết, cần tối ưu hóa các chức năng cần nhiều thời gian thực hiện nhất. Khi mọi thứ đã được tối ưu hóa và dường như không còn gì để cải thiện, bạn nên sắp xếp các chức năng theo số lượng cuộc gọi và tìm cách giảm bớt nó. Ngay cả khi PHP nhanh, bạn cũng nên cân nhắc xem liệu bạn có cần gọi các hàm thường xuyên như vậy không?

Nếu bạn gặp phải các tình huống sau, bạn nên xem xét việc lưu vào bộ nhớ đệm:

  • Các hàm bất biến được gọi bên trong một vòng lặp,
  • Một số nội dung được tạo hai lần,
  • Nội dung không thay đổi được tạo ra mọi lúc,
  • Nội dung được tạo ra ngay cả khi không được sử dụng.

Bạn không nên lưu trữ mọi thứ vào bộ nhớ đệm vì bộ nhớ cũng là một tài nguyên quý giá. Cache dữ liệu bạn truy cập liên tục. Ngoài ra, bộ nhớ đệm sẽ không có ý nghĩa gì nếu bộ nhớ đệm lãng phí nhiều tài nguyên hơn mức tiết kiệm được.

Ngoài bộ nhớ đệm trong mã, đừng quên bộ đệm sử dụng máy chủ web (), cũng như phía máy khách. Nếu bạn sử dụng đúng tiêu đề, nhiều yêu cầu có thể được giải quyết trước khi chúng đến được máy chủ.

FirePHP là một tiện ích mở rộng dành cho firebug, kết hợp với lớp php nhỏ của nó, cho phép bạn truyền dữ liệu từ php, chẳng hạn như tất cả các loại var_dump và thông tin gỡ lỗi khác tới bảng điều khiển firebug. Ưu điểm chính của tiện ích mở rộng này là ở chỗ tất cả thông tin gỡ lỗi được phát qua các tiêu đề và không làm xáo trộn các trang cũng như không phá vỡ logic của ứng dụng dưới bất kỳ hình thức nào. Trang web chính thức: http://firephp.org/.

Ý chính.

Thuật toán lược tả chung như sau:
  1. Ở đầu trang, chúng tôi kích hoạt tính năng lập hồ sơ bằng xhprof_enable()
  2. Ở cuối trang, tắt tính năng lập hồ sơ bằng xhprof_disable() và lưu dữ liệu đã thu thập bằng save_run()
  3. Tiếp theo, bằng cách sử dụng lớp php firephp, chúng tôi chuyển một liên kết tới dữ liệu lược tả tới phần máy khách
  4. Trong bảng điều khiển firebug, chúng tôi mở thông tin chúng tôi cần
  5. Chúng tôi vui mừng :)
Tất nhiên, tôi cũng muốn nói rằng việc thêm các hàm này vào tập lệnh PHP của bạn theo cách thủ công là điều tuyệt vời. Nhưng tôi muốn thông tin này luôn có sẵn trong quá trình phát triển và không xuất hiện trên các máy chủ sản xuất. Chúng tôi giải quyết vấn đề này như sau:

Trong các dự án của chúng tôi, trong hầu hết tất cả các tập lệnh, một tệp làm việc với trình nạp lớp, các hàm kết nối và những thứ cần thiết khác được kết nối ngay từ đầu. Vì vậy, chúng tôi đã bao gồm việc đưa hồ sơ vào tệp này. Và để có thể bật/tắt chế độ gỡ lỗi theo ý muốn, chúng tôi đã thêm kiểm tra hằng số cấu hình, đồng thời chúng tôi gói các kiểm tra này vào một số thẻ meta được tự động xóa khi dự án được xây dựng. Điều tương tự cũng áp dụng cho việc tắt tính năng định hình và ghi thông tin vào tiêu đề bằng firephp - những tác vụ này được giải quyết bằng một hàm, được gọi ở cuối mỗi tập lệnh PHP và cũng được gói trong các thẻ meta. Nó trông giống như thế này:

// Các hằng số sau được ghi vào file config của ứng dụng

/** Phương thức hoạt động của môi trường * */
định nghĩa("APPLICATION_ENV", "dev" ); // dev - gỡ lỗi | chuyên nghiệp sản xuất
/** Đường dẫn tới hồ sơ */
định nghĩa("XHPROF_ROOT" , __DIR__ . "/ExtProcs/gỡ lỗi/xhprof-0.9.2");

/***************************************************************************************
* Tiếp theo, trong tệp được tải ở đầu mỗi tập lệnh, chúng tôi khởi chạy tính năng lược tả
* DEV_START và DEV_END là thẻ meta của chúng tôi, mọi thứ giữa chúng đều bị cắt bỏ trong quá trình lắp ráp
***************************************************************************************/

//-- DEV_START
//-- trong chế độ gỡ lỗi, chúng tôi kết nối các thư viện gỡ lỗi

// Tải firephp
require_once(__DIR__ . "/includes/ExtProcs/debug/firephp/FirePHP.class.php");
//-- tải hồ sơ
"/xhprof_lib/utils/xhprof_lib.php");
require_once(XHPROF_ROOT. "/xhprof_lib/utils/xhprof_runs.php");
// Khởi tạo hồ sơ với các cờ cần thiết. Mô tả chi tiết các lá cờ
// có thể tìm thấy tại php.net/manual/ru/xhprof.constants.php
xhprof_enable(XHPROF_FLAGS_CPU + XHPROF_FLAGS_MEMORY);
}
//-- DEV_END

// À, hàm này được gọi ở cuối mỗi script
// Cuộc gọi của nó cũng được gói gọn trong DEV_START và DEV_END

/**
* Tạo liên kết đến kết quả lược tả và hiển thị nó trong bảng điều khiển
*/
hàm dev_boot_Down() (
if (APPLICATION_ENV === "dev" ) (
// Khởi tạo phiên bản firephp
$firephp = FirePHP::getInstance(true);
// Tắt hồ sơ và lưu dữ liệu
$xhprof_data = xhprof_disable();
$xhprof_runs = XHProfRuns_Default mới();
$run_id = $xhprof_runs->save_run($xhprof_data, "xhprof_testing" );
// Tạo một liên kết đến dữ liệu lược tả và ghi nó vào bảng điều khiển
$link = "http://" . $_SERVER["HTTP_HOST" ] . "/includes/ExtProcs/debug/xhprof-0.9.2/xhprof_html/index.php?run=($run_id)&source=xhprof_testing\n";
$firephp->info($link, "profiling data" );
}
}


* Mã nguồn này đã được đánh dấu bằng Công cụ đánh dấu mã nguồn.

Tôi sẽ không đi sâu vào chi tiết cài đặt các tiện ích mở rộng này, vì mọi thứ ở đây đều đơn giản. Tôi sẽ chỉ nói về một số khía cạnh của việc thiết lập. xhproof chỉ có một biến cấu hình - xhprof.output_dir, trỏ đến thư mục nơi dữ liệu lược tả sẽ được lưu. Do đó, hãy đảm bảo rằng người dùng thực thi tập lệnh PHP có quyền ghi vào thư mục đã chỉ định. Vì vậy, hãy viết một cái gì đó như thế này trong php.ini của bạn:


tiện ích mở rộng=xhprof.so
xhprof.output_dir="/var/tmp/xhprof"

Bạn cũng nên cài đặt thứ gì đó như dấu chấm hoặc Graphviz để vẽ biểu đồ cuộc gọi. Tôi có Graphviz trên MacOS X.

Sau khi hoàn thành các quy trình được mô tả ở trên, chúng tôi có thể mở và xem cấu hình của bất kỳ tập lệnh nào của chúng tôi trực tiếp trên trình duyệt bất kỳ lúc nào.

Cài đặt xhprof cho php:

Sudo apt-get cài đặt php5-xhprof

Khởi động lại Apache:

Dịch vụ Sudo khởi động lại Apache2

In phpinfo(); và kiểm tra xem mô-đun có được kết nối hay không?

Chúng tôi kiểm tra /etc/php5/apache2/conf.d để xem liệu liên kết đến cấu hình xhprof.ini có xuất hiện ở đó hay không.

Nếu không thì hãy tự tạo liên kết và khởi động lại Apache.

Sudo ln -s /etc/php5/mods-available/xhprof.ini /etc/php5/apache2/conf.d/20-xhprof.ini Sudo service Apache2 khởi động lại

Chúng tôi kiểm tra kết nối xhprof, kiểm tra xem 20-xhprof.ini có được kết nối hay không:

Ảnh chụp màn hình hiển thị phiên bản 0.9.2, mặc dù trong quá trình cài đặt, phiên bản 0.9.4 đã được hiển thị nhưng đây không phải là trở ngại đối với chúng tôi.

Bây giờ chúng ta có thể lập hồ sơ mã của mình.

  1. Ở đầu trang, hãy bật tính năng lập hồ sơ bằng xhprof_enable();
  2. Ở cuối trang, tắt tính năng lập hồ sơ bằng xhprof_disable() và lưu dữ liệu đã thu thập bằng save_run();
  3. Tiếp theo chúng tôi phân tích.

Chức năng xhprof_enable() lấy cờ làm đối số:

XHPROF_FLAGS_CPU để ghi lại số liệu thống kê của bộ xử lý,

XHPROF_FLAGS_MEMORY - dành cho bộ nhớ,

XHPROF_FLAGS_NO_BUILTINS - để bỏ qua các chức năng tích hợp sẵn.

Để lưu và thảo luận thêm, chúng ta cần cài đặt một công cụ phân tích hồ sơ.

Tải xuống kho lưu trữ bằng công cụ phân tích từ trang xhprof:, lấy phiên bản 0.9.4.

Trên máy chủ hoặc PC cục bộ, tạo một thư mục có thể truy cập qua localhost hoặc một miền riêng để chúng tôi giải nén kho lưu trữ đã tải xuống:

Bây giờ chúng ta có thể lưu hồ sơ.

https://xn--d1acnqm.xn--j1amh/altadmin/posts/edit/188

Mã theo dõi trông giống như thế này:

// Khởi tạo trình lược tả - chúng tôi sẽ tính cả thời gian xử lý và mức tiêu thụ bộ nhớ xhprof_enable(XHPROF_FLAGS_CPU + XHPROF_FLAGS_MEMORY);
// Mã cấu hình # Dừng trình lược tả $xhprof_data = xhprof_disable(); # Lưu báo cáo và tạo liên kết để xem báo cáo include_once "/var/www/html/xhprof-0.9.4/xhprof_lib/utils/xhprof_lib.php"; include_once "/var/www/html/xhprof-0.9.4/xhprof_lib/utils/xhprof_runs.php"; $xhprof_runs = XHProfRuns_Default mới(); $run_id = $xhprof_runs->save_run($xhprof_data, "xhprof_test"); echo "Báo cáo: http://localhost/xhprof-0.9.4/xhprof_html/index.php?run=$run_id&source=xhprof_test"; tiếng vang "\n";

/var/www/html/xhprof-0.9.4 - đường dẫn đến thư mục nơi chúng tôi đã giải nén các thư viện mà chúng tôi cần.

Báo cáo: http://localhost/xhprof-0.9.4/xhprof_html/index.php?run=57c32f3095d21&source=xhprof_test

Đây là những gì một phân tích hồ sơ trông giống như. Bảng này hiển thị tất cả các lệnh gọi hàm được lược tả.

Chúng ta có thể sắp xếp các chức năng bằng cách nhấp vào tiêu đề của bảng.

Khi chúng ta thấy một số hàm được thực thi nhiều lần hoặc trong một thời gian rất dài, chúng ta có thể nhấp vào hàm này và một bảng tương tự sẽ mở ra nhưng với các lệnh gọi nội bộ bên trong hàm được đề cập và môi trường chính nơi hàm được gọi.

Các chỉ số:
Tổng số Inc. Wall Time (thời gian dành cho việc thực thi các chức năng, có tính đến việc chờ phản hồi từ ổ cắm, hệ thống tệp và các tài nguyên khác)
Tổng số Inc. CPU (thời gian thực hiện các chức năng)
Tổng số Inc. MemUse (sử dụng bộ nhớ)
Tổng số Inc. PeakMemUse (mức sử dụng bộ nhớ cao nhất)
Số lượng cuộc gọi chức năng

Ngoài ra còn có tùy chọn hiển thị báo cáo bằng đồ họa. Nhưng để làm điều này, bạn cần đảm bảo rằng bạn đã cài đặt thư viện graphviz:

Apt-get cài đặt đồ thị

Sau đó, trong hồ sơ của bạn, bạn cần nhấp để hiển thị và thì đấy:

Bây giờ bạn có thể phân tích và cải thiện mã.