SlideShare a Scribd company logo
1 of 28
Download to read offline
Боль №3: Legacy Code
The only valid measurement of code quality: WTF/minute
Почему не проще?
• Код, в принципе, решает свои задачи
• На него потрачено немало человеко-часов
• Ресурсы ограничены и много текущих задач
• Есть другой подход - evolution
Как будем улучшать?
• Будем использовать composer
• Придерживаться стандартов PSR
• Поэтапно рефакторить
• Отлаживать только с Xdebug
• Профилировать код (в том числе и в бою)
Наследство
• проект живет с 17 июля 2011
• построен на Zend 1 (Zend 2 уже больше двух лет*)
• My_Super_Awesome_Class (пространству имен уже два года*)
• отсутствие единого стандарта (до PSR еще долгих два года*)
• отсутствие цельной архитектуры (толстые контроллеры; мешанина
из php и sql; массивы адской структуры)
• сторонние библиотеки в library (composer только на подходе*)
• код опирается на PHP 5.2 (PHP 5.3 уже два года*)
* на момент старта разработки
Используйте Composer
• Проще управлять зависимостями
• Проще обновлять сторонние библиотеки
• Очень гибкий инструмент:
• version: ~x.y, > x.z; x.y.z; x.*
• private: Satis или Toran Proxy
• non-composer: директива repositories
• Автозагрузка PSR-0, PSR-4 и не только
• Разработчики не лезут в исходный код сторонних библиотек!
Какие преимущества?
Как сейчас
{
"name": "enter/core",
"require": {
"php": ">=5.5",
…,
"zendframework/zendframework1": "~1.12"
},
"require-dev": {
"phpunit/phpunit": "~4",
"squizlabs/php_codesniffer": "~1.0"
},
"autoload": {
"classmap": ["library/"],
"psr-0": { … },
"psr-4": { "Enter": "src/Enter" }
}
}
Составьте roadmap по
рефакторингу
• Придерживайтесь стандарту PSR-4 для улучшения
структуры проекта
• Пишите unit-тесты
• Покрывайте критичный функционал приемочными
тестами
• Придерживайтесь принципов SOLID, DRY, KISS и YAGNI
• Анализируйте логи
Анализ логов для
рефакторинга
• Настроили rsyslog и logrotate для сбора логов со
всех боевых машин
• cat %project%-pool-ro.log | grep -Eo "PHP.*[0-9]" | sort
| uniq -c
• Количество вхождений - вес; в каждый следующий
релиз обязательно включаем парочку ошибок с
наибольшим весом
52 PHP Fatal error: Call to a member function getId() on a non-object in %file% on line 1233
1871 PHP Fatal error: Call to a member function setPrice() on a non-object in %file% on line 125
217392 PHP Warning: array_key_exists() expects parameter 2 to be array, null given in %file% on line 826
29676 PHP Strict Standards: Only variables should be passed by reference in %file% on line 1269
217392 PHP Warning: array_key_exists() expects parameter 2 to be array, null given in %file% on line 826
147344 PHP Warning: Invalid argument supplied for foreach() in %file% on line 2522
и еще сотни строк
* количество записей в день
Что получили в начале
7 PHP Warning: array_key_exists() expects parameter 2 to be array, null given in %file% on line 333
75 PHP Warning: array_key_exists() expects parameter 2 to be array, null given in %file% on line 336
60 PHP Warning: Creating default object from empty value in %file% on line 60
1 PHP Warning: Invalid argument supplied for foreach() in %file% on line 215
86 PHP Warning: Invalid argument supplied for foreach() in %file% on line 2198
64 PHP Warning: Invalid argument supplied for foreach() in %file% on line 407
75 PHP Warning: Invalid argument supplied for foreach() in %file% on line 55
Что имеем сейчас
Что дальше
Собираем slowlog с помощью fabric
@task(default=True)
def alalyze_slow_logs():
   execute(get_slow_log_ro)
   execute(agregate_slow_log_ro)
   execute(alalyze_slow_log_ro)
@task
@parallel
@roles('dbro')
def get_slow_log_ro():
   get(
       env.log_remote_path + 'slow.log',
       env.log_local_path + 'slow_ro.%s.log' % (env.host)
   )
@task
def agregate_slow_log_ro():
   local('cat %s/slow_ro.*.log > %s/slow_ro.log' % (
       env.log_local_path,
       env.log_local_path
   ))
@task
def alalyze_slow_log_ro():
   local('mysqldumpslow %s/slow_ro.log > %s/total_slow_ro.log' % (
       env.log_local_path,
       env.log_local_path
   ))
- просто `$ fab` для старта
- параллельно собираем slow.log со всех тачек
- собираем в один файл для обработки
- прогоняем его через mysqldumpslow
Улучшайте процесс отладки
кода
Logger::getLogger(…)->debug(‘Загружаем информацию о дереве категорий');
зачем это повсюду в коде?
Почему сразу не использовать
Xdebug?!
• Сложно настроить удаленную отладку
• ssh -R 9191:127.0.0.1:9000 sandbox
• Сложно настроить отладку через шлюз
• ProxyCommand или ssh -L 9191:sandbox:9191 -R
9191:127.0.0.1:9000 gateway
• var_dump(…); die(); быстрее
• на самом деле это наиболее затратный по времени способ
отладки
Xdebug - это просто!
ssh -R 9191:127.0.0.1:9000 sandbox
zend_extension = xdebug.so
xdebug.remote_enable = 1
xdebug.remote_autostart = 1
xdebug.remote_host = 127.0.0.1
xdebug.remote_port = 9191
xdebug.idekey = PHPSTORM
1
2
3
4
Пользуйтесь профилировщиком
для поиска узких мест
• В качестве профилировщика взяли Pinba
• В качестве «клиента» взяли Intaro Pinboard
• Для включения профилировщика используем
подход Progressive Enhancement (состояние
окружения)
Полезные ссылки
• https://en.wikipedia.org/wiki/SOLID_(object-oriented_design)
• https://en.wikipedia.org/wiki/Don%27t_repeat_yourself
• https://en.wikipedia.org/wiki/KISS_principle
• https://en.wikipedia.org/wiki/You_aren%27t_gonna_need_it
эволюционируй!
Спасибо за внимание!
Есть вопросы?
Камиль Самигуллин
какой-то разработчик
kamil@samigullin.info
@ikamilsk
github.com/kamilsk
linkedin.com/in/kamilsk

More Related Content

What's hot

Сергей Белов
Сергей БеловСергей Белов
Сергей БеловCodeFest
 
Илья Кудинов
Илья КудиновИлья Кудинов
Илья КудиновCodeFest
 
Continuous Delivery, или волшебная кнопка для релизов по запросу, Денис Яковл...
Continuous Delivery, или волшебная кнопка для релизов по запросу, Денис Яковл...Continuous Delivery, или волшебная кнопка для релизов по запросу, Денис Яковл...
Continuous Delivery, или волшебная кнопка для релизов по запросу, Денис Яковл...Ontico
 
Кит на службе у человека microPaaS Deis / Алексей Медведчиков (2ГИС)
Кит на службе у человека microPaaS Deis / Алексей Медведчиков (2ГИС)Кит на службе у человека microPaaS Deis / Алексей Медведчиков (2ГИС)
Кит на службе у человека microPaaS Deis / Алексей Медведчиков (2ГИС)Ontico
 
Инструмент ChangelogBuilder для автоматической подготовки Release Notes
Инструмент ChangelogBuilder для автоматической подготовки Release NotesИнструмент ChangelogBuilder для автоматической подготовки Release Notes
Инструмент ChangelogBuilder для автоматической подготовки Release NotesPositive Hack Days
 
Как мы собираем проекты в выделенном окружении в Windows Docker
Как мы собираем проекты в выделенном окружении в Windows DockerКак мы собираем проекты в выделенном окружении в Windows Docker
Как мы собираем проекты в выделенном окружении в Windows DockerPositive Hack Days
 
«GitHub Flow — немного сложнее, чем на бумаге», Александр Бирюков
«GitHub Flow — немного сложнее, чем на бумаге», Александр Бирюков«GitHub Flow — немного сложнее, чем на бумаге», Александр Бирюков
«GitHub Flow — немного сложнее, чем на бумаге», Александр Бирюков2ГИС Технологии
 
Как подружить команду админов с N командами разработки / Денис Яковлев (2ГИС)
Как подружить команду админов с N командами разработки / Денис Яковлев (2ГИС)Как подружить команду админов с N командами разработки / Денис Яковлев (2ГИС)
Как подружить команду админов с N командами разработки / Денис Яковлев (2ГИС)Ontico
 
Переосмысливая подход к инфраструктурному коду / Евгений Пивень (IPONWEB)
Переосмысливая подход к инфраструктурному коду / Евгений Пивень (IPONWEB)Переосмысливая подход к инфраструктурному коду / Евгений Пивень (IPONWEB)
Переосмысливая подход к инфраструктурному коду / Евгений Пивень (IPONWEB)Ontico
 
Артём Ерошенко «Рецепт приготовления облачных тестингов»
Артём Ерошенко «Рецепт приготовления облачных тестингов»Артём Ерошенко «Рецепт приготовления облачных тестингов»
Артём Ерошенко «Рецепт приготовления облачных тестингов»WrikeTechClub
 
Типовая сборка и деплой продуктов в Positive Technologies
Типовая сборка и деплой продуктов в Positive TechnologiesТиповая сборка и деплой продуктов в Positive Technologies
Типовая сборка и деплой продуктов в Positive TechnologiesPositive Hack Days
 
SDN & DEVOPS ?= ❤: Практики использования SDN / Александр Шалимов (ЦПИКС, МГУ)
SDN & DEVOPS ?= ❤: Практики использования SDN / Александр Шалимов (ЦПИКС, МГУ)SDN & DEVOPS ?= ❤: Практики использования SDN / Александр Шалимов (ЦПИКС, МГУ)
SDN & DEVOPS ?= ❤: Практики использования SDN / Александр Шалимов (ЦПИКС, МГУ)Ontico
 
Как Cluster Membership Software может помочь QA
Как Cluster Membership Software может помочь QAКак Cluster Membership Software может помочь QA
Как Cluster Membership Software может помочь QASQALab
 
Github Flow. Тестировщики против тестирования
Github Flow. Тестировщики против тестированияGithub Flow. Тестировщики против тестирования
Github Flow. Тестировщики против тестированияSQALab
 
Python Development process in Yandex
Python Development process in YandexPython Development process in Yandex
Python Development process in Yandexaviatakz
 
Codeception + Docker + Robo и что из этого вышло
Codeception + Docker + Robo и что из этого вышлоCodeception + Docker + Robo и что из этого вышло
Codeception + Docker + Robo и что из этого вышлоCOMAQA.BY
 
Python tools for web development (Python meetup Almaty #ALAPY)
Python tools for web development (Python meetup Almaty #ALAPY)Python tools for web development (Python meetup Almaty #ALAPY)
Python tools for web development (Python meetup Almaty #ALAPY)aviatakz
 
Движение по хрупкому дну / Сергей Караткевич (servers.ru)
Движение по хрупкому дну / Сергей Караткевич (servers.ru)Движение по хрупкому дну / Сергей Караткевич (servers.ru)
Движение по хрупкому дну / Сергей Караткевич (servers.ru)Ontico
 
Highway to Сontinuous Integration, Денис Трифонов (2GIS)
Highway to Сontinuous Integration, Денис Трифонов (2GIS)Highway to Сontinuous Integration, Денис Трифонов (2GIS)
Highway to Сontinuous Integration, Денис Трифонов (2GIS)Ontico
 

What's hot (20)

Сергей Белов
Сергей БеловСергей Белов
Сергей Белов
 
Илья Кудинов
Илья КудиновИлья Кудинов
Илья Кудинов
 
Continuous Delivery, или волшебная кнопка для релизов по запросу, Денис Яковл...
Continuous Delivery, или волшебная кнопка для релизов по запросу, Денис Яковл...Continuous Delivery, или волшебная кнопка для релизов по запросу, Денис Яковл...
Continuous Delivery, или волшебная кнопка для релизов по запросу, Денис Яковл...
 
Кит на службе у человека microPaaS Deis / Алексей Медведчиков (2ГИС)
Кит на службе у человека microPaaS Deis / Алексей Медведчиков (2ГИС)Кит на службе у человека microPaaS Deis / Алексей Медведчиков (2ГИС)
Кит на службе у человека microPaaS Deis / Алексей Медведчиков (2ГИС)
 
Инструмент ChangelogBuilder для автоматической подготовки Release Notes
Инструмент ChangelogBuilder для автоматической подготовки Release NotesИнструмент ChangelogBuilder для автоматической подготовки Release Notes
Инструмент ChangelogBuilder для автоматической подготовки Release Notes
 
Как мы собираем проекты в выделенном окружении в Windows Docker
Как мы собираем проекты в выделенном окружении в Windows DockerКак мы собираем проекты в выделенном окружении в Windows Docker
Как мы собираем проекты в выделенном окружении в Windows Docker
 
«GitHub Flow — немного сложнее, чем на бумаге», Александр Бирюков
«GitHub Flow — немного сложнее, чем на бумаге», Александр Бирюков«GitHub Flow — немного сложнее, чем на бумаге», Александр Бирюков
«GitHub Flow — немного сложнее, чем на бумаге», Александр Бирюков
 
Как подружить команду админов с N командами разработки / Денис Яковлев (2ГИС)
Как подружить команду админов с N командами разработки / Денис Яковлев (2ГИС)Как подружить команду админов с N командами разработки / Денис Яковлев (2ГИС)
Как подружить команду админов с N командами разработки / Денис Яковлев (2ГИС)
 
Переосмысливая подход к инфраструктурному коду / Евгений Пивень (IPONWEB)
Переосмысливая подход к инфраструктурному коду / Евгений Пивень (IPONWEB)Переосмысливая подход к инфраструктурному коду / Евгений Пивень (IPONWEB)
Переосмысливая подход к инфраструктурному коду / Евгений Пивень (IPONWEB)
 
Артём Ерошенко «Рецепт приготовления облачных тестингов»
Артём Ерошенко «Рецепт приготовления облачных тестингов»Артём Ерошенко «Рецепт приготовления облачных тестингов»
Артём Ерошенко «Рецепт приготовления облачных тестингов»
 
Типовая сборка и деплой продуктов в Positive Technologies
Типовая сборка и деплой продуктов в Positive TechnologiesТиповая сборка и деплой продуктов в Positive Technologies
Типовая сборка и деплой продуктов в Positive Technologies
 
SDN & DEVOPS ?= ❤: Практики использования SDN / Александр Шалимов (ЦПИКС, МГУ)
SDN & DEVOPS ?= ❤: Практики использования SDN / Александр Шалимов (ЦПИКС, МГУ)SDN & DEVOPS ?= ❤: Практики использования SDN / Александр Шалимов (ЦПИКС, МГУ)
SDN & DEVOPS ?= ❤: Практики использования SDN / Александр Шалимов (ЦПИКС, МГУ)
 
Как Cluster Membership Software может помочь QA
Как Cluster Membership Software может помочь QAКак Cluster Membership Software может помочь QA
Как Cluster Membership Software может помочь QA
 
Continuousdelivery
ContinuousdeliveryContinuousdelivery
Continuousdelivery
 
Github Flow. Тестировщики против тестирования
Github Flow. Тестировщики против тестированияGithub Flow. Тестировщики против тестирования
Github Flow. Тестировщики против тестирования
 
Python Development process in Yandex
Python Development process in YandexPython Development process in Yandex
Python Development process in Yandex
 
Codeception + Docker + Robo и что из этого вышло
Codeception + Docker + Robo и что из этого вышлоCodeception + Docker + Robo и что из этого вышло
Codeception + Docker + Robo и что из этого вышло
 
Python tools for web development (Python meetup Almaty #ALAPY)
Python tools for web development (Python meetup Almaty #ALAPY)Python tools for web development (Python meetup Almaty #ALAPY)
Python tools for web development (Python meetup Almaty #ALAPY)
 
Движение по хрупкому дну / Сергей Караткевич (servers.ru)
Движение по хрупкому дну / Сергей Караткевич (servers.ru)Движение по хрупкому дну / Сергей Караткевич (servers.ru)
Движение по хрупкому дну / Сергей Караткевич (servers.ru)
 
Highway to Сontinuous Integration, Денис Трифонов (2GIS)
Highway to Сontinuous Integration, Денис Трифонов (2GIS)Highway to Сontinuous Integration, Денис Трифонов (2GIS)
Highway to Сontinuous Integration, Денис Трифонов (2GIS)
 

Similar to Enter: legacy code

Компиляция скриптов PHP (Алексей Романенко)
Компиляция скриптов PHP (Алексей Романенко)Компиляция скриптов PHP (Алексей Романенко)
Компиляция скриптов PHP (Алексей Романенко)Ontico
 
Ошибки, которые сложно заметить на code review, но которые находятся статичес...
Ошибки, которые сложно заметить на code review, но которые находятся статичес...Ошибки, которые сложно заметить на code review, но которые находятся статичес...
Ошибки, которые сложно заметить на code review, но которые находятся статичес...Andrey Karpov
 
Поиск уязвимостей с использованием статического анализа кода
Поиск уязвимостей с использованием статического анализа кодаПоиск уязвимостей с использованием статического анализа кода
Поиск уязвимостей с использованием статического анализа кодаAndrey Karpov
 
Поиск уязвимостей с использованием статического анализа кода
Поиск уязвимостей с использованием статического анализа кодаПоиск уязвимостей с использованием статического анализа кода
Поиск уязвимостей с использованием статического анализа кодаcorehard_by
 
Компиляция скриптов PHP. Алексей Романенко
Компиляция скриптов PHP. Алексей РоманенкоКомпиляция скриптов PHP. Алексей Романенко
Компиляция скриптов PHP. Алексей РоманенкоFuenteovejuna
 
Инструментируй это
Инструментируй этоИнструментируй это
Инструментируй этоRoman Dvornov
 
ekbpy'2012 - Михаил Коробов - Python 3
ekbpy'2012 - Михаил Коробов - Python 3ekbpy'2012 - Михаил Коробов - Python 3
ekbpy'2012 - Михаил Коробов - Python 3it-people
 
Web осень 2013 лекция 5
Web осень 2013 лекция 5Web осень 2013 лекция 5
Web осень 2013 лекция 5Technopark
 
Опыт использования Spark, Основано на реальных событиях
Опыт использования Spark, Основано на реальных событияхОпыт использования Spark, Основано на реальных событиях
Опыт использования Spark, Основано на реальных событияхVasil Remeniuk
 
Node.js введение в технологию, КПИ #ITmeetingKPI
Node.js введение в технологию, КПИ  #ITmeetingKPINode.js введение в технологию, КПИ  #ITmeetingKPI
Node.js введение в технологию, КПИ #ITmeetingKPITimur Shemsedinov
 
D2D Pizza JS Илья Беда "Куда мы все катимся?"
D2D Pizza JS Илья Беда "Куда мы все катимся?"D2D Pizza JS Илья Беда "Куда мы все катимся?"
D2D Pizza JS Илья Беда "Куда мы все катимся?"Dev2Dev
 
Приемы, затрудняющие обнаружение и анализ вредоносного кода в PHP-сценариях
Приемы, затрудняющие обнаружение и анализ вредоносного кода в PHP-сценарияхПриемы, затрудняющие обнаружение и анализ вредоносного кода в PHP-сценариях
Приемы, затрудняющие обнаружение и анализ вредоносного кода в PHP-сценарияхPositive Hack Days
 
Приемы, затрудняющие обнаружение и анализ вредоносного кода в PHP скриптах
Приемы, затрудняющие обнаружение и анализ вредоносного кода в PHP скриптахПриемы, затрудняющие обнаружение и анализ вредоносного кода в PHP скриптах
Приемы, затрудняющие обнаружение и анализ вредоносного кода в PHP скриптахrevisium
 
Истинный DevOps. Секрет 42.
Истинный DevOps. Секрет 42.Истинный DevOps. Секрет 42.
Истинный DevOps. Секрет 42.Nikita Borzykh
 
PHP Tricks
PHP TricksPHP Tricks
PHP TricksBlackFan
 
Valentin Simonov “Who cracks our games and how that is done”
Valentin Simonov “Who cracks our games and how that is done”Valentin Simonov “Who cracks our games and how that is done”
Valentin Simonov “Who cracks our games and how that is done”DevGAMM Conference
 
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...Platonov Sergey
 

Similar to Enter: legacy code (20)

Компиляция скриптов PHP (Алексей Романенко)
Компиляция скриптов PHP (Алексей Романенко)Компиляция скриптов PHP (Алексей Романенко)
Компиляция скриптов PHP (Алексей Романенко)
 
php frameworks
php frameworksphp frameworks
php frameworks
 
Ошибки, которые сложно заметить на code review, но которые находятся статичес...
Ошибки, которые сложно заметить на code review, но которые находятся статичес...Ошибки, которые сложно заметить на code review, но которые находятся статичес...
Ошибки, которые сложно заметить на code review, но которые находятся статичес...
 
Поиск уязвимостей с использованием статического анализа кода
Поиск уязвимостей с использованием статического анализа кодаПоиск уязвимостей с использованием статического анализа кода
Поиск уязвимостей с использованием статического анализа кода
 
Поиск уязвимостей с использованием статического анализа кода
Поиск уязвимостей с использованием статического анализа кодаПоиск уязвимостей с использованием статического анализа кода
Поиск уязвимостей с использованием статического анализа кода
 
Компиляция скриптов PHP. Алексей Романенко
Компиляция скриптов PHP. Алексей РоманенкоКомпиляция скриптов PHP. Алексей Романенко
Компиляция скриптов PHP. Алексей Романенко
 
Инструментируй это
Инструментируй этоИнструментируй это
Инструментируй это
 
ekbpy'2012 - Михаил Коробов - Python 3
ekbpy'2012 - Михаил Коробов - Python 3ekbpy'2012 - Михаил Коробов - Python 3
ekbpy'2012 - Михаил Коробов - Python 3
 
Web осень 2013 лекция 5
Web осень 2013 лекция 5Web осень 2013 лекция 5
Web осень 2013 лекция 5
 
Опыт использования Spark, Основано на реальных событиях
Опыт использования Spark, Основано на реальных событияхОпыт использования Spark, Основано на реальных событиях
Опыт использования Spark, Основано на реальных событиях
 
Node.js введение в технологию, КПИ #ITmeetingKPI
Node.js введение в технологию, КПИ  #ITmeetingKPINode.js введение в технологию, КПИ  #ITmeetingKPI
Node.js введение в технологию, КПИ #ITmeetingKPI
 
JPHP
JPHPJPHP
JPHP
 
D2D Pizza JS Илья Беда "Куда мы все катимся?"
D2D Pizza JS Илья Беда "Куда мы все катимся?"D2D Pizza JS Илья Беда "Куда мы все катимся?"
D2D Pizza JS Илья Беда "Куда мы все катимся?"
 
Приемы, затрудняющие обнаружение и анализ вредоносного кода в PHP-сценариях
Приемы, затрудняющие обнаружение и анализ вредоносного кода в PHP-сценарияхПриемы, затрудняющие обнаружение и анализ вредоносного кода в PHP-сценариях
Приемы, затрудняющие обнаружение и анализ вредоносного кода в PHP-сценариях
 
Приемы, затрудняющие обнаружение и анализ вредоносного кода в PHP скриптах
Приемы, затрудняющие обнаружение и анализ вредоносного кода в PHP скриптахПриемы, затрудняющие обнаружение и анализ вредоносного кода в PHP скриптах
Приемы, затрудняющие обнаружение и анализ вредоносного кода в PHP скриптах
 
Истинный DevOps. Секрет 42.
Истинный DevOps. Секрет 42.Истинный DevOps. Секрет 42.
Истинный DevOps. Секрет 42.
 
Sivko
SivkoSivko
Sivko
 
PHP Tricks
PHP TricksPHP Tricks
PHP Tricks
 
Valentin Simonov “Who cracks our games and how that is done”
Valentin Simonov “Who cracks our games and how that is done”Valentin Simonov “Who cracks our games and how that is done”
Valentin Simonov “Who cracks our games and how that is done”
 
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
 

More from Kamil Samigullin

OctoLab Cookbook: Go lang tips and tricks - protection of sensitive config data
OctoLab Cookbook: Go lang tips and tricks - protection of sensitive config dataOctoLab Cookbook: Go lang tips and tricks - protection of sensitive config data
OctoLab Cookbook: Go lang tips and tricks - protection of sensitive config dataKamil Samigullin
 
OctoLab Cookbook: how to use composer.yml and stop creating issues about
OctoLab Cookbook: how to use composer.yml and stop creating issues aboutOctoLab Cookbook: how to use composer.yml and stop creating issues about
OctoLab Cookbook: how to use composer.yml and stop creating issues aboutKamil Samigullin
 
OctoLab Cookbook: how to generate a unique key for a sequence
OctoLab Cookbook: how to generate a unique key for a sequenceOctoLab Cookbook: how to generate a unique key for a sequence
OctoLab Cookbook: how to generate a unique key for a sequenceKamil Samigullin
 
Enter Cookbook: refactoring under a microscope
Enter Cookbook: refactoring under a microscopeEnter Cookbook: refactoring under a microscope
Enter Cookbook: refactoring under a microscopeKamil Samigullin
 

More from Kamil Samigullin (6)

OctoLab Cookbook: Go lang tips and tricks - protection of sensitive config data
OctoLab Cookbook: Go lang tips and tricks - protection of sensitive config dataOctoLab Cookbook: Go lang tips and tricks - protection of sensitive config data
OctoLab Cookbook: Go lang tips and tricks - protection of sensitive config data
 
OctoLab Cookbook: how to use composer.yml and stop creating issues about
OctoLab Cookbook: how to use composer.yml and stop creating issues aboutOctoLab Cookbook: how to use composer.yml and stop creating issues about
OctoLab Cookbook: how to use composer.yml and stop creating issues about
 
OctoLab Cookbook: how to generate a unique key for a sequence
OctoLab Cookbook: how to generate a unique key for a sequenceOctoLab Cookbook: how to generate a unique key for a sequence
OctoLab Cookbook: how to generate a unique key for a sequence
 
Enter Cookbook: refactoring under a microscope
Enter Cookbook: refactoring under a microscopeEnter Cookbook: refactoring under a microscope
Enter Cookbook: refactoring under a microscope
 
Enter: testing
Enter: testingEnter: testing
Enter: testing
 
Enter: git workflow
Enter: git workflowEnter: git workflow
Enter: git workflow
 

Enter: legacy code

  • 1.
  • 3. The only valid measurement of code quality: WTF/minute
  • 4.
  • 5.
  • 6.
  • 7. Почему не проще? • Код, в принципе, решает свои задачи • На него потрачено немало человеко-часов • Ресурсы ограничены и много текущих задач • Есть другой подход - evolution
  • 8. Как будем улучшать? • Будем использовать composer • Придерживаться стандартов PSR • Поэтапно рефакторить • Отлаживать только с Xdebug • Профилировать код (в том числе и в бою)
  • 9. Наследство • проект живет с 17 июля 2011 • построен на Zend 1 (Zend 2 уже больше двух лет*) • My_Super_Awesome_Class (пространству имен уже два года*) • отсутствие единого стандарта (до PSR еще долгих два года*) • отсутствие цельной архитектуры (толстые контроллеры; мешанина из php и sql; массивы адской структуры) • сторонние библиотеки в library (composer только на подходе*) • код опирается на PHP 5.2 (PHP 5.3 уже два года*) * на момент старта разработки
  • 11. • Проще управлять зависимостями • Проще обновлять сторонние библиотеки • Очень гибкий инструмент: • version: ~x.y, > x.z; x.y.z; x.* • private: Satis или Toran Proxy • non-composer: директива repositories • Автозагрузка PSR-0, PSR-4 и не только • Разработчики не лезут в исходный код сторонних библиотек! Какие преимущества?
  • 12. Как сейчас { "name": "enter/core", "require": { "php": ">=5.5", …, "zendframework/zendframework1": "~1.12" }, "require-dev": { "phpunit/phpunit": "~4", "squizlabs/php_codesniffer": "~1.0" }, "autoload": { "classmap": ["library/"], "psr-0": { … }, "psr-4": { "Enter": "src/Enter" } } }
  • 13. Составьте roadmap по рефакторингу • Придерживайтесь стандарту PSR-4 для улучшения структуры проекта • Пишите unit-тесты • Покрывайте критичный функционал приемочными тестами • Придерживайтесь принципов SOLID, DRY, KISS и YAGNI • Анализируйте логи
  • 14. Анализ логов для рефакторинга • Настроили rsyslog и logrotate для сбора логов со всех боевых машин • cat %project%-pool-ro.log | grep -Eo "PHP.*[0-9]" | sort | uniq -c • Количество вхождений - вес; в каждый следующий релиз обязательно включаем парочку ошибок с наибольшим весом
  • 15. 52 PHP Fatal error: Call to a member function getId() on a non-object in %file% on line 1233 1871 PHP Fatal error: Call to a member function setPrice() on a non-object in %file% on line 125 217392 PHP Warning: array_key_exists() expects parameter 2 to be array, null given in %file% on line 826 29676 PHP Strict Standards: Only variables should be passed by reference in %file% on line 1269 217392 PHP Warning: array_key_exists() expects parameter 2 to be array, null given in %file% on line 826 147344 PHP Warning: Invalid argument supplied for foreach() in %file% on line 2522 и еще сотни строк * количество записей в день Что получили в начале
  • 16. 7 PHP Warning: array_key_exists() expects parameter 2 to be array, null given in %file% on line 333 75 PHP Warning: array_key_exists() expects parameter 2 to be array, null given in %file% on line 336 60 PHP Warning: Creating default object from empty value in %file% on line 60 1 PHP Warning: Invalid argument supplied for foreach() in %file% on line 215 86 PHP Warning: Invalid argument supplied for foreach() in %file% on line 2198 64 PHP Warning: Invalid argument supplied for foreach() in %file% on line 407 75 PHP Warning: Invalid argument supplied for foreach() in %file% on line 55 Что имеем сейчас
  • 17. Что дальше Собираем slowlog с помощью fabric @task(default=True) def alalyze_slow_logs():    execute(get_slow_log_ro)    execute(agregate_slow_log_ro)    execute(alalyze_slow_log_ro) @task @parallel @roles('dbro') def get_slow_log_ro():    get(        env.log_remote_path + 'slow.log',        env.log_local_path + 'slow_ro.%s.log' % (env.host)    ) @task def agregate_slow_log_ro():    local('cat %s/slow_ro.*.log > %s/slow_ro.log' % (        env.log_local_path,        env.log_local_path    )) @task def alalyze_slow_log_ro():    local('mysqldumpslow %s/slow_ro.log > %s/total_slow_ro.log' % (        env.log_local_path,        env.log_local_path    )) - просто `$ fab` для старта - параллельно собираем slow.log со всех тачек - собираем в один файл для обработки - прогоняем его через mysqldumpslow
  • 19. Logger::getLogger(…)->debug(‘Загружаем информацию о дереве категорий'); зачем это повсюду в коде?
  • 20.
  • 21. Почему сразу не использовать Xdebug?! • Сложно настроить удаленную отладку • ssh -R 9191:127.0.0.1:9000 sandbox • Сложно настроить отладку через шлюз • ProxyCommand или ssh -L 9191:sandbox:9191 -R 9191:127.0.0.1:9000 gateway • var_dump(…); die(); быстрее • на самом деле это наиболее затратный по времени способ отладки
  • 22. Xdebug - это просто! ssh -R 9191:127.0.0.1:9000 sandbox zend_extension = xdebug.so xdebug.remote_enable = 1 xdebug.remote_autostart = 1 xdebug.remote_host = 127.0.0.1 xdebug.remote_port = 9191 xdebug.idekey = PHPSTORM 1 2 3 4
  • 23. Пользуйтесь профилировщиком для поиска узких мест • В качестве профилировщика взяли Pinba • В качестве «клиента» взяли Intaro Pinboard • Для включения профилировщика используем подход Progressive Enhancement (состояние окружения)
  • 24. Полезные ссылки • https://en.wikipedia.org/wiki/SOLID_(object-oriented_design) • https://en.wikipedia.org/wiki/Don%27t_repeat_yourself • https://en.wikipedia.org/wiki/KISS_principle • https://en.wikipedia.org/wiki/You_aren%27t_gonna_need_it
  • 25.
  • 26.
  • 28. Спасибо за внимание! Есть вопросы? Камиль Самигуллин какой-то разработчик kamil@samigullin.info @ikamilsk github.com/kamilsk linkedin.com/in/kamilsk