fa
Feedback
Node.JS [ru] | Серверный JavaScript

Node.JS [ru] | Серверный JavaScript

رفتن به کانال در Telegram

Node.js, backend и AI-разработка: статьи, новости, вайбкодинг, автоматизация и работа с ИИ-агентами. Личный блог автора - @just_genych По вопросам рекламы или разработки: @g_abashkin РКН: https://vk.cc/cJPGOP

نمایش بیشتر

📈 تحلیل کانال تلگرام Node.JS [ru] | Серверный JavaScript

کانال Node.JS [ru] | Серверный JavaScript (@we_use_js) در بخش زبانی روسی بازیگری فعال است. در حال حاضر جامعه شامل 11 186 مشترک است و جایگاه 11 029 را در دسته فناوری و برنامه‌ها و رتبه 58 057 را در منطقه روسيا دارد.

📊 شاخص‌های مخاطب و پویایی

از زمان ایجاد در невідомо، پروژه رشد سریعی داشته و 11 186 مشترک جذب کرده است.

بر اساس آخرین داده‌ها در تاریخ 09 ژوئیه, 2026، کانال فعالیت پایداری دارد. در ۳۰ روز گذشته تغییر اعضا برابر -94 و در ۲۴ ساعت گذشته برابر -9 بوده و همچنان دسترسی گسترده‌ای حفظ شده است.

  • وضعیت تأیید: تأیید نشده
  • نرخ تعامل (ER): میانگین تعامل مخاطب 7.00% است و در ۲۴ ساعت نخست پس از انتشار، محتوا معمولاً 4.69% واکنش نسبت به کل مشترکان کسب می‌کند.
  • دسترسی پست‌ها: هر پست به طور میانگین 783 بازدید دریافت می‌کند. در اولین روز معمولاً 525 بازدید جمع‌آوری می‌شود.
  • واکنش‌ها و تعامل: مخاطبان به‌طور فعال حمایت می‌کنند؛ میانگین واکنش به هر پست 2 است.
  • علایق موضوعی: محتوا بر موضوعات کلیدی مانند node.js, javascript, node, process.exit(1, модуль تمرکز دارد.

📝 توضیح و سیاست محتوایی

نویسنده این فضا را محل بیان دیدگاه‌های شخصی توصیف می‌کند:
Node.js, backend и AI-разработка: статьи, новости, вайбкодинг, автоматизация и работа с ИИ-агентами. Личный блог автора - @just_genych По вопросам рекламы или разработки: @g_abashkin РКН: https://vk.cc/cJPGOP

به لطف به‌روزرسانی‌های پرتکرار (آخرین داده در تاریخ 10 ژوئیه, 2026)، کانال همواره به‌روز و دارای دسترسی بالاست. تحلیل‌ها نشان می‌دهد مخاطبان به‌طور فعال با محتوا تعامل دارند و آن را به نقطه اثرگذاری مهم در دسته فناوری و برنامه‌ها تبدیل کرده‌اند.

11 186
مشترکین
-924 ساعت
-337 روز
-9430 روز
جذب مشترکین
ژوئیه '26
ژوئیه '26
+8
در 0 کانال‌ها
ژوئن '26
+83
در 0 کانال‌ها
Get PRO
مه '26
+282
در 22 کانال‌ها
Get PRO
آوریل '26
+78
در 0 کانال‌ها
Get PRO
مارس '26
+70
در 0 کانال‌ها
Get PRO
فوریه '26
+145
در 0 کانال‌ها
Get PRO
ژانویه '26
+137
در 57 کانال‌ها
Get PRO
دسامبر '25
+88
در 25 کانال‌ها
Get PRO
نوامبر '25
+129
در 69 کانال‌ها
Get PRO
اکتبر '25
+25
در 28 کانال‌ها
Get PRO
سپتامبر '25
+145
در 85 کانال‌ها
Get PRO
اوت '25
+79
در 6 کانال‌ها
Get PRO
ژوئیه '25
+230
در 7 کانال‌ها
Get PRO
ژوئن '25
+228
در 9 کانال‌ها
Get PRO
مه '25
+314
در 4 کانال‌ها
Get PRO
آوریل '25
+131
در 0 کانال‌ها
Get PRO
مارس '25
+333
در 21 کانال‌ها
Get PRO
فوریه '25
+110
در 3 کانال‌ها
Get PRO
ژانویه '25
+258
در 18 کانال‌ها
Get PRO
دسامبر '24
+418
در 53 کانال‌ها
Get PRO
نوامبر '24
+447
در 40 کانال‌ها
Get PRO
اکتبر '24
+294
در 27 کانال‌ها
Get PRO
سپتامبر '24
+304
در 33 کانال‌ها
Get PRO
اوت '24
+300
در 24 کانال‌ها
Get PRO
ژوئیه '24
+333
در 34 کانال‌ها
Get PRO
ژوئن '24
+348
در 32 کانال‌ها
Get PRO
مه '24
+383
در 28 کانال‌ها
Get PRO
آوریل '24
+368
در 27 کانال‌ها
Get PRO
مارس '24
+277
در 10 کانال‌ها
Get PRO
فوریه '24
+771
در 3 کانال‌ها
Get PRO
ژانویه '24
+358
در 24 کانال‌ها
Get PRO
دسامبر '23
+589
در 34 کانال‌ها
Get PRO
نوامبر '23
+212
در 17 کانال‌ها
Get PRO
اکتبر '23
+379
در 7 کانال‌ها
Get PRO
سپتامبر '23
+153
در 0 کانال‌ها
Get PRO
اوت '23
+898
در 0 کانال‌ها
Get PRO
ژوئیه '23
+1 381
در 0 کانال‌ها
Get PRO
ژوئن '23
+1 194
در 0 کانال‌ها
Get PRO
مه '23
+718
در 0 کانال‌ها
Get PRO
آوریل '23
+387
در 0 کانال‌ها
Get PRO
مارس '23
+495
در 0 کانال‌ها
Get PRO
فوریه '23
+46
در 0 کانال‌ها
Get PRO
ژانویه '23
+1 101
در 0 کانال‌ها
Get PRO
دسامبر '22
+58
در 0 کانال‌ها
Get PRO
نوامبر '22
+55
در 0 کانال‌ها
Get PRO
اکتبر '22
+92
در 0 کانال‌ها
Get PRO
سپتامبر '22
+289
در 0 کانال‌ها
Get PRO
اوت '22
+35
در 0 کانال‌ها
Get PRO
ژوئیه '22
+15
در 0 کانال‌ها
Get PRO
ژوئن '22
+22
در 0 کانال‌ها
Get PRO
مه '22
+30
در 0 کانال‌ها
Get PRO
آوریل '22
+34
در 0 کانال‌ها
Get PRO
مارس '22
+26
در 0 کانال‌ها
Get PRO
فوریه '22
+15
در 0 کانال‌ها
Get PRO
ژانویه '22
+27
در 0 کانال‌ها
Get PRO
دسامبر '21
+258
در 0 کانال‌ها
Get PRO
نوامبر '21
+2 073
در 0 کانال‌ها
Get PRO
اکتبر '21
+38
در 0 کانال‌ها
Get PRO
سپتامبر '21
+273
در 0 کانال‌ها
Get PRO
اوت '21
+37
در 0 کانال‌ها
Get PRO
ژوئیه '21
+184
در 0 کانال‌ها
Get PRO
ژوئن '21
+294
در 0 کانال‌ها
Get PRO
مه '21
+79
در 0 کانال‌ها
Get PRO
آوریل '21
+119
در 0 کانال‌ها
Get PRO
مارس '21
+106
در 0 کانال‌ها
Get PRO
فوریه '21
+196
در 0 کانال‌ها
Get PRO
ژانویه '21
+130
در 0 کانال‌ها
Get PRO
دسامبر '20
+3 528
در 0 کانال‌ها
تاریخ
رشد مشترکین
اشارات
کانال‌ها
10 ژوئیه0
09 ژوئیه0
08 ژوئیه0
07 ژوئیه0
06 ژوئیه+1
05 ژوئیه+2
04 ژوئیه0
03 ژوئیه+2
02 ژوئیه+3
01 ژوئیه0
پست‌های کانال
Телеграм канал AI для бизнеса AI - не будущее. Это настоящее вашего бизнеса. Телеграм-канал "AI для бизнеса" знает все о внед
+4
Телеграм канал AI для бизнеса AI - не будущее. Это настоящее вашего бизнеса. Телеграм-канал "AI для бизнеса" знает все о внедрении и использовании искусственного интеллекта в бизнесе в России и мира. Только со своими подписчиками канал делится: - как внедрить искусственный интеллект в реальные бизнес-процессы, - разборами кейсов: как компании сократили затраты на 30-50% с помощью AI, - лайфхаками по автоматизации рутинных задач, - новостями мира AI и разборами трендов. Сами давно читаем и вам советуем подписаться. Подписаться #реклама 16+ О рекламодателе

2
⁣Грейсфул шатдаун: как SIGTERM и postMessage ломают порядок сигналов Каждый middle/senior разработчик Node.js сталкивался с грейсфул шатдауном, но редкий замечает скрытую ловушку — смешивание process.on('SIGTERM') и Worker.prototype.postMessage. Из-за разницы приоритетов событий и микрозадач теряются данные в production. Проблема приоритетов событий SIGTERM — системное событие с высоким приоритетом в цикле событий. postMessage — асинхронная операция, попадающая в очередь микрозадач. Если SIGTERM приходит до завершения отправки сообщения, оно обрабатывается уже после shutdown. Результат — потеря данных, которые должны были уйти в Worker. Production-пример и диагностика Рассмотрим типичный код: process.on('SIGTERM', () => { console.log('Shutdown'); worker.terminate(); }); worker.postMessage({ type: 'data', payload: result }); Здесь postMessage может быть прерван сигналом. Как диагностировать: * Логируйте порядок событий с таймстемпами. * Используйте process.on('SIGTERM', { once: true }) для однократного вызова. * Проверяйте флаг isShuttingDown перед любым postMessage. Практическое исправление Решение — флаги состояния: let isShuttingDown = false; process.on('SIGTERM', () => { isShuttingDown = true; }); if (!isShuttingDown) worker.postMessage({ ... }); Для надёжности — SharedArrayBuffer для атомарной синхронизации между основным потоком и Worker, если требуется строгий контроль. Типичная ошибка Многие путают: проблема не в доступе к process из Worker threads — Worker его не имеет. Корень — порядок микрозадач в основном потоке, где postMessage может быть отложен после обработки SIGTERM. Вывод: Используйте флаги состояния перед асинхронными операциями в обработчиках сигналов — это предотвращает потерю данных при грейсфул шатдауне.
383
3
Прошла половина лета Выгореть ещё успеем. А пока лето — отправляемся загорать. И не просто так, а со скидкой 5000 рублей по п
Прошла половина лета Выгореть ещё успеем. А пока лето — отправляемся загорать. И не просто так, а со скидкой 5000 рублей по промокоду NETSIL от Яндекс Путешествий. Забронировать #реклама travel.yandex.ru О рекламодателе
447
4
Маск внезапно выкатил Grok 4.5 — первую версию, заточенную под код и агентов 😨 Обучали её в связке с Cursor, и по бенчмаркам+1
Маск внезапно выкатил Grok 4.5 — первую версию, заточенную под код и агентов 😨 Обучали её в связке с Cursor, и по бенчмаркам она уже перепрыгивает GPT-5.5, заодно держится на уровне Opus 4.8. Terminal-Bench: у неё 83%, а у Opus 4.8 — 78,9%. Прайсинг: $2/$6 за миллион токенов. «Opus-уровень, но шустрее, меньше жрет токенов и дешевле» — написал Маск в X. В Cursor она уже есть на всех тарифах. Завтра ждем ответочку от Альтмана 😊 👉 Node.JS [ru]
474
5
🔍Тестовое собеседование на Frontend-разработчика с ex. TeamLead в Сбер 9 июля(в четверг!) в 19:00 по мск приходи онлайн на о
🔍Тестовое собеседование на Frontend-разработчика с ex. TeamLead в Сбер 9 июля(в четверг!) в 19:00 по мск приходи онлайн на открытое собеседование, чтобы посмотреть на настоящее интервью на Middle Frontend-разработчика. Как это будет: 📂 Даниил Дмитриев, старший разработчик в R-Vision, ex. TeamLead в Сбер, будет задавать реальные вопросы и задачи разработчику-добровольцу 📂 Даниил будет комментировать каждый ответ респондента, чтобы дать понять, чего от вас ожидает собеседующий на интервью 📂 В конце можно будет задать любой вопрос Даниилу Это бесплатно. Эфир проходит в рамках менторской программы от ШОРТКАТ для Frontend-разработчиков, которые хотят повысить свой грейд, ЗП и прокачать скиллы. Переходи в нашего бота, чтобы получить ссылку на эфир → @shortcut_front_bot Реклама. О рекламодателе.
560
6
Гео-аналитическая платформа вдвоём за 2,5 месяца: история spec-driven разработки Автор поделился опытом старта проекта с чист
Гео-аналитическая платформа вдвоём за 2,5 месяца: история spec-driven разработки Автор поделился опытом старта проекта с чистого листа. Перед ним стояла амбициозная задача, не было легаси и была полная свобода выбора подхода. Он решил максимально довериться AI и больше не трогать код. Изначально были сомнения, что такой подход выдержит реальный масштаб, так как опыт подсказывал, что чем больше проект, тем быстрее AI путается в контексте и упирается в лимиты. Через 2,5 месяца работы вдвоём удалось запустить гео-аналитическую платформу. Автор отмечает, что в до-AI эпоху такой проект строили бы годами. Этот опыт изменил его представление о разработке. Читать далее
520
7
МТС Линк. Всё для коммуникации в команде 💻Платформа для общения, работы и обучения онлайн с поддержкой ИИ Встречи, чаты и зв
МТС Линк. Всё для коммуникации в команде 💻Платформа для общения, работы и обучения онлайн с поддержкой ИИ Встречи, чаты и звонки в одном приложении ✅МТС Линк доступен в AppStore. Берите работу с собой и оставайтесь на связи с коллегами в любое время Зарегистрироваться #реклама 16+ mts-link.ru О рекламодателе
512
8
Как один отказ бизнесу сэкономил компании 10 миллионов рублей К концу проекта внедрения нового биллинга бизнес предложил пере
Как один отказ бизнесу сэкономил компании 10 миллионов рублей К концу проекта внедрения нового биллинга бизнес предложил перенести архивные продукты и исторические данные по ним. Архивные продукты использовались редко — для разбора спорных ситуаций с клиентами. Изначально было решено не избавляться от старого биллинга, а использовать его для чтения ретроданных. После оценки работ выяснилось, что типового механизма нет — нужно менять архитектуру, разрабатывать сценарии миграции, тестировать и поддерживать. Оценка составила около 10 миллионов рублей. Пересчет финансовой модели показал, что дополнительные инвестиции увеличивают срок окупаемости проекта на один год. Компания вкладывала бы деньги в функциональность без измеримой бизнес-ценности. Было принято решение отказать бизнесу и предложить оставить эти данные доступными для чтения в legacy биллинге. Источник
571
9
⁣Сидеть и работать в корпорации страшно, жизнь-то мимо проходит. Уходить строить бизнес страшно, а вдруг прогорит. Один из вариантов - разрабатывать свой пет-проект по вечерам. Многие успешные компании, например, Twitter, создавались именно так. Это не значит, что ваш проект обязательно заработает миллиарды, но заработать больше, чем в найме, и получить ценный опыт вполне реально. Перед началом разработки появляется множество вопросов, например: – Как выбрать идею для пет-проекта? – Что нужно знать про маркетинг? – Как запуститься и довести до первых продаж не имея бюджета на рекламу? В телеграм-канале Твой пет проект, Михаил Табунов делится своим опытом с разработчиками и менеджерами. Он рассказывает, где искать идею для нового проекта, что нужно знать о маркетинге, как запустить стартап и привлечь первых 10 клиентов, а также о многих других важных вещах. Подписывайтесь на Твой пет проект получайте пользу от практиков рынка!
563
10
Онлайн-магистратура в ИТМО и МИФИ Программы онлайн-магистратуры ИТМО и МИФИ в партнёрстве с Яндексом. Актуальные знания, прак
Онлайн-магистратура в ИТМО и МИФИ Программы онлайн-магистратуры ИТМО и МИФИ в партнёрстве с Яндексом. Актуальные знания, практическое обучение и гибкий график. Учитесь, совмещая с работой. Доступна господдержка оплаты, отсрочка от армии Перейти на сайт #реклама 16+ practicum.yandex.ru О рекламодателе
584
11
PROvoke на Analyst Days: как мы выступали в корсете и что из этого вышло Привет, Хабр! В первой части я рассказывал, как мы с
PROvoke на Analyst Days: как мы выступали в корсете и что из этого вышло Привет, Хабр! В первой части я рассказывал, как мы с Татьяной Маркиной готовили доклад «Провоок» на Analyst Days — про споры, студию в Краснодаре, логистический ад и идею с кнутом и пряником. А сегодня — вторая часть: что произошло на сцене, какие роли мы играли, почему корсет так и не вышел в свет, и как один разговор в кулуарах перевернул моё понимание публичных выступлений. Подробности — во второй части статьи. Источник: Анатомия парного доклада: как мы собирали «PROvoke» на Analyst Days. Часть 2 — выступление и фидбек
629
12
Выберите свой автомобиль Belgee на официальном сайте Сочетание надёжности и комфорта. Широкий выбор комплектаций Узнать больш
Выберите свой автомобиль Belgee на официальном сайте Сочетание надёжности и комфорта. Широкий выбор комплектаций Узнать больше #реклама belgee.ru О рекламодателе
595
13
⁣Buffer.write со str.length — тихая бомба под production. Ты пишешь в буфер, передаёшь offset через str.length, и данные записываются в неверное место. Всё молча. Никаких ошибок. Просто битая информация. В UTF-8 один символ может занимать от 1 до 4 байт. «Привет» — это 6 символов, но 12 байт. Если offset посчитан по длине строки, ты фактически говоришь Buffer: «запиши мне данные со смещением 6 байт». А нужно было с 12. Разница в два раза. Я такое видел в production: кусок бинарного заголовка перезаписывался, файл читался как мусор. И никто не мог понять, почему. Диагностика — используй Buffer.byteLength(str, 'utf8') для вычисления реального размера в байтах; — сравнивай str.length и Buffer.byteLength(str) — если различаются, в строке есть не-ASCII символы; — проверяй логи, где размер буфера и смещение не сходятся. Исправление Простое решение: const byteOffset = Buffer.byteLength(str, 'utf8'); buf.write(str, byteOffset); Или вообще запиши с начала: buf.write(str, 0, 'utf8'). Типичная ошибка — расчёт offset вручную через str.length * someCoefficient — это антипаттерн; — молчаливое переполнение буфера без проверки остаточного места; — путаница между символьным и байтовым смещением в одном бинарном сериализаторе. Профилактика — всегда считай байты через Buffer.byteLength(); — не вычисляй offset вручную для строк с Unicode; — в TypeScript включай strict — он ловит часть таких косяков. Вывод: Silent data corruption — гадость редкая, но реальная. Проверь код: не используешь ли str.length как offset для Buffer.write?
600
14
Будьте в центре внимания — с Прайм-баннером С новым медийным форматом Прайм-баннер вы можете не просто размещать рекламу на с
Будьте в центре внимания — с Прайм-баннером С новым медийным форматом Прайм-баннер вы можете не просто размещать рекламу на самых популярных сервисах Яндекса с высоким Brand Safety, а гибко управлять кампанией: — Оптимизируйте стоимость размещения — формат доступен по аукционной модели без порога входа — Настраивайте кросс-частоту и исключайте из показов неподходящие площадки — Размещайтесь как на уже знакомых, так и на уникальных местах показа — Выбирайте нужные среди более чем 600 таргетингов без наценок — Оценивайте результаты с помощью исследований Brand Lift, Search Lift, Visit Lift и Target Lift Узнайте больше о возможностях Прайм-баннера для вашего бренда. Узнать больше #реклама 16+ yandex.ru О рекламодателе
580
15
Как я хакнул рынок труда: пишем свой ИИ-комбайн для автооткликов на HH.ru Если вы хоть раз искали работу в IT за последний год, то знаете, что рынок беспощаден к новичкам. Нужно откликнуться на сотни вакансий, а в итоге получаешь отказы от роботов. Чтобы пробиться через фильтры HR, нужно под каждую вакансию писать уникальное сопроводительное письмо. В этой статье автор сделал полный разбор того, как написал собственного автономного ИИ-агента, который ищет вакансии, фильтрует мусор с помощью локальной нейросети, пишет персонализированные сопроводительные письма и отчитывается в Telegram, пока пользователь спокойно занимается своими делами. Скрипт задумывался бесплатным, автономным и не требующим настройки вокруг платных API. Читать далее
704
16
⁣Неявный deadlock в Node.js: AsyncLocalStorage + worker_threads + await в run() Многие знают AsyncLocalStorage для проброса контекста, но скрещивание его с пулом worker_threads и await внутри колбэка run() создаёт неочевидный deadlock. Эта ошибка часто остаётся незамеченной до первого production-инцидента, когда пул потоков залипает при высокой нагрузке. Как проявляется deadlock Внутри run() вы помещаете ID запроса и вызываете await, пока воркер не закончит задачу. Если потоков в пуле ограниченное число (например, 2), а запросов много, каждый await блокирует run(), не освобождая поток из пула. Воркеры заняты, потоки ждут await — контекст AsyncLocalStorage не отпускается до полного завершения колбэка. Пример problem: const als = new AsyncLocalStorage(); async function processRequest(data) { await als.run({ requestId: Date.now() }, async () => { const worker = new Worker('./worker.js'); const result = await new Promise((resolve, reject) => { worker.on('message', resolve); worker.on('error', reject); }); console.log(als.getStore().requestId); }); } Как обнаружить - Залогируйте время выполнения воркеров: рост с увеличением числа запросов — тревожный сигнал. - Используйте clinic.js или 0x: они покажут аномальные пики ожидания. - Типичная ошибка: пул из 2 воркеров и 100 параллельных запросов — все зависнут через несколько секунд. Практический совет Не оставляйте await внутри run(). Вынесите ожидание наружу: async function processRequest(data) { const worker = new Worker('./worker.js'); const result = await new Promise(/*...*/); als.run({ requestId: Date.now() }, () => { console.log(als.getStore().requestId); }); } Либо передавайте контекст через worker.postMessage() — это проще и исключает deadlock. Предупреждение AsyncLocalStorage отлично работает на веб-серверах с краткими синхронными операциями, но await внутри run() с ограниченным пулом потоков — прямой путь к deadlock. Проверяйте такие места на этапе code review. Вывод: Избегайте await внутри колбэка AsyncLocalStorage.run() при работе с пулом worker_threads — выносите асинхронное ожидание наружу или передавайте контекст через сообщения.
632
17
⁣Диагностика и устранение неявной фрагментации кучи в Node.js Long-lived HTTP серверы с разными по размеру payload часто страдают от "дырявой" кучи, хотя утечек памяти нет. Память фрагментируется из-за чередования маленьких и больших Buffer-ов, что ведет к росту RSS и частым GC паузам. Как проявляется фрагментация После обработки HTTP запросов создаются Buffer-ы разного размера: маленькие для заголовков, большие для тела. GC освобождает их неупорядоченно, оставляя пустоты между выделенными блоками. Со временем это увеличивает RSS на 20-40% без утечек. Симптомы: падение производительности через 12+' часов работы, частые stop-the-world паузы GC. Диагностика в production Первый шаг — трассировка с --trace-gc. Запустите: NODE_OPTIONS="--trace-gc" node app.js. В выводе ищите Mark-sweep паузы >50ms. Второй шаг — сравнение heapdump-ов через час и сутки работы в Chrome DevTools. Ищите фрагментированные объекты Buffer, разбросанные по куче. Третий шаг — проверьте флаги V8: node --v8-options | grep -i "heap.*frag". Решение: Buffer Pool для однородности Создайте пул Buffer-ов фиксированного сегмента, например 1024 байта. Это снижает разнообразие размеров и уменьшает фрагментацию. Пример: class BufferPool { constructor(size = 1024) { this.pool = []; this.size = size; } alloc(size) { if (size > this.size) return Buffer.allocUnsafe(size); if (this.pool.length) return this.pool.pop().slice(0, size); return Buffer.allocUnsafe(this.size); } free(buf) { this.pool.push(buf); } } Практические советы и ошибки - Для максимального снижения фрагментации используйте Buffer.allocUnsafeSlow вместо Buffer.allocUnsafe в пуле — он избегает shared memory pool. - Настройте --max-old-space-size и --optimize-for-size для ограничения кучи. - Типичная ошибка — использовать Buffer.allocUnsafe для всех случаев без разбора. Это увеличивает фрагментацию из-за случайных размеров. - В Node 20+ можно изолировать тяжелые операции через --experimental-vm-modules в отдельных контекстах. Вывод: Фрагментация кучи в long-lived серверах — реальная проблема, решаемая через Buffer Pool с фиксированным сегментом и контроль аллокаций, а не через поиск утечек.
624
18
Получи грант до 3,48 млн на обучение дизайну Поступай на дизайн в Центральный университет с грантом. Для учеников 10–11-х кла
Получи грант до 3,48 млн на обучение дизайну Поступай на дизайн в Центральный университет с грантом. Для учеников 10–11-х классов и СПО. Освой графический, UI/UX и продуктовый дизайн. Создавай визуальные концепты будущего. На программе студенты получают фундаментальную базу, развивают прикладные навыки, приобретают опыт работы над реальными проектами, собирают портфолио и строят связи внутри дизайн-сообщества Подать заявку #реклама 16+ cu.ru О рекламодателе
491
19
⁣Скрытый убийца производительности: синхронный DNS в dns.lookup под нагрузкой Высоконагруженный HTTP-клиент на Node.js внезапно теряет пропускную способность? Event loop залипает при большом количестве параллельных запросов? Чаще всего проблема не в HTTP, а в том, как система разрешает доменные имена. В чем суть? dns.lookup (используется http.request, https, axios по умолчанию) при вызове без флагов обращается к системному getaddrinfo через libuv. Этот вызов синхронный и блокирует event loop на время резолвинга. При 1000+ RPS latency одного разрешения (например, 50 мс) превращается в 50 000 мс общего блокирования цикла. Как диагностировать? 1. Подключить dns.promises и выполнить dns.promises.lookup при нагрузке. Если event loop задерживает микротаски, виновник найден. 2. Использовать process.hrtime.bigint() до и после dns.lookup - разница > 10 мс системного времени указывает на проблему. 3. clinic doctor - на графике async latency видны ступеньки, совпадающие с пиками DNS-запросов. Как устранить? Для http(s) агентов - замена на асинхронный DNS: const { createConnection } = require('net'); const dns = require('dns/promises'); const agent = new http.Agent({ createConnection: async (options, cb) => { const { address } = await dns.lookup(options.hostname); const socket = createConnection({ ...options, host: address }); cb(null, socket); }, }); Типичная ошибка: использование только maxSockets или scheduling: 'lifo' снижает частоту новых соединений, но не решает первопричину при множестве уникальных хостов. Проще - библиотеки dns-cache или cacheable-lookup. Вывод: блокировка из-за dns.lookup - классическая проблема одного потока Node.js на стыке системных вызовов, решается заменой на асинхронное разрешение через dns.promises или кастомный агент.
671
20
⁣Диагностика и устранение гонок данных при конкурентном доступе к node:sqlite из worker_threads через in-memory WAL-режим В production сценариях с worker_threads и in-memory SQLite в WAL режиме разработчики часто забывают синхронизировать доступ. Итог — SQLITE_BUSY, рассинхрон данных и дубли в уникальных полях. Проблема: гонка без синхронизации Несколько воркеров читают и пишут в одну in-memory базу без внешней координации. WAL помогает с параллельным чтением, но не спасает от гонок записи. Типичные проявления: ошибки SQLITE_BUSY, частичные обновления и потеря данных. Решение: один писатель с явными блокировками Выделите один воркер для критических записей (например, инкременты). Координируйте через SharedArrayBuffer и Atomics — это дешевле мьютексов. Воркеры-читатели используют отдельные соединения в WAL. Production-oriented пример с BEGIN IMMEDIATE Начиная с Node.js 23 используйте DatabaseSync. Обязательно PRAGMA journal_mode=WAL; и PRAGMA synchronous=NORMAL;: import { DatabaseSync } from 'node:sqlite'; const db = new DatabaseSync(':memory:', { readwrite: true, create: true }); db.exec('PRAGMA journal_mode=WAL;'); db.exec('PRAGMA synchronous=NORMAL;'); function safeUpdate(sql) { db.exec('BEGIN IMMEDIATE;'); try { db.exec(sql); db.exec('COMMIT;'); } catch { db.exec('ROLLBACK;'); throw new Error('Write failed'); } } BEGIN IMMEDIATE блокирует запись сразу, избегая гонок. Без него два воркера могут начать транзакции одновременно — ловите SQLITE_BUSY. Предупреждение: in-memory WAL не для продакшена In-memory база теряет данные при краше. Для реальных проектов используйте файловую базу с WAL — это гарантирует персистентность. Вывод: гонки данных в SQLite лечатся одним писателем и явными блокировками через BEGIN IMMEDIATE, давая скорость WAL без потери консистентности.
675