Комментарии 57
Какова вероятность, что проблема была в СУБД, а не Neste.js? Получается, вы не просто поменяли backend, но полностью переписали приложение. Даже если использовать те же технологии и переписать как надо, это даст буст + СУБД + бэк. И каков процент заслуги именно go?
Поддержу вопрос.
Честно говоря, в статье много обобщённого, никакой конкретики.
По сути сводится к: «у нас что-то медленно работало. Решили сменить стек полностью. Вроде заработало быстрее».
Ответа на вопросы из заголовка статьи в самой стать к нет.
Статья носит обзорный характер, и мы опустили множество технических нюансов. В скором времени планируем опубликовать дополнительные материалы с конкретными данными по этапам миграции и подробными показателями производительности. Поэтому уровень статьи "Простой".
Раз на несколько статей хотели разнести историю успеха, могли бы как раз подвесить интригу в цифрах.
Что-то вроде метрик Старый Стек vs Новый Стек. Причём по слоям. А в следующей статье уже добавить подробностей замена чего на что какой прирост дало. Хотя, и следующей статьи не понадобилось бы тогда.
Имея такие цифры на руках, сами себе бы и ответили, а стоило ли менять прям весь стек. Или достаточно было бы решить вопрос с БД. И не тратить время на замену ЯП.
И как тут уже писали , ни один ЯП не ускоряет выполнения одного и того же запроса к БД. Скорость самого SQL запроса не зависит от ЯП, который его вызывает. А про оптимальность таблиц, индексов, настроек БД под ваши нужды.
Мы полностью переписали приложение, не ограничиваясь заменой СУБД. Новая архитектура на Go позволила оптимизировать потоки, снизить нагрузку на ОЗУ и ЦП, а также использовать все преимущества языка.
Процент заслуги можно считать совокупным: и оптимизация СУБД, и мощь Go сыграли свою роль.
Я правильно понимаю что речь идёт про бекенд вашего сайта который сейчас рендерит статичную страницу 404?
выполнение сложных запросов могло занимать десятки миллисекунд. После перехода на Go с использованием PostgreSQL и GORM и Горутин многие из этих запросов стали выполняться примерно в 10 раз быстрее.
А как Go повлиял и горутины повлияли на снижение времени выполнение запросов?
Go заметно снижает время выполнения запросов благодаря двум ключевым факторам:
- Компиляция в машинный код: Go-компилятор генерирует оптимизированный код, что обеспечивает более быструю работу по сравнению с интерпретируемыми языками.
- Горутины позволяют легко распределять задачи обработки запросов по многим потокам, что минимизирует задержки на I/O и синхронизацию, приводя к ускорению выполнения некоторых операций.
За счёт этих ключевых факторов, есть большое влияние на скорость выполнения запросов.
Почему от Вашего ответа попахивает ИИ?
И что-то ключевые факторы никак не объясняют, с чего вдруг запросы быстрее стали выполняться.
Запах ИИ? Возможно, это аромат индексов, кеширования и connection pooling’а. Или просто свежий воздух, появившийся после оптимизации запросов. Но если хочется разобраться глубже, могу объяснить — только предупреждаю, эффект может быть необратимым.
И что-то ключевые факторы никак не объясняют, с чего вдруг запросы быстрее стали выполняться.
Давайте поговорим про скорость выполнения, насчёт первого и второго фактора.
Go компилируется в машинный код, что обычно и делает его быстрее, чем интерпретируемые или JIT-скомпилированные языки. При это сами двоичные файлы Go оптимизированы для производительности.
В то время, как Nodej.js интерпретируется с помощью движка V8, который использует компиляцию Just-In-Time (JIT). Хотя V8 и высоко оптимизирован, он обычно не может сравниваться с чистой скоростью выполнения компилируемых языков, в нашем случае Go.
Горутины:
Go использует горутины, которые чрезвычайно легковесны по сравнению с потоками. Он может эффективно обрабатывать тысячи параллельных задач, благодаря своей модели параллелизма и планировщику. Что очень важно с больших количествах запросов.
В то время, как Node.js использует управляемую событиями, неблокирующую модель ввода-вывода. Он обрабатывает параллелизм с помощью однопоточного цикла событий, который эффективен для задач ввод-вывода, но может испытывать трудности с задачами, которые связаны с процессором.
К ответу приложим сравнение различных методов и алгоритмов языка программирования проведённых другими разработчиками.
Надеюсь мы ответили на ваш вопрос.


Хм, вообще-то JIT должен (и дает) большую производительность, нежели статически скомпилированный код. В любом случае, код на сервере никак не влияет на скорость выполнения запросов на СУБД.
Горутины никак не помогают выполнять запросы на СУБД (скорее мешают, кстати).
Хм, вообще-то JIT должен (и дает) большую производительность, нежели статически скомпилированный код.
Это в каком мире такие чудеса происходят?
В нашем. У JIT больше данных для оптимизаций, нежели у компилятора, поэтому он выдает более эффективный код. Это же не интерпретация, это как раз про компиляцию. Но JIT знает про конкретные паттерны использования кусочков кода, про статистику переходов и так далее.
Топопвые JIT-компиляторы на Java дают большую производительность для соответствующих кейсах. Но, конечно, нужно набирать соответствующий статистику.
Тот же Go медленнее нормального кода на Java.
Это конечно замечательно что JIT той же JVM умеет делать всякие приятные пакости типа девиртуализации, подгонку каких то параметров под текущие статы системы. Но, я правильно понимаю что исполнением в режиме интерпретатора, JITованием, сбором статистики для JITования и перекомпиляций занимается волшебный дух и дикие тормоза от этих операций не уходят в общий зачет? Также как издержки в виде стаббирования методов, доп инструкций для окружения, тормознутые загрузки классов, верификации байткода на лету, разрешения символических ссылок, в общем все то чего в том же Go или просто нет или оно на этапе компиляции посчиталось, видимо на это мы просто глаза закрываем и верим что программа выполняемая программой работает быстрее чем программа напрямую выполняемая процессором и ОС.
Если код выполняется ровно один раз - то, конечно, скомпилированный быстрее. Если его нужно выполнить миллион раз (а на бэкенде обычно именно такие сценарии), то потери на обвязку реального кода уже не так важны, а вот оптимизации под конкретные сценарии очень даже существенны.
Но для однократных скриптов вообще быстрее какой-нибудь пайтон взять. А вот для нагруженного бэкенда - уже совсем другая история.
Впрочем, на реальную производительность гораздо больше влияет качество библиотек, особенности конфигурации GC и прочие мелочи. Которые пока лучше в JVM (но, может быть, лет за десять golang и догонит).
Потому на каком-нибудь techempower java стабильно (кроме одного теста) обгоняет Go. Впрочем, rust еще быстрее почти всегда.
Если его нужно выполнить миллион раз (а на бэкенде обычно именно такие сценарии), то потери на обвязку реального кода уже не так важны, а вот оптимизации под конкретные сценарии очень даже существенны.
Назовете что за оптимизации что они они делают?
Полного актуального списка я за пять минут не нашел, можно посмотреть на https://advancedweb.hu/profile-based-optimization-techniques-in-the-jvm/
Но это для довольно старой версии JVM, с тех пор еще что-то добавили.
Пока будет вспоминать можете почитать на досуге для общего развития например это
https://go.dev/doc/pgo
и задуматься много ли шансов у "Топоповых JIT-компиляторы на Java" со всеми их издержками перед нативными стеками
Ну вот JIT - это оптимизации PGO, только выполняемые прямо во время исполнения и подстраивающиеся при изменении профиля. Ну и с некоторыми дополнительными фенечками, которые в статике сложно реализовать.
А что так поздно PGO появился в GO? В GraalVM он еще с 19го года, как раз чтобы хоть как-то JIT догнать по производительности.
Ну и не так давно в Hotspot тоже добавили профилирование JIT на старте (а в других-то JVMках оно было очень давно).
вообще-то JIT должен (и дает) большую производительность, нежели статически скомпилированный код
JIT дают большую производительность, чем AOT? Вы из поколения фанатов jvm/js, или как автор статьи - фанат сгенерированных ответов от ИИ?
Ну, вообще очень давно JIT дает более оптимальный код, чем AOT, в чем проблема-то? Данных при выполнении больше, поэтому больше оптимизаций доступно. Да, в JIT сложно с глобальными оптимизациями, но их и в AOT мало кто делает (да и время компиляции взлетает неимоверно).
Понятно, что это не про всякий JIT, но JVMовский долго вылизовали и денег туда вбухано неимоверно.
Я бы еще отметил компактность образов (особенно если собирать FROM scratch) и низкие потребление памяти и CPU.
Я тут небольшой сервис написал на работе с нуля на GO, и когда я согласовывал ресурсы в k8s под него, то изрядно устал объяснять девопсам, что да - поду реально нужно 70-90MB и вот оно там в статике ест 0.01% CPU обрабатывая в онлайне хоть и не сильно большой (до 100 сообщений в секунду), но все-таки поток довольно объемных сообщений из kafka. Они после решений на node/java и т.п. просто не понимают как оно в принципе может хоть что-то делать используя так мало ресурсов.
Но ведь использование ресурсов не означает автоматически
стали выполняться примерно в 10 раз быстрее. Тут скорее всего узкое горлышко должно быть Io.
Да и Kafka это не postgtes и тем более не mongo
"Тут другое"....
В копании много всякого и на всяком.... Но когда девопсам принесли новый сервис (тут нет сравнения было vs стало), который (по их мнению) ест так, что не понято: что он там вообще полезного может сделать, то их немного заклинило. Один раз даже прозвучало "а может такой сервис просто не нужен если так мало требует" :)
Вопрос был не highload/lowload, а в том как он в принципе хоть что-то полезного может делать с такими потребностями в ресурсах.
Ну, вообще перекладывать 100 сообщений в секунду на 0.01% CPU и 90MB можно и на java сделать. Не делают, так как нет смысла ради сотни мегабайт идти в оптимизированные фреймворки и проще воткнуть тот же Spring. Но технически проблем нет.
перекладывать 100 сообщений в секунду на 0.01% CPU и 90MB можно и на java сделать.
Не верю. Могу даже поспорить, что если я в личку скину вам постановку и вы попробуйте это сделать на java c любым фреймворком, то оно в таких ресурсах просто не запустится.
Хм, и в чем проблема? Даже приложение на спринге упаковывают в 64MB памяти и это без GraalVM. После появления модульности появилась возможность очень сильно уменьшать расходы на системные библиотеки, а в остальном все зависит от подхода к разработке.
Да, обычно это нафиг никому не нужно, нет разницы между 64 или 128MB и задачи оптимизировать модули нет. Но никаких принципиальных проблем нет.
Не поясните мне что именно вы называете "упаковывают в 64MB памяти и это без GraalVM"? Это про образ что-ли? Так образ там порядка 10MB (go-шный бинарик + сертификаты для поддержки httpS). Если upx натравить, то go-шный бинарь можно раза в полтора-два ужать. Но вот это уж точно никому не нужно.
Ну и да, там там не только к кафке нужно подцепится и читать, но еще через ETCD лидера выбрать и в пару мест по HTTPS сходить + на s3 архивчик закинуть. Ну и в RAM там основное две структуры: справочник (мапа стрка по строке) и кеш с принятыми данными (мата структур по строке) в каждой структуре порядка 10-12 тысяч элементов.
Нет, конечно, я про размер оперативки для контейнера, содержащего работающий сервис.
Но интеграция с etcd (а зачем оно нужно, кстати, лидер в кафке не в etcd живет), https, s3 не требует кучи памяти. Как и несколько небольших кэшей, хотя все зависит от размера записей в кэше, если там по 10тысяч элементов по килобайту, то они уже 20 мегабайт съедят.
Другое дело, что обычно на Java/Kotlin сделают все на спринге, что позволит потратить на подобные задачи в два раза времени, хотя, конечно, при этом уже нужно будет 128 оперативки, а не 90, но это обычно всем пофиг.
Лидер (через ETCD) выбирается между несколькими подами(экземплярами сервиса) чтобы не грузить апстрим дублями данных. Это не хайлоад, а хайавайлабилити. Кеш данных (10K+) там не по килобайту на запись, но именно он отъедает основную память. Тот же сервис, но с кешем всего на 300 элементов уже работает в 30КБ.
Меня всегда удивляли люди которые выбирают MongoDB. Я понимаю что у него есть преимущества, но я просто не встречал проектов где они были бы лучше любой реляционной БД. Это я молчу про то что транзакции в Монге появились не так давно.
Очень часто люди делают как услышали где-то либо пытаются в хайп.
Здесь никакой конкретики, а значит написали фигово, потому что не понимали, что к чему. И переписали на го с другой СУБД потому что не понимали что к чему и после и просто это сработало.
У монги есть ряд объективных преимуществ:
шардирование из коробки
возможность писать любые данные в формате json без схемы
хорошо работает на вставку данных
Проблема в том, что все эти преимущества нужны примерно в 5% приложений. И зачем люди берут монгу вместо условного постгреса для стандартного круда, это реально вопрос.
Ну и да, все эти преимущества не бесплатные, CAP-теорему не переиграешь, к этому тоже надо быть готовым
возможность писать любые данные в формате json без схемы
Короче говоря когда нужно херак, херак и в продакшен.
возможность писать любые данные в формате json без схемы
хорошо работает на вставку данных
ну такие же преимущества есть и обычных текстовых файлов, или у таблицы вида
key TEXT PRIMARY KEY,
value JSONB
в том же постгресе.
Вообще аргумент про "писать любые данные без схемы" мне непонятен. Такое ощущение что с этими данными никто не планирует позже работать, иначе я не могу понять в чем смысл отсутствия этой самой схемы.
Для этого мы внедрили GORM
Выбрали Go, чтобы улучшить производительность и выбрали GORM чтобы её уничтожить. Brilliant. Возьмите pgx, а ещё замените стандартный encode/json на github.com/json-iterator/go с конфигом var json = jsoniter.ConfigFastest и о чудо, вы ещё на ровном месте серьезно прокачаете производительность.
NestJS давал нам возможность быстро и удобно создавать приложения
Удобно? Вы видели Express, Koa, Hapi? Вот с ними удобно, а NestJS это бегемот неудобный и сверх медленный в плане перформанса.
мы отказались от MongoDB в пользу PostgreSQL
Поздравляю, а разве не очевидно что изначально использовать MongoDB это провальная идея?
Возьмите pgx
Мы внимательно изучали документацию GORM, у них под капотом уже pgx, так зачем делать костыли, когда уже есть достаточно хороший и развивающийся ORM?
а ещё замените стандартный encode/json на github.com/json-iterator/go
У нас собственный утилиты на GO, которые позволяют эффективно работать с JSON, однако спасибо за ваши идеи.
Удобно? Вы видели Express, Koa, Hapi? Вот с ними удобно, а NestJS это бегемот неудобный и сверх медленный в плане перформанса.
Об express можно сразу забыть, он использует устаревший паттерн callback-функций и приводит к печальным последствиям. В остальном Nest js предлагает отличную архитектуру из коробки и заставляет следовать некоторым паттернам разработки.
Поздравляю, а разве не очевидно что изначально использовать MongoDB это провальная идея?
К сожалению, не всё сразу удаётся оценить в нужно виде. Нам пришлось пройти через пробы и ошибки. Во время смены стека, мы решились на этот шаг. Потому-что переписать наш ORM и Репы в Nest.JS было бы слишком затратно.
Express, Koa, Hapi ? Ты серьезно про их удобство ?
Express, Koa, Hapi ? Ты серьезно про их удобство ?
Да, про сравнению с NestJS на Express'e писать одно удовольствие. Легко, просто и быстро.
Код ещё с 2018 года для того чтобы Express был с async/await + обработка непредвиденных ошибок:
// Wrap only Express.js route or middleware functions
export const asyncWrapper = (fn: (req?: express.Request<any>, res?: express.Response, next?: express.NextFunction) => Promise<any>) => (...args) => {
fn(...args)
.catch((err: Error) => {
const req: express.Request = args[0];
const res: express.Response = args[1];
const next: express.NextFunction = args[2];
handleExpressUnexpectedError(err, req, res, next);
});
}app.get('/api/project/:id', GetProjectsById);interface IRequestParams {
id: string;
}
export const GetProjectsById = asyncWrapper(async (req, res, next) => {
const requestParams = req.params as IRequestParams;
const projectId = requestParams.id;
const dbClient = await getDbClient(); // Get connection from pool
const projects = await dbClient.selectOne<IProject>(`SELECT id, name, owner_id, created_at FROM projects WHERE id = :projectId`, {projectId});
successResponse(req, res, next, {
data: projects
});
});Всё предельно просто и понятно, никаких лишних нагромождений и конструкций
лучше бы не приводил этот пример, здесь всё плохо
сложность тестирования
проблемы с масштабируемостью
прямая работа с базой в обработчике запроса
и т.д. и т.п.
сложность тестирования
Для этого же есть end-to-end где полностью вся цепочка сразу тестируется. Это намного качественнее. Какой смысл изолированно протестировать 10 функций которые будут работать без ошибок по отдельности, если реальный запрос будет состоять из цепочки из 10 этих же функций и как раз в таком случае будет падать с ошибкой. Тесты будут зеленые, а API не рабочем, замечательное тестирование.
проблемы с масштабируемостью
Какие ещё проблемы с масштабируемостью??? Сколько угодно экземпляров запускай и вперед. С чего вы это взяли?
прямая работа с базой в обработчике запроса
И что? В любом случае работа с базой данных будет вызвана в обработчике запроса, сразу или через 1-2-10 функций. Мы либо сразу понимаем что мы делаем и что происходит, либо бегаем по десятку файлов, все пытаемся удержать в уме, чтобы выстроить цепочку что происходит, что куда прокидывает, что вызываем и т.п.
Keep It Simple, слышали о таком? В этом примере сразу понятно что происходит, вообще любому человеку. Т.е. при таком подходе ситуация когда мы написали код, а через 2 месяца к нему вернулись и не понимаем что тут уже происходит просто исключена, т.к. KISS во всей красе.
и т.д. и т.п.
И что же ещё?
я правильно понимаю , что для вас масштабируемость это запуск нескольких экземпляров ? предлагаете полностью перейти на e2e тесты ? и kiss это не что иное как все в одном хендлере держать ?
я правильно понимаю , что для вас масштабируемость это запуск нескольких экземпляров ?
Во первых не по прояснили что конкретно вы имеете в виде под словом "масштабируемость". Для меня это в первую очередь про производительность, т.е. способность держать нагрузки, а она бывает 2х видов, горизонтальная и вертикальная. Ни там ни там, никаких проблем быть не может. Возможно вы про масштабируемость кода, и опять, вообще никаких проблем. Если вы что-то другое по этом понимаете, уточните тогда.
предлагаете полностью перейти на e2e тесты ?
Есть такой принцип, под каждую задачу - свой инструмент. e2e это самый надежный способ тестирования АПИ.
Unit тесты это больше про тестирование функционала библиотек, или каких то специфических функций в проекте(но опять же, она так же и покроется при e2e).
Поэтому да, по умолчанию e2e более чем с головой всё покрывает и дает гораздо больше гарантий нежели Unit'ы. А я выбираю конечно же надежность.
и kiss это не что иное как все в одном хендлере держать?

Это не что иное как - простые вещи должны быть простым. И да, в 99.99% проектах если все сразу написано в хэнделе это гораздо проще и лучше. А если логика обработка конкретного хэндлера реально очень громоздкая, то разумеется можно и нужно её по логическим частям вынести в функции, в других файлах. Но чтобы в хэндлере была реально громоздкая логика, это шанс исчезающе мал.
Но если для вас сходить в базу, сходить в кэш, пульнуть что-то в очередь, запустить функцию валидации входящих данных это громоздкая логика, то да) В таком случае надо все разбивать по файлам в которых не более 20 строк кода.
Прямое управление памятью и минимальное время сборки мусора
Вы бы после того как Вам ChatGPT сгенерирует статью хотя бы ее прочитал перед тем как выкладывать. Так чисто для разнообразия.
Это очень странная статья и не менее странные обсуждения в комментариях.
У меня нет коммерческого опыта на Go, писал я на нем только для себя, один пэт до сих пор работает на нем, хоть это и бессмысленно, так что что-то написать я на Go смогу, но с большим спектром реальных проблем не сталкивался. Однако, к сожалению, есть опыт коммерческой разработки на Nest, но не стоит думать, что я защищаю инструмент и тем более делаю это из большой любви к нему. Nest отчаянно пытается быть фреймворком и Spring'ом от мира js/ts. Кое-где даже получается.
NestJS давал нам возможность быстро и удобно создавать приложения благодаря своей структуре и широкому набору функционала.
Nest - это не про быстрое создание приложений, в отличие от Spring Boot. Ручная компановка модулей мне нравится, но она создает дополнительные действия и не оставляет прав на ошибку с менеджментом провайдеров, импортов и экспортов. А для широково набора функционала нужны как дополнительные пакеты самого Nest, которые кстати не имеют общего роадмапа версий (простой пример - nest/core и nest/common 11 семейства версий, которые не поддерживаются nest/axios 4 версии), так и сторонние, которые к тому же имеют свойства прекращения поддержки (привет KafkaJS).
Компилируемый Go-код позволяет достичь высокой скорости исполнения приложений, что особенно важно при нашей работе с большими объёмами данных и множеством одновременных соединений.
В случае, если "проблемы" возникают после того, как код получил эти данные, с учетом выполнения большого количества "синхронных" операций, которые к тому же могут быть исполнены параллельно, проще говоря, если проблема точно не в производительности БД. Однако из прочтенного дальше я начинаю в этом сомневаться.
Благодаря строгой типизации и лаконичному синтаксису, код на Go становится проще для поддержки и рефакторинга, что снижает вероятность возникновения ошибок в критических местах приложения.
Лаконичный синтаксис Go это та еще тема для холивара, но как по мне больше дело вкуса, однако я бы не стал утверждать, что синтаксис Go упрощает рефакторинг и поддержку. Лично я считаю, что он слишком лаконичен в некоторых местах, настолько, что это скорее мешает и путает. Строгая типизация есть и в ts, при том сделать её можно настолько строгой, что Вам будет больно. Тут видимо речь была скорее про runtime type check.
Одним из центральных изменений стала смена базы данных – мы отказались от MongoDB в пользу PostgreSQL.
А есть какие-то объективные показатели, как миграция между разными СУБД повлияла на производительность без смены стэка языка программирования? То есть вы поменяли сразу две больших части приложения, почему тогда вы утверждаете, что проблема была именно в Nest, а Go стал той самой золотой пулей?
Это решение мотивировалось следующими причинами:
Проще говоря изначально Mongo не отвечал вашим потребностям и не совсем понятно, как и почему был выбран. Это хорошо, что вы нашли подходящее решение и системная или даже архитектурная ошибка была устранена. Не понятно только, какое отношение это имеет к отказу от Nest в пользу Go. На этом пункте есть ощущение, что команда просто решила поменять стэк по одной из причин: безнадежность, приход нового архитектора проекта, команда захотела научиться чему-то новому, расширить свой стэк и поднять свою ценность на рынке соискателей. Надеюсь, что дело не в последнем, ибо искренне не понимаю, почему за это действо платить должен бизнес.
Благодаря GORM, большинство рутинных операций по взаимодействию с базой данных стало лаконичным и структурированным, что позволило сократить время на разработку и устранение возможных ошибок.
TypeORM не справляется с простейшими рутиннымы взаимодействиями с БД? Я не спорю, что TypeORM достаточно тормознутый и сильно проигрывает работе через драйвер БД и понял бы, если бы именно производительность стала поинтом, но в чем преимущество времени на разработку и поддержку в случае сравнения двух данных ORM я не понимаю.
GORM предоставляет удобные инструменты для управления версиями схемы базы данных, что значительно облегчило процесс перехода и интеграции новых функциональностей.
С каких это пор TypeORM не поддерживает миграции? Это явно не преимущество, это базовый функционал каждого из инструментов. Если вы, конечно, использовали в качестве ORM ранее Prisma, я бы понял, но тут так же были бы вопросы к выбору инстументария изначально.
Использование ORM позволило организовать код по слоям — от доступа к данным до бизнес-логики, сделав архитектуру более прозрачной и удобной для поддержки.
Это вопрос компетенций команды, структуры и организации кода и архитектуры. Всё это вы можете сделать и с помощью TypeORM, так что плюс экосистемы Go.
Касательно приведенных далее плюсов Go я скорее согласен, но хотелось бы не читать их повторно, а увидеть что-то и про минусы языка, которые не понравились команде.
но и переосмыслить архитектуру приложения.
Это можно сделать и без смены стэка.
После перехода на Go с использованием PostgreSQL и GORM и Горутин многие из этих запросов стали выполняться примерно в 10 раз быстрее. В результате, ряд операций начинают завершаться менее чем за миллисекунду, что значительно повышает отзывчивость нашего сервиса.
И всё же, какое влияние на это оказала конкретно PostgreSQL? А точнее, какой припрост отдельно от PostgreSQL и отдельно от Go + GORM?
В общем-то я рад, что ваша команда переписала продукт, попробовала что-то новое, так еще и успешно. Однако же хочется понимать, как вы продали это бизнесу? Единственным возможным вариантом вижу, что вы пообещали прирост производительности в 10 раз и смогли в него попасть, заранее зная, что он будет примерно таким, а значит где-то в команде или компании уже были гоферы, при том достаточно опытные.
С годами, у меня крепнет уверенность, что в улучшениях, наступивших после «у нас была система на Х, мы переписали её на Y» основная заслуга не в «на Y», а в «переписали».
О последнем, собственно, писал ещё Голуб в своём руководстве по стрельбе в колено, но кто ж так просто даст переписать всё с Х на Х, но с учётом опыта?
Хотел написать подобную статью с критикой nest.js и переходом на clojure, но боюсь теперь что закидают помидорами за отсутствие конкретики 😂
Подозреваю, что достаточно было отказаться от MongoDB.
Вы чего, GORM в прод засунули?
Он по сути только для прототипирования и годится.
Предвкушаю море хейта от тех, кто не любит писать запросы ручками и сразу обрисую свою позицию.
Разрабатывая бэк, мы в 99% получаем приложение с IO bound нагрузкой. Это значит, что сервис тратит больше всего времени на обмен данными с чем бы то ни было. А ORM системы из-за дополнительных абстракций, а зачастую ещё и используя рефлексию, заметно увеличивают время обработки запроса. Перед релизом можно и нужно реализовывать репо используя запросы написанные ручками и хороший драйвер.
Я не говорю, что ORM не нужно использовать. Скорее наоборот, если тебе нужно быстренькое и на коленках накидать прототип решения, то это отличный выбор, но не в прод)
У Вас кстати сайт не открывается
Статья о том как поменяли бд с Монго на postgres и заюзали необходимую ОРМ. не благодарите.
MongoDB полностью отвечает ACID
Можете написать конкретную проблематику которую вы решали с переездом на postgresql?
Информация
- Сайт
- hikasami.ru
- Дата регистрации
- Дата основания
- Численность
- 2–10 человек
- Местоположение
- Канада
- Представитель
- Никита Кононенко
GO: Как и почему мы отказались от Nest.JS