Привет ребята. Меня зовут Павел, я сооснователь сервиса Codesign и отвечаю за его техническую составляющую. Codesign – это веб-сервис для создания и обсуждения обратной связи при работе над веб-сайтами, дизайн-макетами и презентациями. Если вам дизайнеры по-прежнему пишут правки по верстке сплошным текстом в письме, то пора завязывать и переходить на Codesign.
Мы запустили сервис 22 июля 2015 года и с тех пор набрали 3500 зарегистрированных пользователей, пережили запуск на ProductHunt, когда к нам зашло 10 000 человек за 36 часов, получили своих первых платных пользователей и обсуждаем получение финансирования от европейских (я живу в Италии) инвесторов. В этой статье я расскажу как мы построили архитектуру сервиса и организовали процесс разработки.
При разработке Codesign мы стремились к модульности, посчитав что в этом случае легче будет вносить правки и заменять один блок другим. Первым серьезным решением было полное разделение API и веб-приложения, таким образом, что они работают на разных серверах. Так как у команды был опыт с Python / Django, было решено построить API на основе Django Rest Framework. Веб-приложение мы первоначально планировали писать на AngularJS, но нанятый front-end разработчик убедил нас реализовывать на React. Серверная сторона веб-приложения реализована с использованием фреймворка Express на Node.js.
По причине того, что мы хотели как можно меньше времени тратить на настройку серверов и иметь возможность быстро масштабироваться (в случае если мы ожидаем большой скачок трафика, например после публикации на популярном ресурсе) мы решили разворачивать наш код на Heroku. Таким образом на Heroku мы имеем 2 сервера для API (production / development) и 2 сервера для веб-приложения (production / development). В Heroku на бесплатном тарифе сервер засыпает каждый час и должен быть не активным более 6 часов в сутки. У меня было несколько серверов поднятых несколько месяцев до появления новых тарифов, и на них этого ограничения нет. Веб-приложение и API работают на бесплатных серверах, которые мы периодически масштабируем, когда ожидаем наплыв трафика. Основным плюсом Heroku я считаю простоту развертывания и его GIT основу, которая позволяет автоматически деплоить код из Github. Этот процесс более подробно описан ниже.
В Heroku есть большое количество различных подключаемых плагинов, среди которых есть так же системы управления базами данных (СУБД). До релиза 22го июля у нас был прототип использующий MySQL и мы решили продолжить работать в рамках этой СУБД и подключили ClearDB. Бесплатный тариф имеет ограничение базы данных в 5МБ, таким образом мы сперва перешли на тариф Punch, а далее Drift за $50 в месяц. Сейчас ClearDB самая дорогая составляющая из технологических сервисов (дороже только Intercom, но я не говорю о нем в этой статье) за которые мы платим. Я считал что $50 в месяц это дорого и считал что на Amazon RDS я получу выше производительность за те же деньги. Проведя ряд экспериментов я понял, что это не так, ибо аналогичную скорость выполнения запросов я получал только на RDS инстансах, которые стоят дороже $50, таким образом мы остались с ClearDB.
Основу Codesign составляют графические файлы, которые пользователи загружают для дальнейшего обсуждения. Здесь мы не вели долгого обсуждения и остановились на Amazon S3, где при нашем трафике и количестве хранимых картинок мы платим $3-4 в месяц. На медленном интернете загрузка картинок свыше 4МБ занимала более 30 секунд и возникала timeout ошибка от Heroku. Чтобы решить эту проблему, мы стали на сервере только генерировать специальную ссылку, по которой можно загружать картинки напрямую в Amazon S3 из браузера. Так проблема была решена.
Когда один пользователь внес изменения в борд (коллекцию картинок для обсуждения) на Codesign, то другие участники этого борда получают уведомления. Для реализации этих уведомлений мы используем два сервиса: Heroku task scheduler для инициализации отправки уведомлений каждый час, и Mandrill для отправки писем как таковых.
Django сам по себе позволяет отправлять отчеты об 500-х ошибках возникающих на сервере. Это удобно. Но еще более удобным оказался сервис Opbeat. Он собирает информацию по ошибкам, показывает статистику их возникновения, назначает каждую группу ошибок на человека, который закоммитил код, в котором возникла эта ошибка. Помимо этого Opbeat мониторит запросы к серверу и показывает узкие места с производительностью. Существует много аналогичных сервисов, но Opbeat подкупил своей простотой и бесплатностью до 3х пользователей. Однажды у нас возникла проблема с тем, что endpoint на получение списка бордов в папке выполнялся 4 секунды. Мы не могли понять в чем конкретно проблема. Opbeat показал, что мы очень неоптимально делаем запросы для проверки прав пользователей. Мы оптимизировали код и исполнение endpointа ускорилось в 20 раз.
Наша разработка в настойщий момент полностью построена на GIT:
Далее мы планируем внедрить следующие инструменты:
Данная статья это пример того, как различные сторонние сервисы могут быть интегрированы для упрощения работы над собственным продуктом. К архитектуре, которую вы видите в этой статье мы пришли не сразу, а постепенно – методом проб и ошибок. Мы не претендуем и не агитируем на то, что данная архитектура является идеальной. Мы открыты для обсуждения и будем очень рады услышать обратную связь по архитектуре, которую мы используем.
Если вам нравится Codesign, приходите работать к нам — у нас открыты 4 удаленные вакансии.
Мы запустили сервис 22 июля 2015 года и с тех пор набрали 3500 зарегистрированных пользователей, пережили запуск на ProductHunt, когда к нам зашло 10 000 человек за 36 часов, получили своих первых платных пользователей и обсуждаем получение финансирования от европейских (я живу в Италии) инвесторов. В этой статье я расскажу как мы построили архитектуру сервиса и организовали процесс разработки.
Frameworks
При разработке Codesign мы стремились к модульности, посчитав что в этом случае легче будет вносить правки и заменять один блок другим. Первым серьезным решением было полное разделение API и веб-приложения, таким образом, что они работают на разных серверах. Так как у команды был опыт с Python / Django, было решено построить API на основе Django Rest Framework. Веб-приложение мы первоначально планировали писать на AngularJS, но нанятый front-end разработчик убедил нас реализовывать на React. Серверная сторона веб-приложения реализована с использованием фреймворка Express на Node.js.
Deployment
По причине того, что мы хотели как можно меньше времени тратить на настройку серверов и иметь возможность быстро масштабироваться (в случае если мы ожидаем большой скачок трафика, например после публикации на популярном ресурсе) мы решили разворачивать наш код на Heroku. Таким образом на Heroku мы имеем 2 сервера для API (production / development) и 2 сервера для веб-приложения (production / development). В Heroku на бесплатном тарифе сервер засыпает каждый час и должен быть не активным более 6 часов в сутки. У меня было несколько серверов поднятых несколько месяцев до появления новых тарифов, и на них этого ограничения нет. Веб-приложение и API работают на бесплатных серверах, которые мы периодически масштабируем, когда ожидаем наплыв трафика. Основным плюсом Heroku я считаю простоту развертывания и его GIT основу, которая позволяет автоматически деплоить код из Github. Этот процесс более подробно описан ниже.
Database
В Heroku есть большое количество различных подключаемых плагинов, среди которых есть так же системы управления базами данных (СУБД). До релиза 22го июля у нас был прототип использующий MySQL и мы решили продолжить работать в рамках этой СУБД и подключили ClearDB. Бесплатный тариф имеет ограничение базы данных в 5МБ, таким образом мы сперва перешли на тариф Punch, а далее Drift за $50 в месяц. Сейчас ClearDB самая дорогая составляющая из технологических сервисов (дороже только Intercom, но я не говорю о нем в этой статье) за которые мы платим. Я считал что $50 в месяц это дорого и считал что на Amazon RDS я получу выше производительность за те же деньги. Проведя ряд экспериментов я понял, что это не так, ибо аналогичную скорость выполнения запросов я получал только на RDS инстансах, которые стоят дороже $50, таким образом мы остались с ClearDB.
Storage
Основу Codesign составляют графические файлы, которые пользователи загружают для дальнейшего обсуждения. Здесь мы не вели долгого обсуждения и остановились на Amazon S3, где при нашем трафике и количестве хранимых картинок мы платим $3-4 в месяц. На медленном интернете загрузка картинок свыше 4МБ занимала более 30 секунд и возникала timeout ошибка от Heroku. Чтобы решить эту проблему, мы стали на сервере только генерировать специальную ссылку, по которой можно загружать картинки напрямую в Amazon S3 из браузера. Так проблема была решена.
Notifications
Когда один пользователь внес изменения в борд (коллекцию картинок для обсуждения) на Codesign, то другие участники этого борда получают уведомления. Для реализации этих уведомлений мы используем два сервиса: Heroku task scheduler для инициализации отправки уведомлений каждый час, и Mandrill для отправки писем как таковых.
Monitoring
Django сам по себе позволяет отправлять отчеты об 500-х ошибках возникающих на сервере. Это удобно. Но еще более удобным оказался сервис Opbeat. Он собирает информацию по ошибкам, показывает статистику их возникновения, назначает каждую группу ошибок на человека, который закоммитил код, в котором возникла эта ошибка. Помимо этого Opbeat мониторит запросы к серверу и показывает узкие места с производительностью. Существует много аналогичных сервисов, но Opbeat подкупил своей простотой и бесплатностью до 3х пользователей. Однажды у нас возникла проблема с тем, что endpoint на получение списка бордов в папке выполнялся 4 секунды. Мы не могли понять в чем конкретно проблема. Opbeat показал, что мы очень неоптимально делаем запросы для проверки прав пользователей. Мы оптимизировали код и исполнение endpointа ускорилось в 20 раз.
Development
Наша разработка в настойщий момент полностью построена на GIT:
- Сперва разработчик вносит изменения и загружает код в development ветку в Github. В master ветку в Github напрямую пушить код невозможно, это запрещено в настройках репозитория.
- В этот момент срабатывает webhook и код репозитория переразворачивается на development сервере Heroku.
- Убедившись что код работает адекватно, мы создаем pull request в master ветку, при принятии которого код автоматически отправляется на production сервер Heroku. Если что-то пошло не так и была найдена какая-то ошибка, то Heroku позволяет очень легко делать откаты на предыдущие версии.
Будущее
Далее мы планируем внедрить следующие инструменты:
- Heroku review apps – для параллельного тестирования разных фич отдельно следуя git flow (сейчас у нас только один development сервер)
- Travis – для запуска unit тестов при каждом push на Github
- CodeClimate – для автоматического анализа кода (приведет к высокому качеству кода)
- Amazon RDS – когда нам не будет хватать тарифов, которые предлагает ClearDB будет необходимо разворачивать более мощные RDS инстансы
- Firebase – для реализации real time обновления некоторых блоков
- Stripe – для приема платежей (сейчас используется Gumroad)
Заключение
Данная статья это пример того, как различные сторонние сервисы могут быть интегрированы для упрощения работы над собственным продуктом. К архитектуре, которую вы видите в этой статье мы пришли не сразу, а постепенно – методом проб и ошибок. Мы не претендуем и не агитируем на то, что данная архитектура является идеальной. Мы открыты для обсуждения и будем очень рады услышать обратную связь по архитектуре, которую мы используем.
Если вам нравится Codesign, приходите работать к нам — у нас открыты 4 удаленные вакансии.