Профилирование и оптимизация фреймворков...

13
Профилирование и оптимизация фреймворков высоконагруженных систем на примере Zend Framework Цехановский Сергей IT 2.0

Upload: quartsoft

Post on 04-Feb-2015

1.676 views

Category:

Documents


1 download

DESCRIPTION

 

TRANSCRIPT

Профилирование и оптимизация фреймворков высоконагруженных систем

на примере 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

Спасибо за внимание!