Всем привет! Меня зовут Александр Павленко, PHP-разработчик в NIX и спикер.
В ИТ-сфере я наблюдаю следующую тенденцию: чем крупнее проект и чем быстрее растет разработка, тем чаще команде приходится меняться, расширять логику приложения и улучшать функционал.
В больших проектах постоянный рефакторинг — неизбежный процесс.
Иногда за этим скрываются проблемы, но не стоит их бояться.
Подобные моменты — отличный шанс получить новые навыки, повысить свою экспертность и завоевать доверие клиента.
В этой статье я поделюсь опытом нашей команды и расскажу, как мы решили все проблемы.
Я выделил то, что, на мой взгляд, требовало от нас наибольшей оперативности.
Где все началось
Продуктом, с которым мы имели дело, был сайт по продаже автомобилей в США.Когда мы запускали проект, был запланирован MVP. На тот момент 80% текущего функционала даже не предполагалось делать.
Проект постоянно рос, менялся, добавлялись взаимодействия.
Даже когда заказчик думал, что перешел в поддержку, мы все равно внедряли новые функции.
Дошло до того, что релизы выходили чуть ли не каждую неделю.
Одной из таких фундаментальных функций стала инвентаризация — серверный процесс, влияющий на актуальность информации, которую видит пользователь.
Однако пользователь об этом так и не узнал.
Инвентаризация отвечала за ежедневную обработку данных от дилеров – информации об автомобилях и их фотографий.
Каждый день сайт обновлялся и добавлялись новые данные в среднем по 5 миллионам автомобилей.
И этот процесс нужно было быстро реализовать.
Поначалу у заказчика не было четкого представления, что он хочет получить в итоге.
Дальше все произошло в спешке.
Некоторые неточности привели к тому, что обработка данных заняла 14 часов, не было адекватного логирования того, какие шаги мы прошли, и если что-то упало, то где и почему.
Также отмечался высокий процент отказов (например, с появлением некорректного файла).
Проблема заключалась не столько в количестве сбоев, сколько в том, что каждый раз их приходилось перезапускать вручную и контролировать каждый шаг.
Все это в совокупности привело к высокой вероятности потери данных.
Если ночью процесс падал и логирования как такового не было, то на следующее утро при ручном перезапуске система игнорировала новый файл.
Соответственно, новые данные были потеряны.
Если оставить все как есть, вчерашняя информация тоже никак не изменилась.
В результате пользователи увидели нерелевантные данные.
Пострадал клиент, пострадали мы.
Для решения проблемы мы пошли на распараллеливание процессов и свели ручной контроль к минимуму.
Сейчас весь процесс занимает пару часов.
Поскольку оно начинается примерно за два часа до рабочего времени клиента, сайт успевает полностью обновиться.
А если были какие-то сбои, его можно было быстро перезапустить одной командой.
Индексирование.
Опыт первых «граблей» Как Краулер увидел наш сайт? Ни за что.
Страницы сайта либо не были проиндексированы, либо были проиндексированы неправильно.
Это повлияло на показатели и поисковые запросы и на настроение клиента в целом.
Наше SPA-приложение (одностраничное приложение) было реализовано на React. За последние пять лет вопрос SEO для подобных приложений стал очень актуальным.
Посмотрев проблему в Интернете, мы столкнулись с двумя совершенно полярными мнениями: одни считают, что проблем с индексацией SPA-приложений нет, другие говорят, что в той или иной степени они есть, и они даже уступают монолиту.
На старте проекта в 2017 году популярные поисковые системы обычно частично или полностью не поддерживали индексацию JS-приложений, за исключением Google. Мы установили Prerender, который должен был решить все наши проблемы, и в некоторых местах производительность улучшилась.
Но радоваться было рано.
На фоне проблем с индексацией возникла еще одна сложность — большой объем JS и сторонних JS скриптов, с которыми мы интегрировались.
Их число только росло, поскольку это была инициатива заказчика.
Мы знали, что в какой-то момент это повлияет на производительность.
Вот так мы пришли к радикальным изменениям — переписали на монолит основные страницы сайта (главную страницу поисковых запросов и страницу автомобилей).
Они были наиболее часто запрашиваемыми и имели самую большую нагрузку JS. Положительные изменения не заставили себя долго ждать.
Это стало для нас хорошим уроком: всегда глубже вникайте в любые проблемы и поощряйте к этому клиента.
Для последующих изменений важно понимать, чего клиент ожидает от разработки.
Большие объемы данных и их фильтрация
Довольно быстро мы достигли 15 миллионов пользователей (спойлер: в процессе достигло 40 миллионов ).Учитывая опыт первых «граблей», мы поняли, что нужно изначально заложить такую логику, чтобы не было проблем с обработкой данных.
Таким образом мы смогли полностью реализовать возложенный на нас функционал и сделать это эффективно.
В поисках решения мы искали среди крупных компаний примеры, максимально приближенные к нашим задачам.
Переполнение стека , Нетфликс , Саундклауд , GitHub и другие ресурсы в той или иной степени использовали два инструмента — Эластичный поиск И Редис .
В итоге мы выбрали их для нашего проекта.
Что нужно было сделать? Мы говорили о хранении большого объема записей.
На сайте были различные дилерские программы для пользователей, и их тоже приходилось учитывать.
Они участвовали в поиске и фильтрации данных.
Также необходимо было предусмотреть возможность сохранения любимых автомобилей и поисковых запросов.
Это личная боль клиента.
Ему не нравилось, что, проведя некоторое время на сайте, используя множество фильтров и сортировок для поиска, он мог моментально его потерять.
У нас есть более 20 типов взаимосвязанных фильтров.
Выбор одного напрямую влиял на возможности других.
Условия сортировок были сложными по многим показателям.
Например, одна из последних сортировок представляла собой многоэтапные условия и влияла на приоритетность конкретного автомобиля в списке.
Поворачиваясь к Эластичный поиск И Редис , мы сразу разграничили их зоны влияния.
Elasticsearch стал своего рода хранилищем базовой информации и помогал обрабатывать определенные данные и фильтровать поисковые запросы.
Redis сначала была отведена роль небольшого кэш-хранилища, которое затем разросло как в вариативности, так и в функциональности.
Благодаря этим инструментам мы обошли «грабли», которые могли случиться с нашими данными.
Новые задачи были функциональными и больше касались изменений, поступающих от клиента на лету.
Мы справились с ними довольно быстро и эффективно.
Борьба за прибыльный и качественный продукт
Каждый клиент хочет иметь самый большой, производительный, узнаваемый и, самое главное, прибыльный продукт. Наш клиент не исключение.Он постоянно искал пути улучшения ресурса.
Тематика сайта по продаже автомобилей пользуется большой популярностью.
Существует множество аналогов и соответственно конкурентов.
Среди них нам нужно было выделить двоих, с которыми наш заказчик находился в негласной конкуренции.
В чем-то он старался сравняться с ними, в чем-то старался их опередить.
В ходе работы мы сравнивали ресурсы по двум показателям: визуальная загрузка страницы – когда пришел контент, который видит пользователь, и он может с ним что-то сделать; полная загрузка — когда все скрипты и процессы загружены в визуальный контент. Из-за большого количества интеграций и некоторых недостатков с нашей стороны мы сильно отставали от конкурентов по второму показателю.
Я также был очень разочарован низкой производительностью страницы поиска.
Требовалась срочная оптимизация.
Таким образом, мы превзойдем или, по крайней мере, достигнем того же уровня, что и наши конкуренты, и станем более удобными для пользователей.
Здесь важно отметить, что в какой-то момент клиент начал активно предлагать инновации.
Мы многое изменили и добавили в спешке.
Окончательная бизнес-логика сильно отличалась от исходной.
Сроки поджимали.
Из-за нехватки времени мы не рассмотрели возможности новой бизнес-логики достаточно подробно.
С нашей стороны было несколько недостатков.
Это также стало причиной оптимизации некоторых частей продукта.
Среди всех оптимизаций хочу выделить кеширование.
Процесс был разделен на два этапа:
- для кэширования на Нгинкс Ответили наши администраторы;
- Часть PHP легли на плечи разработчиков.
Более того, мы выяснили, какие сущности меняются чаще/реже, какую информацию они несут и насколько они важны для пользователей.
Поэтому мы не только кешировали их отдельно, но и выбрали разные «сроки жизни» кеша, а также дополнительные процессы, которые могли быть пересозданы внепланово при определенных условиях.
Например, вероятность появления новых фильтров была гораздо меньше, чем вероятность того, что дилер пришлет новый автомобиль, точно соответствующий текущим фильтрам (марке, модели).
В этом случае жизнеспособность кэша была меньше.
Таким образом мы свели к минимуму возможные проблемы с релевантностью данных.
После улучшения кэширования и других оптимизаций мы увидели положительные результаты на всем сайте.
Статистика говорила сама за себя: по визуальной загрузке мы обогнали соперников, а по полной загрузке очень близко подошли к первому конкуренту, что тоже можно считать успехом.
Результат оптимизации – стремление к производительности
Мне очень нравится фраза американского математика, автора бестселлера «Искусство программирования» Дональда Кнута: «Если вы оптимизируете все, что можете, вы навсегда останетесь несчастным».
Но клиенту настолько понравился результат оптимизации, что он нацелился на максимально быструю работу.
Я нашел несколько инструментов для его измерения и посвятил львиную долю наших усилий анализу этих инструментов.
Мы попробовали несколько.
Например, Dareboost и Google Audits. Первый ресурс представлял собой полноценный сайт со множеством метрик и позволял просматривать покадровую загрузку страницы с точностью до миллисекунд, второй представлял собой обычную вкладку в инспекторе Chrome, которая делала то же самое, но менее подробно.
В Google Аудит вы можете выбрать тип приложения для анализа (мобильное или десктопное) и индикаторы для проверки сайта.
Ресурс делит уязвимости на пять категорий:
- доступность;
- производительность;
- прогрессивное веб-приложение;
- передовая практика;
- SEO.
Весь функционал Dareboost доступен по платной подписке.
Ресурс даже может определить, какие технологии использовались при создании страницы.
По результатам анализа можно построить графики и выявить моменты, которые следует улучшить в будущем: вещи, которые можно исправить, хотя это не является чем-то критичным, и проблемы, требующие срочного решения.
Что касается нашего сайта, Dareboost и Google Audits согласились дать рекомендации.
Чаще всего отмечали отсутствие метатегов и http-заголовков.
Или, по мнению инструментов, они были настроены недостаточно безопасно.
Постепенно наша погоня за производительностью свелась к тому, что мы улучшили кеширование, добавили на страницы http-заголовки и метатеги, сделали мобильную версию удобной для пользователя.
Все изменения произошли в кратчайшие сроки.
В остальное время мы пытались объяснить заказчику, что любые последующие изменения тратят его и наши ресурсы, а не дают видимый эффект. Вам нужно остановиться и понять, имеет ли это смысл.
Дошло до абсурда: Google Audits заявил, что у нас нет фирменного цвета в метатеге, который влиял на цвет url во время поискового запроса.
Но с его добавлением визуально ничего не изменилось, но время на эту задачу мы уже потратили.
Как мы дошли до 50 часов работы одного специалиста
Долгое время этот момент никого в команде не беспокоил.И с этим проблем не было.
Но стандартное обновление Эластичный И Ларавел привело к тому, что используемые нами библиотеки вообще перестали поддерживаться.
Во многих местах мне приходилось что-то добавлять своими руками или создавать какие-то слои.
Это не сложно, но занимает много времени.
В нашем случае регулярное обновление вылилось почти в 50 часов работы одного специалиста.
Мы задумались: а не написать ли нам скрипты, которые бы мониторили библиотеки? В тех же мажорных версиях Laravel пишут об обновлениях и исправлениях уязвимостей безопасности, что очень важно.
Думаю, ни один заказчик не откажется потратить время на решение вопросов безопасности.
Как только мы взяли этот момент под свой контроль, процесс пошел легче.
Последующие обновления были регулярными и занимали минимальное время.
Что хотелось бы сказать напоследок: подобные и прочие «грабли», на которые вы натыкаетесь, являются неотъемлемой частью жизни большого проекта.
Не нужно из-за них расстраиваться, искать виноватых или каждый раз пугаться перед очередной трудностью.
Просто возьмите их на себя, поднимите систему и улучшите настроение клиенту.
Разобравшись в том, чего вы раньше не знали, или объяснив коллеге что-то новое, вы в будущем сможете гораздо быстрее справляться с задачами «со звездочкой».
Теги: #Управление разработкой #Управление проектами #рефакторинг
-
Что Искать В Ит-Консультанте
19 Oct, 24 -
О Программах
19 Oct, 24 -
Летний Баркемп В Одессе
19 Oct, 24