Aby wyjaśnić — Node.js nie jednowątkowy. Twój kod aplikacji jest wykonywany w jednym wątku, ale pod maską używa ich w razie potrzeby - spójrz tutaj (zarówno odpowiedź, jak i komentarze pod nią):
Oraz:
Jak widać mysql
używany moduł wymaga przekazania wywołania zwrotnego dla query()
metody (i prawdopodobnie wielu innych). Więc kiedy to wywołasz, wykonanie twojego kodu będzie kontynuowane, a wywołanie zwrotne zostanie wywołane, gdy nadejdą wyniki z bazy danych.
Co do twojego pytania - nie tworzysz nowego połączenia dla każdego żądania. Zajrzyj do readme plik mysql
moduł Połączenia w puli sekcja
:
Kiedy wywołujesz dbPool.getConnection()
połączenie jest tworzone tylko wtedy, gdy w puli nie ma już dostępnych połączeń - w przeciwnym razie po prostu pobiera jedno z góry. Wywołanie objConn.release()
zwalnia połączenie z powrotem do puli — nie jest rozłączane. To wywołanie umożliwia ponowne wykorzystanie go przez inne części Twojej aplikacji.
Podsumowując:
- Tworzenie nowego połączenia dla każdego żądania nie jest dobrym pomysłem ponieważ będzie zużywać więcej zasobów (procesora, pamięci RAM) zarówno na maszynach aplikacji, jak i bazy danych.
- Używanie jednego połączenia dla wszystkich żądań jest również niewłaściwe, ponieważ jeśli którakolwiek z operacji zajmie dużo czasu, połączenie zostanie zawieszone, co spowoduje, że wszystkie inne żądania będą na to czekać.
- Korzystanie z puli połączeń to świetny pomysł, który pozwala wykonywać wiele operacji na Twojej bazie danych w tym samym czasie, nawet jeśli wykonanie jednej z nich zajmuje dużo czasu.
Aktualizacja: Aby odpowiedzieć na pytania z komentarzy:
Kiedy używasz jednego połączenia dla każdego żądania, mysql
moduł musi otworzyć nowe gniazdo, połączyć się z bazą danych i uwierzytelnić się przed wykonaniem zapytania - to zajmuje trochę czasu i pochłania trochę zasobów. Z tego powodu jest to złe podejście.
Z drugiej strony, gdy używasz tylko jednego połączenia (nie puli połączeń), uruchomienie zapytania, którego wykonanie zajmuje dużo czasu, spowoduje zablokowanie wszystkich innych zapytań na tym połączeniu do czasu jego zakończenia - co oznacza, że każde inne żądanie będzie musiało poczekać. To także złe podejście.
Tworzenie nowej puli połączeń dla każdego żądania przypomina używanie nowego połączenia, chyba że wywołasz pool.getConnection()
wielokrotnie - wtedy jest jeszcze gorzej (weź zasoby wykorzystane przy tworzeniu nowego połączenia i pomnóż je przez liczbę pool.getConnection()
połączeń).
Aby dokładniej wyjaśnić jedno połączenie dla każdej operacji a wszystkie operacje w jednym połączeniu pytanie:
Każda operacja w każdym połączeniu jest uruchamiana po zakończeniu poprzedniej (jest synchroniczna, ale nie po stronie klienta), więc jeśli masz tabelę z kilkoma miliardami wierszy i wydajesz polecenie SELECT * FROM yourtable
ukończenie tego zajmie trochę czasu, blokując każdą operację na tym połączeniu, dopóki się nie zakończy.
Jeśli masz jedno połączenie dla każdej operacji, która musi być wydana równolegle (np. dla każdego żądania) problem znika. Ale jak wspomniano wcześniej, otwarcie nowego połączenia wymaga czasu i zasobów, dlatego pula połączeń koncepcja została wprowadzona.
Odpowiedź brzmi:użyj jednej puli połączeń dla wszystkich żądań (tak jak w przykładowym kodzie) – liczba połączeń będzie skalowana zgodnie z ruchem w Twojej aplikacji.
Aktualizacja nr 2:
Na podstawie komentarzy widzę, że powinienem również wyjaśnić koncepcję puli połączeń. Działa to tak, że uruchamiasz aplikację z pustą pulą połączeń i inicjalizacją, aby utworzyć maksymalnie n połączenia (afaik to 10 dla mysql
domyślnie).
Za każdym razem, gdy wywołasz dbPool.getConnection()
sprawdza, czy w puli są dostępne połączenia. Jeśli są, chwyta jeden (uniedostępnia), jeśli nie, tworzy nowy. Jeśli osiągnięto limit połączeń i nie ma dostępnych połączeń, zgłaszany jest jakiś wyjątek.
Wywołanie connection.release()
zwalnia połączenie z powrotem do puli, dzięki czemu jest ponownie dostępne.
Używanie puli w celu uzyskania tylko jednego globalnego połączenia dla całej aplikacji jest całkowicie błędne i sprzeczne z samą koncepcją (możesz zrobić to samo, po prostu tworząc połączenie ręcznie), więc użyj puli połączeń Mam na myśli użyj puli połączeń tak, jak miała być używana - aby uzyskać z niej połączenia, kiedy ich potrzebujesz .