Цель — создание нового высоконагруженного стартапа в современных условиях. Создание архитектуры будем рассматривать на примере Billingolang — проект универсального биллинга, общего назначения, написанный на golang. Проект включает в себя доступ через API, сайт, интеграцию в бухгалтерские системы, отчеты и графики.
Изначально были откинуты однопоточные системы. Выбирать пришлось между Erlang, Golang и Rust. Основным языком программирования был выбран Golang, потому что найти программистов на Erlang сложно, хотя устойчивость и горячая замена кода шли в плюс Erlang. Rust, же не смотря на формальное отсутствие состояния гонки, все-таки более подходит не для написания приложений, но драйверов и операционных систем.
Обмен сообщениями между компонентами системы происходит не на классическом RabbitMQ, а на NATS — последний показал бенчмарки на сервере который сейчас используется, 1M сообщений (+360К при кластеризации) в секунду против 40К у зайца. Да и кластеризуется он быстрее и легче чем RabbitMQ.
База данных: MySQL InnoDB Сluster 7.6 (MySQL server 8.0). Шикарно верстается и отлаживается комьюнити средством MySQL Workbench.
API — пишется на Swagger (OpenAPI 2.0). Это позволяет избежать ошибок разными программистами, генерируется чистый хорошо документированный код и документация по API. К сожалению Swagger по умолчанию использует для рутинга gorilla/mux, но после генерации всего API, рутинг будет переделан на kataras/muxie — он быстрее.
Фронтенд: из доступных фреймворков: Iris, Beego и Revel — выбран Revel. Медленнее чем Iris, но все есть из коробки, включая интеграцию с графиками. Основную нагрузку все равно будет нести API.
Масштабирование: все компоненты системы собраны в LXC контейнерах, пока перед которыми стоит балансер HAProxy. Идея масштабирования сводится к тому, чтобы по мере увеличения клиентов последовательно переходить на более мощные сервера с сохранением структуры контейнеров, а в последствии разнести контейнера на отдельные сервера, заменив HAProxy на NATS. Кроме классического масштабирования «железом» всегда остается возможность внутри контейнеров-обработчиков запросов к API и сайту увеличивать количество goroutine. Хотя и этот процесс, как показала практика, имеет логические ограничения.
Вообще, основная мысль статьи и мое глубокое убеждение заключается в том, что начальную архитектуру высоконагруженных проектов, в современных условиях бессмысленно строить на однопоточных системах, несмотря на их годами развитую инфраструктуру и наличие большого количества доступных программистов. И всю схему проекта необходимо создавать изначально закладывая легкий перенос на более мощное и распределенное оборудование. Это позволит в будущем легко найти баланс между масштабированием «железом» и кодом, не увеличивая кратно расходы.
Обычная и самая распространенная ошибка новых стартапов — плохая начальная проработка архитектуры. По-принципу — «быстренько начнем писать, а потом разберемся». Как правило в последствии — это ведет к краху проекта.
Как говорится — «90% успеха — это подготовка». Не бойтесь потратится изначально на создание грамотной, продуманной архитектуры — это окупится сторицей.
Удачи!
Изначально были откинуты однопоточные системы. Выбирать пришлось между Erlang, Golang и Rust. Основным языком программирования был выбран Golang, потому что найти программистов на Erlang сложно, хотя устойчивость и горячая замена кода шли в плюс Erlang. Rust, же не смотря на формальное отсутствие состояния гонки, все-таки более подходит не для написания приложений, но драйверов и операционных систем.
Обмен сообщениями между компонентами системы происходит не на классическом RabbitMQ, а на NATS — последний показал бенчмарки на сервере который сейчас используется, 1M сообщений (+360К при кластеризации) в секунду против 40К у зайца. Да и кластеризуется он быстрее и легче чем RabbitMQ.
База данных: MySQL InnoDB Сluster 7.6 (MySQL server 8.0). Шикарно верстается и отлаживается комьюнити средством MySQL Workbench.
API — пишется на Swagger (OpenAPI 2.0). Это позволяет избежать ошибок разными программистами, генерируется чистый хорошо документированный код и документация по API. К сожалению Swagger по умолчанию использует для рутинга gorilla/mux, но после генерации всего API, рутинг будет переделан на kataras/muxie — он быстрее.
Фронтенд: из доступных фреймворков: Iris, Beego и Revel — выбран Revel. Медленнее чем Iris, но все есть из коробки, включая интеграцию с графиками. Основную нагрузку все равно будет нести API.
Масштабирование: все компоненты системы собраны в LXC контейнерах, пока перед которыми стоит балансер HAProxy. Идея масштабирования сводится к тому, чтобы по мере увеличения клиентов последовательно переходить на более мощные сервера с сохранением структуры контейнеров, а в последствии разнести контейнера на отдельные сервера, заменив HAProxy на NATS. Кроме классического масштабирования «железом» всегда остается возможность внутри контейнеров-обработчиков запросов к API и сайту увеличивать количество goroutine. Хотя и этот процесс, как показала практика, имеет логические ограничения.
Вообще, основная мысль статьи и мое глубокое убеждение заключается в том, что начальную архитектуру высоконагруженных проектов, в современных условиях бессмысленно строить на однопоточных системах, несмотря на их годами развитую инфраструктуру и наличие большого количества доступных программистов. И всю схему проекта необходимо создавать изначально закладывая легкий перенос на более мощное и распределенное оборудование. Это позволит в будущем легко найти баланс между масштабированием «железом» и кодом, не увеличивая кратно расходы.
Обычная и самая распространенная ошибка новых стартапов — плохая начальная проработка архитектуры. По-принципу — «быстренько начнем писать, а потом разберемся». Как правило в последствии — это ведет к краху проекта.
Как говорится — «90% успеха — это подготовка». Не бойтесь потратится изначально на создание грамотной, продуманной архитектуры — это окупится сторицей.
Удачи!