golang

GO: Как и почему мы отказались от Nest.JS

  • воскресенье, 2 марта 2025 г. в 00:00:07
https://habr.com/ru/companies/hikasami/articles/886862/

В мире разработки всегда наступает момент, когда необходимо переосмыслить используемые технологии. В Hikasami, наблюдая за ростом используемых ресурсов и усложнением бизнес-задач, мы столкнулись с выбором: продолжать использовать привычный NestJS или искать новое решение, способное обеспечить высокую производительность и масштабируемость. Ответ оказался очевиден - нужно перейти на Go.

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

Почему Go?

  • Производительность:

    Компилируемый Go-код позволяет достичь высокой скорости исполнения приложений, что особенно важно при нашей работе с большими объёмами данных и множеством одновременных соединений.

  • Конкурентность:

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

  • Простота кода и надежность:

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

  • Экосистема и сообщество:

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

В этой статье мы поделимся нашим опытом перехода от Nest.JS к Go в Hikasami: Расскажем, с какими сложностями мы столкнулись, как организовали миграцию и какие возможности открылись перед нами после смены технологий. Этот практический опыт может послужить полезным ориентиром для разработчиков и команд, ищущих пути повышения производительности своих продуктов.

Основные сложности и этапы перехода на Go

Переход с Nest.JS на Go в Hikasami сопровождался рядом существенных изменений в архитектуре приложений и выборе стека технологий. Ниже описаны ключевые моменты, с которыми мы столкнулись, а также преимущества, которые открыл для нас Go.

Переход на PostgreSQL

Одним из центральных изменений стала смена базы данных – мы отказались от MongoDB в пользу PostgreSQL. Это решение мотивировалось следующими причинами:

  • Транзакционная целостность:  

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

  • Реляционные связи:  

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

  • Расширенная аналитика:  

    Возможность использования встроенных аналитических функций и расширений предоставляет дополнительные возможности для обработки и анализа данных «на лету».

Использование GORM и новая архитектура

Переход на PostgreSQL вызвал необходимость переосмысления подхода к доступу к данным. Для этого мы внедрили GORM, который стал мощным инструментом для работы с базой данных в среде Go.

  • Упрощение кода:  

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

  • Миграции схемы базы данных:  

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

  • Читаемость и поддержка:  

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

Дополнительные сложности и возможности языка Go

Поскольку рассказ в значительной степени посвящён языку Go, стоит отметить, что миграция оказалась не только сменой инструментов работы с данными, но и переворотом в мыслях о программировании на уровне систем.

  • Параллелизм и конкурентность:

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

  • Производительность:

    Компиляция в машинный код обеспечивает высокую скорость исполнения приложений. Прямое управление памятью и минимальное время сборки мусора дают дополнительное преимущество при масштабировании.

  • Инструментарий:

    Стандартная библиотека Go предоставляет набор мощных инструментов для разработки, от работы с HTTP до реализации системных утилит, что сокращает зависимость от внешних пакетов и позволяет создавать автономные исполняемые файлы.

  • Простота поддержки и тестирования:

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

Итоги перехода

В совокупности, переход на Go дал нам возможность не только улучшить производительность и масштабируемость сервиса, но и переосмыслить архитектуру приложения. Переключение на PostgreSQL совместно с использованием GORM стало фундаментом для более строгой и надёжной работы с данными, а преимущества самого языка позволили оптимизировать работу с параллельными процессами и упростить поддержку кода.

Чтобы наглядно продемонстрировать влияние оптимизаций, стоит привести следующий пример. Ранее некоторые задачи по работе с аниме, связанные с выборкой и обработкой данных, выполнялись достаточно медленно – выполнение сложных запросов могло занимать десятки миллисекунд. После перехода на Go с использованием PostgreSQL и GORM и Горутин многие из этих запросов стали выполняться примерно в 10 раз быстрее. В результате, ряд операций начинают завершаться менее чем за миллисекунду, что значительно повышает отзывчивость нашего сервиса.