"Don`t block the event loop..." - πιθανότατα έχετε ακούσει αυτή τη φράση πολλές φορές... Δεν εκπλήσσομαι γιατί είναι μια από τις πιο σημαντικές παραδοχές όταν εργάζεστε με το Node. Υπάρχει όμως και ένα δεύτερο "πράγμα" το οποίο θα πρέπει να αποφεύγετε να μπλοκάρετε - το Worker Pool. Αν το αμελήσετε, μπορεί να έχει σημαντικό αντίκτυπο στην απόδοση της εφαρμογής, ακόμα και στην ασφάλειά της.
Νήματα
Το κύριο πράγμα που πρέπει να θυμάστε: υπάρχουν δύο τύποι νημάτων στο Node.js: Κύριο νήμα - το οποίο χειρίζεται το Βρόχος συμβάντων, και Δεξαμενή εργαζομένων (thread pool) - που είναι η δεξαμενή νημάτων -
χάρη στο libuv. Κάθε ένας από αυτούς έχει διαφορετική δουλειά. Ο στόχος του πρώτου είναι να χειρίζεται μη μπλοκαρισμένες λειτουργίες εισόδου/εξόδου, ενώ ο δεύτερος είναι υπεύθυνος για εργασίες εντατικής CPU και επίσης για μπλοκαρισμένες λειτουργίες εισόδου/εξόδου.

Αλλά τι είναι ένα νήμα και πώς διαφέρει από μια διαδικασία; Υπάρχουν αρκετές διαφορές, αλλά η πιο σημαντική για εμάς είναι ο τρόπος με τον οποίο τους κατανέμεται η μνήμη. Μπορείτε να σκεφτείτε για μια διεργασία όπως για μια εφαρμογή. Μέσα σε κάθε διεργασία, υπάρχει ένα κομμάτι μνήμης που προορίζεται μόνο για αυτή τη διεργασία. Έτσι, μια διεργασία δεν έχει πρόσβαση στη μνήμη της δεύτερης και αυτή η ιδιότητα εξασφαλίζει υψηλή ασφάλεια. Για να δημιουργήσουμε επικοινωνία μεταξύ τους, πρέπει να κάνουμε κάποια εργασία. Τα νήματα είναι διαφορετικά. Τα νήματα εκτελούνται μέσα σε μια διεργασία και μοιράζονται την ίδια μνήμη, οπότε δεν υπάρχει κανένα απολύτως πρόβλημα με το να μοιράζονται τα νήματα δεδομένα.
Ωστόσο, ένα ζήτημα προκαλεί πρόβλημα. Ονομάζεται κατάσταση αγώνα. Τα νήματα μπορούν να εκτελούνται ταυτόχρονα, οπότε πώς θα ξέρουμε ποιο θα τελειώσει πρώτο; Μπορεί να συμβεί ότι την πρώτη φορά που θα το τρέξετε, η πρώτη λειτουργία τελειώνει πρώτη, ενώ την επόμενη φορά μπορεί να αποδειχθεί το αντίθετο και η δεύτερη λειτουργία να τελειώσει πριν από την πρώτη. Φανταστείτε να εργάζεστε με λειτουργίες εγγραφής/ανάγνωσης υπό τέτοιες συνθήκες! Ένας εφιάλτης! Είναι μερικές φορές πολύ δύσκολο να γράψετε σωστές κωδικός σε περιβάλλον πολλαπλών νημάτων.
Επίσης, οι γλώσσες με πολλαπλά νήματα έχουν μεγάλη επιβάρυνση μνήμης επειδή δημιουργούν ένα ξεχωριστό νήμα για κάθε αίτηση- έτσι, αν θέλετε να καλέσετε 1000 αιτήσεις, δημιουργούν 1000 νήματα.
Πώς να αντιμετωπίσετε ένα τέτοιο πρόβλημα; Χρησιμοποιήστε ένα μόνο νήμα! Και αυτό είναι που Κόμβος σας προσφέρει.

Ως JavaScript προγραμματιστής Σας ενθαρρύνω να παρακολουθήσετε το ταινία
στο οποίο ο Bart Belder εξηγεί με σαφήνεια την έννοια του βρόχου γεγονότων. Το παραπάνω διάγραμμα προέρχεται από την παρουσίασή του. Και αν δεν γνωρίζετε καθόλου αυτούς τους όρους, και οι δύο Κόμβος και το Libuv έχουν εξαιρετική τεκμηρίωση 🙂
Σχετικά με το μπλοκάρισμα
Στο Ανάπτυξη JavaScript βιομηχανία λένε ότι επειδή Κόμβος είναι single-threaded και non-blocking, μπορείτε να επιτύχετε μεγαλύτερη ταυτόχρονη χρήση με τους ίδιους πόρους από ό,τι με λύσεις multi-threaded. Είναι αλήθεια, αλλά δεν είναι τόσο όμορφο και εύκολο όσο φαίνεται.
Από το Node.js είναι single-threaded (τμήμα JS), οι εργασίες με μεγάλη ένταση CPU θα μπλοκάρουν όλες τις αιτήσεις που βρίσκονται σε εξέλιξη μέχρι να ολοκληρωθεί η συγκεκριμένη εργασία. Έτσι, είναι αλήθεια ότι σε Node.js μπορείτε να μπλοκάρετε κάθε αίτηση μόνο και μόνο επειδή μία από αυτές είχε μια εντολή μπλοκαρίσματος μέσα. Ο κώδικας μπλοκαρίσματος σημαίνει ότι χρειάζεται περισσότερο από μερικά χιλιοστά του δευτερολέπτου για να ολοκληρωθεί. Αλλά μην συγχέετε τον μεγάλο χρόνο απόκρισης με το μπλοκάρισμα. Η απόκριση από τη βάση δεδομένων μπορεί να πάρει πολύ μεγάλο χρονικό διάστημα, αλλά δεν μπλοκάρει τη διεργασία σας (εφαρμογή).
Οι μέθοδοι μπλοκαρίσματος εκτελούνται συγχρονισμένα και οι μέθοδοι μη μπλοκαρίσματος εκτελούνται ασύγχρονα.
Πώς μπορείτε να επιβραδύνετε (ή να μπλοκάρετε) το βρόχο συμβάντων;
- ευάλωτη regex - μια ευάλωτη κανονική έκφραση είναι αυτή στην οποία η μηχανή κανονικών εκφράσεων μπορεί να πάρει εκθετικό χρόνο- μπορείτε να διαβάσετε περισσότερα γι' αυτές. εδώ,
- Λειτουργίες JSON σε μεγάλα αντικείμενα,
- χρησιμοποιώντας σύγχρονα APIs από Κόμβος όλες οι μέθοδοι εισόδου/εξόδου της τυπικής βιβλιοθήκης Node.js παρέχουν επίσης τις ασύγχρονες εκδόσεις τους,
- άλλα σφάλματα προγραμματισμού, όπως σύγχρονοι άπειροι βρόχοι.
Σε αυτή την περίπτωση, εφόσον η δεξαμενή εργασίας χρησιμοποιεί μια δεξαμενή νημάτων, είναι δυνατόν να μπλοκαριστούν και αυτά; Δυστυχώς, ναι 🙁 Κόμβος βασίζεται σε μια φιλοσοφία ένα νήμα για πολλούς πελάτες.
Ας υποθέσουμε ότι μια συγκεκριμένη εργασία που εκτελείται από έναν συγκεκριμένο Εργαζόμενο είναι πολύ περίπλοκη και χρειάζεται περισσότερο χρόνο για να ολοκληρωθεί. Ως αποτέλεσμα, ο Worker μπλοκάρεται και δεν μπορεί να χρησιμοποιηθεί για την εκτέλεση οποιασδήποτε άλλης εκκρεμούς εργασίας μέχρι να εκτελεστούν οι οδηγίες του. Όπως πιθανότατα έχετε ήδη μαντέψει, αυτό μπορεί να επηρεάσει την απόδοση. Μπορείτε να αποτρέψετε τέτοια ζητήματα ελαχιστοποιώντας τη διακύμανση των χρόνων των Εργασιών με τη χρήση της κατάτμησης Εργασιών.
Συμπέρασμα
Αποφύγετε το μπλοκάρισμα, αυτό είναι σίγουρο. Αν μπορείτε, επιλέγετε πάντα ασύγχρονες εκδόσεις των APIs της τυπικής βιβλιοθήκης. Διαφορετικά, μετά την εκτέλεση της εφαρμογής σας, ο πελάτης μπορεί να αντιμετωπίσει διάφορα προβλήματα, ξεκινώντας από την υποβαθμισμένη απόδοση και καταλήγοντας στην πλήρη απόσυρση, η οποία είναι μοιραία από τη σκοπιά του χρήστη.
Διαβάστε περισσότερα:
Γιατί θα πρέπει (πιθανώς) να χρησιμοποιήσετε την Typescript
Πώς να μην σκοτώσετε ένα έργο με κακές πρακτικές κωδικοποίησης;
Στρατηγικές άντλησης δεδομένων στο NextJS