Topjava — онлайн-школа по обучению программированию на самом популярном в мире языке Java
Первое занятие бесплатно
Этапы развития проекта обучения
Java Online Projects: как это было,
взгляд изнутри

Здравствуйте! Меня зовут Григорий Кислин, автор и ведущий учебных проектов и стажировок Java. Хотел рассказать с технической точки зрения, как проект жил и развивался. На каждом этапе приходилось выбирть только самые необходимые для текущей работы решения, которые реализовывались по принципу KISS, или, русский аналог ДУП: Дешево, Удобно и Практично.
Начало: преподавание в учебном центре
Все началось с оффлайн преподавания в Санкт-Петербургском платном учебном центре в октября 2013 г. Там провел несколько очных выпусков разработанного мной курса «Практика Java. Разработка Web приложения». Преподавание шло на основе разработки одного большого веб проекта и приходилось решать достаточно тривиальные вещи, например, передача написаного мной кода всем участникам. Пробовались флешки:), скайп, передача файлов по сети. Искалось решение для обновления проекта участниками и отделения моего кода от кода домашних заданий. В конце пришли к очевидному решению — к системе контроля версий, обновлению проекта патчами и выполнению домашних заданий в ветках git.

К обучению Java добавилось обучение Git и GitHub, без знания которых жизнь разработчика немыслима. Параллельно преподаванию я разрабатывал учебный проект Java Enterprise (Spring, JPA/Hibernate, REST, ..), основанный на вступительном задании в Toptal.
Уход в свободное плавание
В преподавании хотелось некоторой автономии, например, приводить своих участников на курс с небольшой скидкой и получать за них комиссионные, что не было в планах владельцов центра. В результате переключился на онлайн формат и стал вести разработку проекта на вебинарах самостоятельно. Сделал простенький сайт на Bootstrap, выбрал недорогой хостинг host-food(там же можно недорого купить домен) и прикрутил к сайту php скрипт для рассылки писем: при регистрации на сайте он рассылал 2 письма — мне и участнику. Письма регистрации веб клиент Yandex сортировал в разные папки, откуда я их вставлял в Google Sheets. Письма рассылал несколькими группами (не более 25 адресатов в одном письме).

Для вебинаров взял платформу Adobe Connect (25 человек в комнате и месяц Trial), общались в группе Skype. Adobe хорошо работает с 2-мя экранами (один для показа, второй рабочий, с заранее подготовленным кодом проекта по занятию) и хорошо записывает у себя в облаке видео вебинара, которое доступно участникам сразу после занятия (надо только не забывать включать запись!). Параллельно скрёб по всем сусекам для набора на первый выпуск Java Enterprise. Запустил его в августе 2014, набралось целых 6 человек!
Рост вглубь
Скоро управление учетом и рассылкой стало занимать значительное время и я понял, что нужен собственный сервис рассылки. Пользоваться сторонним сервисом не хотел (автоматическое добавление туда новых пользователей было не намного проще развертывания своего), да и с Spring Boot хотел потренироваться.

Выбор пал на хостинг AWS с годом (!) бесплатного пользования. Будьте аккуратнее их с бесплатным стеком, через пару недель мне начислили около доллара за то, что не был отключен ежедневный бэкап моего пустого PostgreSQL, и они превысили бесплатные 5 Gb на Amazon S3. А при нажатии кнопки примера деплоя в AWS Elastic Beanstalk он развернул сразу 3 инстанса, что обошлось мне в несколько центов:). В результате остановился на простой конфигурации: EC2 (Amazon Linux AMI), база H2 (понравилась возможность подключения к ней при работающем приложении через запуск TCP сервера) и запуск Spring Boot как JAR. Кстати, при моих нагрузках, бэкап H2 это обычное копирование
файла без остановки сервера. Проекту делал push на GitHub, и забирал его через pull на сервере (недавно процесс еще более упростился — делаю push со своего компа прямо на EC2 по ssh, а логи смотрю в Terminal окне IDEA). Шаблоны писем сделал в Thymeleaf с очисткой кэша каждые 3 секунды (полагаю, что это решение лучше, чем его полностью отключить). В результате шаблон на сервере обновляется сразу, передеплой не требуется.

Почту отправлял через SMTP Yandex (ограничение ~ 500 писем в день, для массовой рассылки необходим заголовок List-Unsubscribe для возможности отписки). Форма регистрации на сайте дергала мой сервис, который сохранял человека в базу, отправлял письмо и показывал результат отправки.

Вместо админки сделал REST контроллер с базовой авторизацией и поставил Postman c набором заготовленных шаблонов для дерганья REST (рассылка, оплата, ручная регистрация).
Дальше-больше: ограничения
500 писем в день стало не хватать, и Yandex стал меня банить. Переключение на запасные email был не лучший вариант и, пошукав, я нашел отличное решение: Amazon Simple Email Service (SES).

Единственно, что для нормальной работы с ним надо написать в техподдержку с просьбой снять ограничения, дать сылку на сайт и ответить 3 раза «Да» на вопросы про управление подпиской. В результате я целый год бесплатно рассылал письма и сейчас за них плачу центы (объемы небольшие, ~ 5-7 тыс. писем в месяц).

Группа Skype, где более 50 человек, становится неудобной для обучения. Мы перешли на Slak, где для каждого урока и каждой темы (например help, отзывы по работе, вакансии) сделали свой канал. Со временем появились каналы подписок RSS, изменений в проекте и пр. Приглашение в Slack также сделал автоматическим через их недокументированное API.

Следующим ограничением было максимальное количество людей для доступа к папке в Google Drive (отредактированные видео вебинаров храню там): 600 человек. Проблема решилось через предоставления доступа к Google группам и G-Suite Admin SDK для автоматического добавления участников в группу. Пришлось изрядно (дня 3-4) погуглить, чтобы с ним проинтегрироваться. Стоит удовольствие 4 € в месяц за участника (т.к. участник я один, а все остальные — гости, то выходит недорого:)
Развитие вширь: новые функции (фичи)
Сайт на host-food стал лишним, логично было его перенести вместе с приложением на AWS. При редизайне сайта помогли простые рекомендации от Google, а при его настройке тестирование на скорость загрузки. Например, следуя рекомендации, простое
включение Gzip в Ngix подняла оценку скорости загрузки с Good до Excelent.

Для выдачи партнерами информации я прикрутил к базе универсальный интерфейс (тема отдельной статьи): запросы храню в периодически перезагружаемом проперти-файле, а названия колонок читаю из метаданных запроса. В результате выставление нового запроса с рапортом ничем не отличается от обновления шаблона и также занимает секунды. Причем оживляю его с помощью простого js, которое возвращается как (ужас!) результаты SQL запроса. Например, партнерам по трудоустройству универсальный интерфейс отдает список участников стажировок с возможностью посмотреть информацию по каждому участнику и выгрузку данных в CSV.

Досточно долго я жил без авторизации вообще. Участник попадал в свой профиль на сайте по ссылке из письма с посоленным хэшем своего email. И только недавно c помощью выпускников (времени самому на все не хватает) добавил авторизацию по OAuth2 через Google и GitHub.

Интерфейс задания пароля, его смены и напоминания не потребовался.

Авторизация позволила сделать профиль «умным»: по каждому проекту (пока их 3, готовлю 4-й), если он уже закончен, предлагается бесплатный повтор, если нет — получение бесплатного вступительного занятия. Также сделал автоматический расчет цены для каждого участника с учетом рефферальной программы и бонусов за участие.

Наконец, недавно сделал следующий шаг в автоматизации — прием платежей с сайта (по современному интернет эквайринг). Интергировался с Тиньков Business, т.к. счет открывал у них (были условия бесплатного оформления документов, открытия счета и первых 6 месяцев обслуживания для новых ИП). Уже в процессе подключения они добавили ложку дегтя — снизили бесплатный лимит на снятия наличных. Да и сам процесс подключения был непрямолинейным из-за нечеткой документации и задумчивой работы службы эквайринга. Компенсировали это внимательной и профессиональной работой менеджеров по работе с клиентами, так что общее впечатление осталось неплохое.

Приложение находится в постоянном изменении: пришлось изменить процесс выдачи бесплатных купонов на IDEA при переходе JetBrains на новую политику, настроил подписку с сайта на рассылки в группы VK (см. статью рассылки в ВК), интергируюсь с сервисом поиска разработчиков GetCoder. Кстати, если рассматриваете предложения о работе, заполните у себя в профиле GitHub локацию — это важная информация для HR. Около 2-х лет назад пришлось уйти с основной работы senior и полностью отдать себя проекту.
В сравнительной табличке API по их возможностям Easy of Use для SAX/StAX говорит о том,что автор не умеет работать со StAX и оставшаяся часть статьи будет о том, как «правильно его готовить».
ГРИГОИЙ КИСЛИН
Автор статьи и JAVA-Тренер