Чему Я Научился, Пока Писал Свой Агрегатор Цен На Игры

Этот пост не реклама моего проекта, а пример того, что дает человеку пет-проект. Я попытаюсь рассказать вам, как мне, тридцатипятилетнему Java-разработчику с обязательствами перед женой, маленьким ребенком и работодателем, удалось найти время для самообразования и интересного хобби.

Попутно расскажу, что я приобрел: какие сервисы, языки, фреймворки я для себя открыл.

Сам проект представляет собой агрегатор цен для онлайн-магазина игр PlayStation Store. На данный момент вы можете с его помощью посмотреть, как менялась цена на игры за последние три месяца, а также посмотреть список игр, обновивших свои ценовые рекорды.

Функция подписки на обновления цен находится в стадии разработки.



Чему я научился, пока писал свой агрегатор цен на игры

Если интересно, добро пожаловать под кат.



Кодируйте во время обеденных перерывов

Я уверен, что практически каждый разработчик сталкивался с проблемой, что его работа охватывает лишь часть его профессиональных интересов.

Всегда есть желание пробовать новые технологии, принимать индивидуальные решения по дизайну приложения и архитектуре всей системы.

Сейчас моей дочке четыре года, сил моих и жены едва хватает, чтобы искупать ее после работы и уложить спать.

Самообразование после этого не было в приоритете — мне пришлось искать другие возможности для своих проектов, и я решил украсть 40 минут обеденного времени и посвятить их самообразованию.

Вооружившись личным ноутбуком и оператором сотовой связи, обеспечивающим лучший интернет в моем бизнес-центре, я приступил к работе.

Изучать технологии в отрыве от полноценной практики неинтересно.

Повторять примеры на уровне «Hello World» быстро надоедает, поэтому я начал придумывать проект, который поможет мне расширить мой технологический кругозор и в то же время будет мне интересен с точки зрения предметной области.

Иногда мне нравится сознательно проводить время за видеоигрой на PlayStation 4. Я также не хочу платить больше, если могу сэкономить.

Поэтому я решил сделать ресурс, позволяющий отслеживать динамику цен на игры и ловить за хвост хорошие предложения.

Уже на этапе анализа я понял, что подобные проекты существуют, поэтому не питал иллюзий по поводу коммерческого успеха своего начинания.

Это не остановило меня.

Так родился FeedHandler. Дважды запускал разработку.

Сначала я попытался создать приложение, разделенное на (микро)сервисы.

Мне не удалось сделать это хорошо (возможно, из-за отсутствия промышленного опыта работы с микросервисной архитектурой).

Я отказался от идеи сервисов и реализовал свое приложение монолитом.

В качестве основы на будущее я разделил логические части на Java-пакеты.

Именно с таким подходом я наконец добрался до релиза.

Думаю, первое время мешало то, что мне очень хотелось сделать все идеально.

Когда я переписывал проект заново, я ставил перед собой более достижимую цель — сделать MVP (минимально ценный продукт) — а затем развивал проект итеративно, делая небольшие, но полноценные детали.



Анатомия агрегатора

Если нарисовать FeedHandler широкими штрихами, то получится следующая схема:

Чему я научился, пока писал свой агрегатор цен на игры

Здесь элементы выделены тремя цветами: зеленым — внешние системы, которые от меня не зависят (пользователи, почтовый сервис, Sony Store API), синим — реализованные модули, которые можно посмотреть на сайте Feedhandler.ru, и желтым — те, которые части, которые я реализовал, начались, но еще не закончены (как правило, они хотя бы запускаются на локальной машине).

Пойдем сверху вниз по схеме.

В отладчике браузера я заметил, что PlayStation Store обращается к своему API (valkyrie-api) при отображении страницы.

В ответ на запрос GET API возвращает лист полных данных об игре.

В которой robots.txt дает:

   

# we re-allow /valkyrie-api/ so that it will re-render properly. # Disallow: /valkyrie-api/

Отлично, это значит, что мы можем использовать это для сбора цен.

FeedHandler PriceCollector. Раз в день сборщик собирает данные из PlayStation API с помощью Java-приложения и помещает их в базу данных.

Приложение Java представляет собой процесс интеграции, написанный на Apache Camel, с которым я работал несколько лет, работая в страховой компании.

Я открыто говорю, что этот фреймворк — моя любовь.

Я всегда использую его, когда мне нужно настроить интеграцию.

Поскольку поначалу я плохо представлял, какая схема будет у конечного продукта, я использовал базу данных без схемы — MongoDB. Это был мой первый опыт работы с ней и мне он очень понравился.

MongoDB — первый продукт, с которым я познакомился во время работы над Feedhandler. Понимаю, что мне далеко до уровня специалиста в области документоориентированных баз данных, но меня порадовало то, как получилось разбить задачу на несколько коллекций разного назначения: игры, статистика (агрегированные данные для отображения на сайт) и другие.

Было довольно интересно обогатить существующие элементы или агрегировать данные для другой коллекции.

Мне он понравился как визуальный редактор https://www.robomongo.org/ .

Для разделения стадий запроса мне нужна была постоянная очередь.

Одно время я работал с ActiveMQ — этот сервер очередей идеально подошел бы мне, но для своих целей я использовал RabbitMQ, чтобы расширить кругозор.

RabbitMQ — второй продукт, с которым я познакомился.

К сожалению, у меня не было времени наработать какой-либо опыт по этому продукту, и я даже не знаю, как RabbitMQ ведет себя под нагрузкой.

Вопросов осталось больше, чем ответов.

Надеюсь, когда-нибудь мне удастся познакомиться с этим продуктом поближе.

API цен FeedHandler. Всё в том же монолите, отдельный java-пакет содержит REST-сервис, отвечающий за предоставление данных для сайта.

Он реализован на Spring-Boot-Starter-Web. В планах было добавить туда кэширование, но на данный момент каждый запрос идет напрямую в базу данных.

Пользовательский интерфейс обработчика фидов.

Сайт реализован на Nuxt.js (сначала написан на Vue.js, затем переработан на Nuxt.js).

До этого я пробовал Django, jsp, jsf и другие шаблонные веб-интерфейсы.

Здесь я хотел посмотреть на что-то новое: либо на act.js, либо на vue.js. Выбор пал на второе.

В целом мне было довольно комфортно писать, хотя я совсем не разработчик пользовательского интерфейса.

Nuxt.js — это фреймворк еще более высокого уровня, основанный на Vue.js. Это освободило меня от ряда обязательств, таких как настройка путей вручную.

Все модули со схемы собираются в образы и поставляются в контейнерах.

У меня давно возник соблазн поработать с докером, и я рискнул.

Docker и docker-compose оказались идеальными помощниками.

Такого удовольствия я, наверное, давно не испытывал.

Изоляция на уровне контейнера впечатляет. На данный момент я развертываю все с помощью Docker: от простых приложений до домашнего сервера plex и Jenkins.

Отдельно на схеме желтым цветом выделены те части, которые не доделаны.

Это все, что связано с личным кабинетом, где по плану пользователь мог подписаться на обновления цен и получать письма.

Синхронизатор моделей, Личный кабинет Feedhandler. API личного кабинета реализован на платформе Django Rest. За этим API стоит база данных Postgres. API личного аккаунта использует тот же пользовательский интерфейс Feedhandler, написанный на Nuxt.js. Модель Django обновляется не напрямую из java-кода, а через сельдерей.

Celeryproject — очаровательный проект, позволяющий забрасывать задачи на Python (и не только) с помощью RabbitMQ. В моем случае я кидаю события «новая игра», «удаление игры» и т.д. Это влияет на наличие подписки на изменение цен в личном кабинете пользователя.

Базовая настройка Django довольно проста.



Инфраструктура: CI, рассылка и другие инструменты.

Дешево (бесплатно) и сердито

Исторически я храню свой код на GitHub. Проект FeedHandler был размещен в частных репозиториях.

Непрерывная интеграция, CI. Для сборок мне идеально подошёл GitLab CI. Из недостатков можно отметить то, что раз пять за год я сталкивался с недоступностью сервиса.

Для моего проекта это было не критично, но у этого инструмента есть огромное преимущество в виде облачного реестра Docker с очень щедрыми ограничениями.

В названии проекта указано 1 ГБ.

У GitLab CI есть ряд публичных работников, которым он может поручить задачу по сбору артефакта.

Чтобы не беспокоиться об утечке моего кода или паролей, я пользуюсь услугами личного работника на арендованном VDS. Образ таких сборщиков распространяется GitLab в виде образа Docker, который вы можете установить на свой сервер.

Тогда схема сборки выглядит так:

Чему я научился, пока писал свой агрегатор цен на игры

Триггером является создание тега на мастере.

Список рассылки.

Диаграмма FeedHandler показывает, что я использую почтовый сервис.

В качестве этого я выбрал Mailgun. Я потратил довольно много времени на выбор, а у Mailgun на тот момент было немало преимуществ: во-первых, он был бесплатным.

Во-вторых, в тарифный план включено удобное API, 10 000 писем и 100 валидаций в месяц.

Я нашел в Интернете Обзор 2015 года с сайта TexTerra , мне он показался наиболее полным и с грамотной оценкой услуг.

В общем, я просмотрел почти весь обзор (кстати, Майгуна там не было), но ни один из предложенных автором почтовых сервисов мне не понравился: то ли в стартовом пакете мало писем, то ли есть нет API. В частности, у MailChimp был щедрый бесплатный план, но API предлагалось только за плату.

На момент написания статьи я заметил, что данного тарифного плана больше не существует. На смену ему пришел тарифный план Flex, 0,8$ за 1000 писем, что в целом тоже не дорого.

Трекер проблем и времени Мой любимый инструмент планирования — YouTrack от JetBrains. Существует бесплатный облачный план для команд до десяти человек.

Честно говоря, мне этот сервис понравился, потому что он больше всего напоминал привычную мне Jira. Разумеется, есть интеграция с IntelliJ IDEA. Пример моей платы:

Чему я научился, пока писал свой агрегатор цен на игры

Во время работы я нашел отличный инструмент для учета времени — Toggl. Самое главное – не забыть выключить таймер.

По результатам работы можно посмотреть интересную статистику, например, что заняло больше всего времени (инфраструктура, бэкенд, UI).

Мониторинг.

Я использовал комбинацию Prometheus (инструмент для сбора метрик) и Grafana (известный инструмент визуализации).

Чтобы своевременно получать информацию об ошибках, я добавил интеграцию со Slack. Я взял несколько показателей: время запроса/ответа, количество ошибок в журнале, количество обновлений цен.

Понятно, что эта система безопасности в некотором роде игрушка — ведь она находится на том же хосте, что и система, которую она мониторила.

При установке Прометея мне так и не удалось указать псевдоним контейнера для снятия метрик — пришлось указывать IP-адрес.

Когда поменялся IP-адрес, так получилось, что я не стал перенастраивать Прометей, так как наблюдать за логами этой системы оказалось не очень интересно — мало что происходило.

Мой день в Slack обычно выглядел так:

Чему я научился, пока писал свой агрегатор цен на игры

Nginx и безопасность.

Я активно использовал nginx, распределяя веб-трафик наружу, закрыл некоторые порты для внешних пользователей, разрешив доступ к ним только через VPN.

Коллега намекнул, что мир шагнул вперед и есть такое понятие, как Траефик.

И это действительно выглядит очень многообещающе; Нарушать правила, используя этикетки на контейнерах, — классная идея.

Но это продукт, на который я положил глаз, но пока боюсь использовать в производстве.

Было бы здорово, если бы кто-нибудь рассказал вам в комментариях о своем промышленном опыте использования Traefik.

Еще одна интересная вещь — CDN. Я использовал CloudFlare. Бесплатный план включает защиту от DDoS-атак и поддержку по электронной почте.

О качестве защиты от DDoS сказать не могу — не сталкивался и не знаю, как она работает. Для меня CloudFlare — это возможность скрыть реальный адрес виртуальной машины, на которой расположены все сервисы Feedhandler. Схема управления трафиком выглядит следующим образом:

Чему я научился, пока писал свой агрегатор цен на игры



Книги, из которых я черпал идеи

Это самое приятное! Однажды я услышал идею, что наша нынешняя точка зрения отражает книги, которые мы сейчас читаем.

Я частично с этим согласен.

В этом разделе главное, что я хочу подчеркнуть, это не «какой я молодец, столько я читаю» или «топ-10 книг, которые нужно прочитать».

Я хочу сказать, что собственный проект — это возможность на лету реализовать то, что вы прочитали в книгах.

Вам понравилась идея? Я надел походные ботинки и отправился в путь по бездорожью! Надо отметить, что книги я читал не в обед, а в метро (еще до сами знаете чего).

Вот книги, которые я прочитал за этот год экспериментов.

Все они так или иначе повлияли на проект. Release It!: Разработка и развертывание готового к использованию программного обеспечения (программисты-прагматики) Майкл Т.

Найгард. На мой взгляд, это часть золотого фонда книг о жизненном цикле программного обеспечения.

Автор очень живо рассказывает о своем опыте (не всегда удачном) разработки архитектуры и поддержки ПО.

Прочитав ее, мне сразу хочется реализовать все эти паттерны в своем продукте.

Ну, автоматический выключатель, конечно.

Освоение Spring Boot 2.0: создавайте современные, облачные и распределенные системы с помощью Spring Boot. Динеш Раджпут Не могу сказать, что я большой поклонник этой книги, но она отлично описывает все возможности Spring Boot. По крайней мере, после него у меня больше не возникало вопросов о том, какие библиотеки Spring-Boot за что отвечают. Чистая архитектура: руководство для мастера по структуре и дизайну программного обеспечения (серия Роберта К.

Мартина) Роберт К.

Мартин Я слышал много споров по поводу современных высказываний дяди Боба.

Я не буду сам вступать в эту дискуссию, но скажу, что именно эта книга рассказала мне о некоторых архитектурных паттернах, которые я ранее не мог усвоить из других источников, например, инверсия зависимостей, CQRS и другие.

Проектирование веб-API от Арно Лоре Я так и не дочитал до конца, но впитал идею серьезного подхода к проектированию API. В частности, он описал спецификацию OpenAPI перед ее реализацией в коде.

Не могу сказать, что сделал все по инструкции или почувствовал какое-то чувство завершенности или уверенности, но это было весело и здорово.



Итоги: много веселья, интересные идеи и, возможно, когда-нибудь я приду на собеседование со своим кодом.

Что-то получилось, что-то нет. Например, мне не удалось интегрировать AdSense в свой проект. Не то чтобы я хочу заработать на рекламе на сайте, который кроме меня никто не посещает, но было бы интересно посмотреть, как это работает. Получил отказ из-за шаблонного наполнения страниц.

В то же время, я не хочу выпрашивать информацию об играх из магазина Sony, это выглядит некрасиво, поэтому я оставил этот вопрос на потом.

Я не смог убедить Twitter, что мне нужен доступ к Twitter API, и мне было отказано.

Я хотел публиковать новости о минимумах цен в своем аккаунте.

Возможно, я выберу альтернативную платформу, например Telegram. Это увлечение не остается незамеченным для окружающих.

В частности, жена подарила мне на день рождения — логотип моего проекта.

Это был полный восторг и, наверное, один из самых лучших и запоминающихся подарков, потому что он созвучен делу, которое меня в тот момент увлекало! Иногда я все же обедаю через час, а не через двадцать минут. Тогда я всегда нахожу единомышленников, с которыми могу обсудить свою работу над проектом или попросить совета по тому или иному вопросу.

Мне очень нравятся такие разговоры, они помогают мне находить новые интересные темы.

Хотя, конечно, было бы лукавством сказать, что все это мне удавалось делать только во время обеденных перерывов.

После того, как я уложила дочь спать, бывали вечера, когда я тратил час или два на свой проект, особенно когда меня увлекала какая-то задача.

Например, когда я обнаружил, как легко и непринужденно писать ботов для Telegram. Грех было бы не потратить на это дело хотя бы час.

Я вообще читаю книги в метро.

Вся эта история с карантином и самоизоляцией нарушила мой привычный темп работы, и проект остался без внимания на пару месяцев.

Периодически я заглядывал к нему, чтобы убедиться, что все в порядке – и пока он меня не подвел.

Я уверен, что смогу применить свои знания и опыт, проверенные на FeedHandler. Проект забрасывать не буду, планирую постепенно доводить его до конца.

Часть с пагинацией (UI, API) уже готова, личный кабинет частично готов.

Новая платформа PS5 должна легко вписаться.

Хотя я не думаю, что смогу монетизировать этот проект, единственная выгода, которую я вижу сейчас, это то, что я смогу ходить на следующие собеседования со своим ноутбуком, кодом и проектом.

Теги: #архитектура #pet-project #GTD #новички

Вместе с данным постом часто просматривают: