Профилирование и оптимизация фреймворков...
description
Transcript of Профилирование и оптимизация фреймворков...
Профилирование и оптимизация фреймворков высоконагруженных систем
на примере Zend Framework
Цехановский СергейIT 2.0
Сравнительный анализ производительности фреймворков
Zend Framework
CakePHPSymfony
Kohana PHP
CodeIgniter
Yii Framework
req/s
Цель профилирования - выловить узкие места
3. FirePHP
Xdebug
1. Xdebug
Временной отчет о процессе выполнения
сценариев
Просмотр в удобочитаемом виде
в WinCacheGrind
2. Отлавливание медленных SQL-запросов
Интеграция в ZF с FirePHP
Наглядное отслеживание SQL запросов в
FireFox
Логирование SQL запросов на стороне сервера
Отчет
Оптимизация: уровень сервера
• Добавление индексов для непроиндексированных полей БД
• Кэширование байт-кода
1. APC2. eAccelerator3. xCache
010100100101001010010010110101001010101001010010101001011010010101101001010010010100010010101010010101101101011010101110101111011011001010110010111111110100101001010100101010010101001000000101010101011010101010010111001010110100101010101011111101011010111010111101101100101011001011111111010010100101010010101001010100100000010101010101101010101001011100101011010010100101011010010101010101111110101101010101111110101101111110101101
$role = 0;$hasCard= false;$cardAlready = false;$tblUserRoles->delete('UserId = ' . $UserId);foreach ($objRoles as $objRole) {if (isset($formData[$objRole->RoleId]) && $formData[$objRole->RoleId]) {if ($objRole->RoleId == 8) $hasCard = true; if ($objRole->RoleId == 13)$cardAlready = true;$objUserRole = $tblUserRoles->createRow();$objUserRole->RoleId = $objRole->RoleId;$objUserRole->UserId = $UserId;$objUserRole->CreateDate = date('Y-m-d H:i:s');$objUserRole->CreateBy = Zend_Auth::getInstance()->getIdentity()->UserId;$objUserRole->save();$role = $objRole->RoleId;}
Оптимизация: уровень приложения
Zend_Cache
1. Кэширование структуры таблиц2. Кэширование информации
Хранение кэша в памяти с
применением Memcached
Хранение кэшированных фрагментов на
диске в виде файлов
Оптимизация: уровень приложения
Объединение классов1. Накопительная сборка всех используемых классов Zend в один php-файл2. Накопительная сборка всех классов, наследуемых от ZF в один файл
Class 1
Class 1 Class 2 Class 3
…Class n
Class 2 Class n
Оптимизация: сборщик классов
$str пустое
?
Пробуем инклудить по
имени ($str).
Класс
определён?
Берем список классов ZF, открываем каждый
файл и сливаем его содержимое в один файл
Записываем в очередь на
добавление в список
пользовательских классов
Удалось
?
Пробуем определить
путь к классу по
имени
Записываем в очередь на
добавление в список
классов ZF
Берем список пользовательских классов,
открываем каждый файл и сливаем его
содержимое в один файлудалось?
да
нет
нет
да
нет
да
да
нет
spl_autoload_register('__autoload');register_shutdown_function('__autoload');
конец
конец
начало($str)
Оптимизация: файл конфигурации
public function __construct($environment, $options = null){$this->_environment = (string) $environment; require_once 'Zend/Loader/Autoloader.php';$this->_autoloader = Zend_Loader_Autoloader::getInstance(); if (null !== $options) {
$session = new Zend_Session_Namespace('iniconf'); if (!$sessOptions = $session->arrConfig) { if (is_string($options)) {$options = $this->_loadConfig($options); $session->config = $options;Zend_Registry::set('conf', $options); $options=$options->toArray();$session->arrConfig = $options;
} elseif ($options instanceof Zend_Config) {$options = $options->toArray();} elseif (!is_array($options)) {throw new Zend_Application_Exception('Invalid options provided; must be location of config file, a config object, or an array');}} else {Zend_Registry::set('conf', $session->config);$options = $sessOptions;}
$this->setOptions($options); }}
Zend/Application.php
Оптимизация: инициализация модулей
$uri = $_SERVER['REQUEST_URI'];
$ar = explode('/', $uri);$mdl = (''!=$ar[1]) ? $ar[1]:'default'; foreach ($modules as $module => $moduleDirectory) {if ($mdl == $module) {…………………………………………}}
Zend/Application/Resource/Modules.php ф-ия init()
Модуль 1 Модуль 2 Модуль n
Класс
Модуль 1 Модуль 2 Модуль n
Класс
Оптимизация: генерация пути
if (empty($path)) {$uri = $_SERVER['REQUEST_URI'];$ar = explode('/', $uri);$mdl = (''!=$ar[1]) ? $ar[1]:'default'; $path = APPLICATION_PATH . '/modules/' . $mdl . '/views';
//$path = $this->_getBasePath(); - тяжелая ф-ия, if (empty($path)) {require_once 'Zend/Controller/Action/Exception.php';
throw new Zend_Controller_Action_Exception('ViewRenderer initialization failed: retrieved view base path is empty');
}}
Zend\Controller\Action\Helper\ViewRenderer.php, initView
Результаты оптимизации
Исходный проект 48 r/s
Включение eAccelerator 57 r/s
Объединение классов 85 r/s
Ручная оптимизация 98 r/s