2012-09-28 8 views
7

Chcę nawiązać połączenie z bazą danych, która ma dużo danych i może trochę potrwać.Play & Akka i wątki blokujące dostęp do bazy danych

Planuję wykonać tę pracę w ramach połączenia z Akka.future (f) i użyć Asynchronicznej {}, aby wyświetlić odpowiedź po zakończeniu pracy.

Czy ma to sens, czy powinienem po prostu wykonać długie wywołanie bazy danych w kontrolerze, bez wysyłania pracy do Akki?

Czy istnieje sposób na niezablokowanie dostępu do bazy danych?

Odpowiedz

1

Jeśli odpowiedź zostanie zablokowana po zakończeniu wywołania bazy danych, przydaje się tylko asynchroniczne, jeśli można wykonać inne prace związane z łączeniem odpowiedzi podczas wykonywania połączenia.

Nie blokujący dostępu do bazy danych może oznaczać kilka różnych rzeczy: bibliotekę klienta, która udostępnia interfejs API oparty na oddzwanianiu, który byłby podobny do przyszłego rozwiązania lub taki, który używa nieblokujących gniazd, aby zaoszczędzić na wykorzystaniu wątku. Zakładam, że masz na myśli to pierwsze, w którym to przypadku myślę, że byłoby funkcjonalnie równoważne użyciu przyszłości.

+0

Bloki wywołania DB i nie mam żadnych innych zadań do wykonania dla tego żądania przychodzącego. Ale sam serwer Play może obsłużyć inne żądanie przychodzące w międzyczasie. Ale jeśli wyślę pracę do Akka.future (praca), to obsłużę ją tymi samymi wątkami, które poradzą sobie z nowymi przychodzącymi prośbami, więc nie sądzę, żeby to miało jakiś wpływ, przekazując ją tak Akka. W rzeczywistości może nawet powodować dodatkowe obciążenie. Czy to ma sens? –

+1

Tak, myślę, że to ma sens. Zakładając blokowanie IO w wywołaniu bazy danych, będzie zajmować wątek, dopóki nie zostanie ukończony. Nie wiem, dobrze się gra, ale nie powinno to przeszkadzać rozsądnym stronom internetowym w obsłudze dodatkowych wniosków. Inne wątki można zaplanować na procesorze podczas oczekiwania na pakiety z serwera DB, tak jak w przypadku każdej innej aplikacji, a Play powinien mieć dostęp do puli wątków. Zaakceptuj odpowiedź, jeśli ma to sens. =) – spieden

2

Możesz użyć Akka.future(f) i dostarczyć swój własny plik konfiguracyjny Akka, aby uzyskać więcej wątków do przetwarzania dostępu do bazy danych. Na przykład spójrz na this config file.

Ale wskazałeś: prawdziwym problemem jest użycie sterownika bazy danych, który blokuje. Nie wiem, którego DB używasz, ale warto na przykład spojrzeć na MongoDB z ReactiveMongo. Dzięki ReactiveMongo wszystkie operacje MongoDB są doskonale nieblokujące i asynchroniczne. Istnieje dobre wprowadzenie here. Co więcej, bardzo dobrze radzi sobie z Play Framework (sprawdź ReactiveMongo Play Plugin).

EDYCJA: Można również sprawdzić "Configuring Playframework's internal Akka system", aby dostroić numer wątków roboczych.

+0

Utknąłem z MySQL ..., ale wygląda na to, że ma również asynchroniczny interfejs API! Czy istnieje dokumentacja dla tego pliku konfiguracyjnego? –

+0

Ponieważ ten plik konfiguracyjny jest rzeczywiście dla Akka, możesz przeczytać [dokument konfiguracyjny Akka] (http://doc.akka.io/docs/akka/2.0.3/general/configuration.html). –

+0

Zapomniałem wspomnieć o tym [doc] (http://www.playframework.org/documentation/2.0.3/AkkaCore) ([konfigurowanie wewnętrznego systemu Akka Playframework] (http://www.playframework.org/documentation/2.0.3/AkkaCore)). –

4

Jeśli jesteś zmuszony do użycia sterownika blokującego dla twojej bazy danych (jeśli z jakiegoś powodu nie działa asynchroniczny sterownik dla MySQL), zastanów się nad skonfigurowaniem puli Aktorów (za pomocą routingu) za pomocą PinnedDispatchera.

Program PinnedDispatcher udostępnia wątek dla każdego aktora i, konfigurując router, umożliwia dostosowanie liczby wątków ściśle odpowiedzialnych za obsługę wywołań bazy danych. Łatwe skalowanie. Ponadto, za pomocą Aktorów można nieco łatwiej układać komunikaty między aktorami (np. Wiadomościami mającymi wyniki wywołania bazy danych).