2016-01-28 18 views
12

Mamy aplikację mobilną, która przedstawia kanał dla użytkowników. Interfejs API REST kanału jest zaimplementowany na serwerze tomcat, który równolegle wykonuje wywołania do różnych źródeł danych, takich jak Couchbase, MYSQL w celu prezentacji treści. Prosty kod jest podany poniżej:Jak zoptymalizować Tomcat do pobierania paszy

Future<List<CardDTO>> pnrFuture = null; 
Future<List<CardDTO>> newsFuture = null; 

ExecutionContext ec = ExecutionContexts.fromExecutorService(executor); 

final List<CardDTO> combinedDTOs = new ArrayList<CardDTO>(); 

// Array list of futures 
List<Future<List<CardDTO>>> futures = new ArrayList<Future<List<CardDTO>>>(); 

futures.add(future(new PNRFuture(pnrService, userId), ec)); 
futures.add(future(new NewsFuture(newsService, userId), ec)); 
futures.add(future(new SettingsFuture(userPreferenceManager, userId), ec)); 

Future<Iterable<List<CardDTO>>> futuresSequence = sequence(futures, ec); 

// combine the cards 
Future<List<CardDTO>> futureSum = futuresSequence.map( 
     new Mapper<Iterable<List<CardDTO>>, List<CardDTO>>() { 
      @Override 
      public List<CardDTO> apply(Iterable<List<CardDTO>> allDTOs) { 
       for (List<CardDTO> cardDTOs : allDTOs) { 
        if (cardDTOs != null) { 
         combinedDTOs.addAll(cardDTOs); 
        } 
       } 

       Collections.sort(combinedDTOs); 
       return combinedDTOs; 
      } 
     } 
); 

Await.result(futureSum, Duration.Inf()); 
return combinedDTOs; 

Teraz mamy około 4-5 równoległych zadań na żądanie. Oczekuje się jednak, że w miarę dodawania nowych rodzajów produktów do paszy wzrośnie do prawie 20-25 równoległych zadań.

Moje pytanie brzmi: jak mogę ulepszyć ten projekt? Jakiego rodzaju dostrojenie jest wymagane w Tomcat, aby upewnić się, że takie 20-25 równoległych połączeń może być obsługiwane optymalnie przy dużym obciążeniu.

Rozumiem, że jest to szeroki temat, ale wszelkie sugestie byłyby bardzo pomocne.

+0

istnieje wymóg, aby przywrócić wszystkie dane w jednym wniosku? – AdamSkywalker

+0

Tak, zostanie przesłany kompletny plik danych. W przyszłości może być podzielona na strony ... –

+0

@ madhur-ahuja: Jest wiele rzeczy, które można ulepszyć, aby ulepszyć ten projekt - Wydaje mi się, że próbujesz zaimplementować coś w stylu [http: // /martinfowler.com/articles/microservices.html] (mikroserwisy) ​​do agregowania różnych źródeł danych w kanale. Problem jest ... kocur jest najmniejszym z twoich problemów. Ponieważ każda usługa zdalna może się nie udać, musisz skupić się na elastyczności systemu, aby faktycznie uzyskać taki wygląd. Wyłączniki i wyważarki są pierwszymi rzeczami, które przychodzą mi na myśl, ale są poza zakresem pytania :) –

Odpowiedz

4

Rozumiem, że dzwonisz do tego z aplikacji mobilnej i liczba plików może wzrosnąć.

w zależności od ilości zwracanych danych, czy możliwe jest zwrócenie wyników niektórych kanałów w tym samym wywołaniu? W ten sposób serwer wykonuje pracę. Masz kontrolę nad serwerem - nie kontrolujesz urządzenia użytkowników i ich prędkości połączenia.

Jak sugeruje nickebbit, rzeczy takie jak DefferedResult są naprawdę łatwe do wdrożenia. jest możliwe, że dane z tych kanałów nie zostałyby zaktualizowane w szybki sposób? Jeśli tak, powinieneś zbadać użycie EHCache i adnotacji @Cacheable.

Możesz wymyślić rozwiązanie, w którym użytkownik zawsze wyciąga buforowaną wersję swoich treści z serwera Tomcat. Ale twój serwer Tomcat stale aktualizuje pamięć podręczną w tle.

Jego dodatkową dzieło - ale na koniec dnia, gdy doświadczenie użytkownika nie jest szybkie - użytkownicy nie będą chcieli korzystać z tej aplikacji

7

Tomcat zarządza przychodzącymi połączeniami HTTP i przesuwa bajty w jedną i drugą stronę. Nie ma optymalizacji Tomcat, którą można zrobić, aby Twoja aplikacja działała lepiej.

Jeśli potrzebujesz 25 procesów równoległych do uruchomienia dla każdego przychodzącego żądania HTTP i uważasz, że to wariactwo, musisz ponownie przemyśleć działanie aplikacji.

Żadna konfiguracja tomcat nie pomoże w przedstawieniu pytania.

4

Wygląda na to, że używasz Akki, ale nie wchodzisz w skład modelu Aktora, spowoduje to prawdopodobnie zwiększenie równoległości i tym samym skalowalności aplikacji.

Gdyby to był ja, przekazywałbym wnioski z mojego interfejsu REST API do pojedynczej lub puli koordynujących aktorów, którzy będą przetwarzać żądanie asynchronicznie. Używając Spring RestController można to zrobić za pomocą Callable lub DeferredResult, ale oczywiście będzie to odpowiednik w jakiejkolwiek strukturze, z której korzystasz.

Ten podmiot koordynujący przekazał następnie przetwarzanie innym podmiotom (tj. Pracownikom), które zajmują się zadaniami związanymi z operacjami we/wy (najlepiej przy użyciu własnego programu rozsyłającego w celu uniemożliwienia blokowania innych wątków związanych z procesorem) i odpowiadania do koordynatora z ich wynikami.

Gdy wszyscy pracownicy pobrali swoje dane i odpowiedzieli koordynatorowi z wynikami, wówczas oryginalne żądanie może zostać wypełnione pełnym zestawem wyników.