Баланс полузнков

Баланс полузнков

Igor Kamyshev

У меня есть совсем небольшой сервис notify — он пересылает HTTP-запросы в Telegram. Он очень простой: в нём даже авторизации нет.

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

Оказалось, все мои небольшие сервисы на Node.js потребляют по 100-200 Мб памяти. С одной стороны, это не такая уж и проблема, можно просто платить 40 долларов, а не 5. С другой стороны, мне стало обидно, что маленькие, почти ничего не делающие сервисы, потребляют столько памяти. Я погрузился в исследование.

Взял notify и посмотрел, как обстоят дела с потреблением памяти внутри приложения. Оказалось, что непосредственно приложение забирает всего 70 Мб (что тоже дофига), а все остальное сжирается окружающей средой, по большей части yarn. Я расскажу в отдельном посте, зачем yarn жрет столько ресурсов и почему с этим придется смириться.

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


Результаты супер-очевидные, но, как мне кажется, все равно интересные.

Elixir

Первая моя мысль — взять Elixir. Это простой и удобный язык с достаточно развитой экосистемой, он работает поверх виртуальной машины и никакие проблемы с нативными зависимостями не будут мешать делать вещи.

Приложения на Elixir работало так же быстро, как оригинальная имплементация на JS, но потребляло в 2-3 раза меньше памяти, размер контейнера снизился в 10 раз (шок). Это классный результат, но не то чего я хотел. Мне все ещё казалось, что 70 Мб памяти для такого простого приложения — это многовато.

Go

Следующим на очереди был Go. Если на Elixir я уже немного писал, и довольно много читал, то с Go — встретился впервые.

В итоге я получил фантастические результаты. Приложение потребляет 4 Мб памяти (в 50 раз меньше), контейнер весит 13 Мб (почти в 20 раз меньше оригинального решения). Это то, чего я хотел. Немного ресурсов для простой задачи.

Забавно, что Go считается менее выразительным языком, чем JS, но кода больше не стало. Как было около 100 строк, так и осталось. Читаемость тоже, вроде не пострадала.

И што?

Никита Прокопов в 2018 году написал статью Software disenchantment, где описал свое разочарование современным состоянием IT — компьютеры становятся быстрее, но программы становятся медленнее. И это правда печально. Я хочу научиться делать такие приложения, которые не будут разочаровывать.

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

Это окей. Просто, мне кажется, что в нашей работе стало слишком много крайностей — все ради DX.

Report Page