Node.js ਦੀ ਉਹ ਬੱਗ ਜੋ ਤੁਹਾਡੀ ਮਾਨੀਟਰਿੰਗ ਤੋਂ ਲੁਕੀ ਹੋਈ ਹੈ
ਤੁਹਾਡਾ ਹੈਲਥ ਚੈੱਕ ਕਹਿੰਦਾ ਹੈ ਕਿ ਸਭ ਕੁਝ ਠੀਕ ਹੈ। ਇਸ ਵਿੱਚ ਸਿਰਫ਼ ਇੱਕ ਮਿਲੀਸਕਿੰਡ ਲੱਗਦੀ ਹੈ। ਫਿਰ ਟ੍ਰੈਫਿਕ ਵਧਦਾ ਹੈ। ਅਚਾਨਕ, ਤੁਹਾਡੀ p99 latency 400ms ਤੱਕ ਵੱਧ ਜਾਂਦੀ ਹੈ। ਤੁਸੀਂ ਆਪਣੇ ਡੈਸ਼ਬੋਰਡ ਦੇਖਦੇ ਹੋ। ਸਭ ਕੁਝ ਹਰਾ ਦਿਖਾਈ ਦਿੰਦਾ ਹੈ।
CPU ਦੀ ਵਰਤੋਂ ਦਰਮਿਆਨੀ ਹੈ। Event loop lag ਸਥਿਰ ਹੈ। ਮੈਮੋਰੀ ਸਹੀ ਹੈ। ਤੁਹਾਡਾ APM ਇੱਕ ਹੌਲੀ ਰਿਕਵੈਸਟ ਦਿਖਾਉਂਦਾ ਹੈ ਪਰ ਇਹ ਨਹੀਂ ਦੱਸਦਾ ਕਿ ਕਿਉਂ। ਕੋਈ ਵੀ ਡਾਟਾਬੇਸ ਕਾਲ ਹੌਲੀ ਨਹੀਂ ਹੈ। ਕੋਈ ਗਲਤੀਆਂ ਨਹੀਂ ਹਨ।
ਸਮਾਂ libuv thread pool ਵਿੱਚ ਖ਼ਰਚ ਹੋ ਰਿਹਾ ਹੈ।
ਸਟੈਂਡਰਡ Node observability event loop 'ਤੇ ਕੇਂਦਰਿਤ ਹੁੰਦੀ ਹੈ। Pool ਇੱਕ ਵੱਖਰੀ ਕਿਊ ਹੈ। ਇਹ ਤੁਹਾਡੀ ਪਹੁੰਚ ਤੋਂ ਬਾਹਰ ਹੈ।
Node event loop 'ਤੇ JavaScript ਚਲਾਉਂਦਾ ਹੈ। ਇਹ ਭਾਰੀ ਕੰਮਾਂ ਨੂੰ libuv thread pool ਵਿੱਚ ਭੇਜ ਦਿੰਦਾ ਹੈ। ਇਸ ਵਿੱਚ ਸ਼ਾਮਲ ਹਨ:
- Filesystem ਦਾ ਕੰਮ (fs.readFile, fs.writeFile)।
- Crypto ਕੰਮ (bcrypt, scrypt, pbkdf2)।
- Compression (zlib gzip, deflate)।
- DNS lookups (dns.lookup)।
Pool ਡਿਫੌਲਟ ਰੂਪ ਵਿੱਚ ਸਿਰਫ਼ ਚਾਰ threads ਰੱਖਦਾ ਹੈ। ਇਹ ਗੱਲ ਤੁਹਾਡੀ ਮਸ਼ੀਨ ਵਿੱਚ ਕਿੰਨੇ ਵੀ CPU cores ਹੋਣ ਦੇ ਬਾਵਜੂਦ ਸੱਚ ਹੈ।
ਚਾਰ threads ਕਾਫ਼ੀ ਨਹੀਂ ਹਨ। ਇੱਥੇ ਤਿੰਨ ਤਰੀਕੇ ਹਨ ਜਿਨ੍ਹਾਂ ਨਾਲ pool ਫੇਲ ਹੋ ਸਕਦਾ ਹੈ:
Bcrypt at login। ਇੱਕ ਸਿੰਗਲ bcrypt hash ਵਿੱਚ 250ms ਲੱਗ ਸਕਦੇ ਹਨ। ਜੇਕਰ ਇੱਕੋ ਸਮੇਂ ਚਾਰ ਲੋਕ ਲੌਗਇਨ ਕਰਦੇ ਹਨ, ਤਾਂ ਸਾਰੇ ਸਲਾਟ ਭਰ ਜਾਂਦੇ ਹਨ। ਪੰਜਵਾਂ ਵਿਅਕਤੀ ਕਿਊ ਵਿੱਚ ਇੰਤਜ਼ਾਰ ਕਰਦਾ ਹੈ। ਉਸਨੂੰ ਸ਼ੁਰੂ ਕਰਨ ਲਈ ਹੀ 250ms ਦਾ ਇੰਤਜ਼ਾਰ ਕਰਨਾ ਪੈਂਦਾ ਹੈ। ਤੁਹਾਡੀ latency ਦੁੱਗਣੀ ਹੋ ਜਾਂਦੀ ਹੈ।
Large gzip operations। ਇੱਕ ਵੱਡੇ ਰਿਸਪਾਂਸ ਨੂੰ ਕੰਪਰੈੱਸ ਕਰਨ ਨਾਲ pool ਦਾ ਇੱਕ ਸਲਾਟ ਰੁਕ ਜਾਂਦਾ ਹੈ। ਜੇਕਰ ਚਾਰ ਰਿਕਵੈਸਟਾਂ ਇੱਕੋ ਸਮੇਂ ਅਜਿਹਾ ਕਰਦੀਆਂ ਹਨ, ਤਾਂ ਬਾਕੀ ਹਰ ਕੰਮ ਇੰਤਜ਼ਾਰ ਕਰਦਾ ਹੈ। DNS lookups ਅਤੇ file reads ਲਾਈਨ ਵਿੱਚ ਫਸ ਜਾਂਦੇ ਹਨ।
DNS lookups। ਜ਼ਿਆਦਾਤਰ Node ਐਪਸ dns.lookup ਦੀ ਵਰਤੋਂ ਕਰਦੀਆਂ ਹਨ। ਇਹ ਇੱਕ blocking system call ਦੀ ਵਰਤੋਂ ਕਰਦਾ ਹੈ। ਇਹ ਕੰਮ ਨੂੰ pool 'ਤੇ ਪਾ ਦਿੰਦਾ ਹੈ। ਜੇਕਰ ਤੁਹਾਡੇ ਨੈੱਟਵਰਕ ਵਿੱਚ ਕੋਈ ਸਮੱਸਿਆ ਆਉਂਦੀ ਹੈ, ਤਾਂ ਇਹ lookups ਪੂਰੇ pool ਨੂੰ ਰੋਕ ਦਿੰਦੇ ਹਨ।
Pool queue ਵਿੱਚ ਫਸੀ ਹੋਈ ਰਿਕਵੈਸਟ ਅਦਿੱਖ ਹੁੰਦੀ ਹੈ। ਇਹ CPU ਦੀ ਵਰਤੋਂ ਨਹੀਂ ਕਰ ਰਹੀ। ਇਹ JavaScript ਨਹੀਂ ਚਲਾ ਰਹੀ। ਇਹ ਸਿਰਫ਼ ਉੱਥੇ ਰੁਕੀ ਹੋਈ ਹੈ।
How to find it:
ਜੇਕਰ ਲੋਡ ਦੇ ਅਧੀਨ ਤੁਹਾਡੀ p99 latency ਵਧਦੀ ਹੈ ਪਰ event loop lag ਸਥਿਰ ਰਹਿੰਦਾ ਹੈ, ਤਾਂ pool ਦੀ ਜਾਂਚ ਕਰੋ।
ਸਭ ਤੋਂ ਤੇਜ਼ ਟੈਸਟ: UV_THREADPOOL_SIZE ਵਧਾਓ। ਆਪਣੇ environment ਵਿੱਚ ਇਸਨੂੰ 64 'ਤੇ ਸੈੱਟ ਕਰੋ ਅਤੇ ਰੀਸਟਾਰਟ ਕਰੋ। ਜੇਕਰ latency ਘਟਦੀ ਹੈ, ਤਾਂ ਤੁਹਾਨੂੰ ਸਮੱਸਿਆ ਮਿਲ ਗਈ ਹੈ।
How to fix it properly:
- bcrypt ਵਰਗੇ ਭਾਰੀ crypto ਲਈ worker_threads ਦੀ ਵਰਤੋਂ ਕਰੋ। ਇਹ ਉਹਨਾਂ ਨੂੰ libuv pool ਤੋਂ ਦੂਰ ਰੱਖਦਾ ਹੈ।
- dns.lookup ਦੀ ਬਜਾਏ dns.resolve ਦੀ ਵਰਤੋਂ ਕਰੋ। ਇਹ ਇੱਕ ਅਸਲੀ async resolver ਹੈ।
- ਸਲਾਟਾਂ ਨੂੰ ਤੇਜ਼ੀ ਨਾਲ ਖਾਲੀ ਕਰਨ ਲਈ zlib ਕੰਮ ਲਈ streams ਦੀ ਵਰਤੋਂ ਕਰੋ।
- ਆਪਣੇ ਮੁੱਖ request paths 'ਤੇ ਭਾਰੀ filesystem ਕੰਮ ਤੋਂ ਬਚੋ।
ਜਦੋਂ ਤੁਹਾਡੇ ਯੂਜ਼ਰ ਇੰਤਜ਼ਾਰ ਕਰ ਰਹੇ ਹੋਣ ਤਾਂ ਹਰੇ ਡੈਸ਼ਬੋਰਡਾਂ ਨੂੰ ਦੇਖਦੇ ਰਹਿਣਾ ਬੰਦ ਕਰੋ।
Source: https://dev.to/r9v/the-nodejs-bug-thats-invisible-to-your-monitoring-oo8
