Hitilafu ya Node.js ambayo haionekani kwenye ufuatiliaji wako

Ukaguzi wako wa afya (health check) unasema kila kitu kiko sawa. Unachukua milisekunde moja. Kisha trafiki inaongezeka. Ghafla, latency yako ya p99 inaruka hadi 400ms. Unatazama dashibodi zako. Kila kitu kinaonekana kuwa cha kijani.

Matumizi ya CPU ni ya wastani. Event loop lag imetulia. Kumbukumbu (Memory) iko sawa. APM yako inaonyesha request inayochelewa lakini haikupi taarifa yoyote kuhusu sababu. Hakuna wito wa hifadhidata (database calls) unaochelewa. Hakuna makosa (errors).

Muda unatumika kwenye libuv thread pool.

Ufuatiliaji wa kawaida wa Node unajikita kwenye event loop. Pool ni foleni tofauti. Iko nje ya uwezo wako wa kuiona.

Node huendesha JavaScript kwenye event loop. Inasukuma kazi nzito kwenye libuv thread pool. Hii ni pamoja na:

  • Kazi za mfumo wa faili (fs.readFile, fs.writeFile).
  • Kazi za crypto (bcrypt, scrypt, pbkdf2).
  • Ukandamizaji (zlib gzip, deflate).
  • Utafutaji wa DNS (dns.lookup).

Pool kwa kawaida ina threads nne tu. Hii ni kweli bila kujali ni kiini (cores) vingapi vya CPU mashine yako ilivyo na vyo.

Threads nne hazitoshi. Hizi hapa ni njia tatu ambazo pool inaharibika:

  1. Bcrypt wakati wa kuingia (login). Hash moja ya bcrypt inaweza kuchukua 250ms. Ikiwa watu wanne wanaingia kwa wakati mmoja, nafasi zote zimejaa. Mtu wa tano anasubiri kwenye foleni. Anatumia 250ms kuanza tu. Latency yako inazidika mara mbili.

  2. Operesheni kubwa za gzip. Kukandamiza jibu (response) kubwa kunachukua nafasi kwenye pool. Ikiwa requests nne zanafanya hivi kwa wakati mmoja, kila kazi nyingine inasubiri. Utafutaji wa DNS na kusoma faili vinakwama kwenye foleni.

  3. Utafutaji wa DNS. Programu nyingi za Node hutumia dns.lookup. Hii hutumia wito wa mfumo unaozuia (blocking system call). Inaiweka kazi kwenye pool. Ikiwa mtandao wako una hitilafu ndogo, utafutaji huu unazuia pool nzima.

Request iliyonaswa kwenye foleni ya pool haiionekani. Halitumii CPU. Halitekelezi JavaScript. Limepakiwa tu.

Jinsi ya kuipata:

Ikiwa latency yako ya p99 inaongezeka chini ya mzigo lakini event loop lag inabaki vilevile, kagua pool.

Jaribio la haraka zaidi: Ongeza UV_THREADPOOL_SIZE. Iweke kuwa 64 kwenye mazingira yako (environment) na uwashe upya. Ikiwa latency inashuka, umepata tatizo.

Jinsi ya kulirekebisha ipasavyo:

  • Tumia worker_threads kwa crypto nzito kama bcrypt. Hii huweka kazi hizo mbali na libuv pool.
  • Tumia dns.resolve badala ya dns.lookup. Ni mtafuta (resolver) halisi wa async.
  • Tumia streams kwa kazi za zlib ili kuachia nafasi (slots) haraka zaidi.
  • Epuka kazi nzito za mfumo wa faili kwenye njia zako kuu za maombi (request paths).

Acha kutazama dashibodi za kijani wakati watumiaji wako wanasubiri.

Chanzo: https://dev.to/r9v/the-nodejs-bug-thats-invisible-to-your-monitoring-oo8