2012-07-12 3 views
15

Jestem trochę zdezorientowany, w jaki sposób Go obsługuje równoczesne żądania w Google App Engine. Mam więc nadzieję, że ktoś może zapewnić jakąś jasność.W jaki sposób Go obsługuje równoczesne żądanie w Google App Engine

Oto fakty, które mam zgromadzone:

  1. Go jest pojedynczy gwintowany na App Engine. - this is because it is possible to do arbitrary pointer arithmetic by creating race conditions with multiple threads

  2. Goroutines are multiplexed onto multiple OS threads so if one should block, such as while waiting for I/O, others continue to run.

  3. [App Engine has a] 10 concurrent limit [which] is enforced through a limit on concurrent threads on every runtime. Most of such cases, our scheduler will try to spin up a new instance.

Jeśli Go jest pojedynczy gwintowany na App Engine następnie wskaż 3 jest dyskusyjna. Pozostawia to 1 i 2. Jeśli funkcja Go on App Engine ma jeden wątek, a wątki są wymagane do kontynuowania wykonywania podczas blokowania dla operacji we/wy, wydaje się, że instancja App Engine Go zablokuje wszystkie goryle podczas oczekiwania na I/O.

Czy to prawda? Jeśli nie, w jaki sposób współbieżność Go działa na App Engine?

Aby pomóc w kwantyfikacji rzeczy. Gdybym miał utrzymywać połączenie otwarte przez 30 sekund. W jaki sposób współbieżne połączenia mogą utrzymywać pojedynczą instancję AE Go?

Dziękuję.

EDIT: oto wniosek funkcja, która pozwoli Go Instancji obsługiwać więcej niż 10 jednoczesnego żądania Allow configurable limit of concurrent requests per instance. Proszę gwiazdować.

+7

Ustawienie GOMAXPROCS = 1 (czyli to, co robi GAE) oznacza, że ​​zawsze będzie dokładnie jeden aktywny wątek, który wykonuje goroutines. Możesz nadal mieć kilka zablokowanych wątków (nie liczą). Zauważ też, że biblioteka Go używa epola w tle, więc jest mało prawdopodobne, że I/O zablokuje cały wątek (ale istnieje kilka innych sposobów blokowania wątku w Go). Nie wiem nic o ogólnym 10-nitkowym ograniczeniu GAE. – tux21b

+1

Limit współbieżnych żądań jest teraz konfigurowalny (maksymalnie do 80), zobacz http://stackoverflow.com/a/37364981/943833 – Roganartu

Odpowiedz

21

Instancja aplikacji Go App pozwala na 10 jednoczesnych żądań, ale działa tylko jeden wątek procesora. W efekcie wiele żądań może być przetwarzanych jednocześnie, ale tylko jedna będzie w stanie wykonywać pracę CPU na raz. Jeśli jednym z żądań jest, powiedzmy, oczekiwanie na wywołanie API datastore do zwrócenia, inne żądanie może być przetworzone przez to samo wystąpienie.

Twoje zdanie "Jeśli Go jest pojedynczo gwintowany w App Engine, punkt 3 jest moot". jest nieprawidłowe. Nadal istnieje limit 10 jednoczesnych żądań w locie do pojedynczej instancji Go App Engine. Dokumentacja jest nieco luźna w słowach, gdy mówi o "wątkach".

+3

** Ta odpowiedź wymaga znacznie większej propagacji. ** Zrozumiałem, że środowisko wykonawcze Go kolejkuje żądania, tak aby przychodzące żądanie musiało czekać, aż bieżące żądanie zostanie w pełni przetworzone. Było oczywiste, że jedna prośba może odegrać wiele rutynowych procedur i działać jednocześnie, ale nie ma tak wielu rutynowych procedur. – mjibson

+0

Dokumenty mówią: "wiele żądań może być obsługiwanych jednocześnie przez daną instancję", ale nigdy nie przeszedłem tak daleko w akapicie, dopóki nie przeczytałem go ponownie, po zatrzymaniu się na ograniczeniu jednowątkowym. – mjibson

+0

Dzięki David. Nadal nie mam pewności co do dławienia wniosku. Podjęłam [odpowiedź Takashiego tutaj] (http://stackoverflow.com/a/11443482/236564), że wszystkie instancje są ograniczone przez 10 współbieżnych wątków zamiast żądań. Wygląda na to, że mogło się to ostatnio zmienić. Czy to nie prawda dla Go? Jeśli rzeczywiście są to wątki, jaki byłby praktyczny limit liczby równoczesnych żądań, które mogłaby obsłużyć instancja F1 Go? –

4

Muszę przyznać, że nie mam wewnętrznej wiedzy o AppEngine. To wszystko spekulacje i zgadywanie, ale myślę, że jest to trochę rozsądne.

Twoja aplikacja nigdy nie osiągnie limitu dziesięciu wątków. Dzieje się tak dlatego, że istnieje bardzo niewiele przyczyn tworzenia wątków. Po pierwsze, maksymalna liczba działających goroutinów jest ustawiona na jeden na enforce memory safety. Po drugie, w przeciwieństwie do zwykłego programu do uruchamiania, silnik aplikacji nie musi w rzeczywistości tworzyć układów. Jedyny czas, jaki robi to na networking. Wszystkie IO w appengine mogą zostać zmultipleksowane w jeden wątek epoll. Oznacza to, że potrzebujesz tylko dwóch wątków w danym momencie. Następnie możesz dodać wątek trzeci lub czwarty w przypadku, gdy co jakiś czas musisz uruchomić inne systemy, takie jak przydzielanie pamięci i akceptowanie/zamykanie połączeń. Są to szybkie układy, które blokują przez bardzo krótki czas. Nawet z tymi innymi systemami nadal jesteś bardzo daleko od limitu dziesięciu wątków.

Nie ma to wpływu na współbieżność, ponieważ wszystko, co robisz w grze, sprowadza się do czekania, aż coś powróci do sieci. Nie potrzebujesz wielu wątków, aby robić wiele rzeczy naraz.

+0

Dziękuję Stephen, który był bardzo pomocny. –

+0

@KyleFinley, jeśli nie jesteś zbyt zaznajomiony z tym "materiałem epollowym", bardzo radzę przynajmniej przeglądać klasyczne prace ["The C10K problem"] (http://www.kegel.com/c10k.html) . – kostix

+0

@kostix Ciekawy artykuł. Dziękuję Ci. –