2016-01-28 6 views
12

Wir haben eine mobile App, die Feeds für Benutzer darstellt. Die feed-REST-API ist auf tomcat implementiert, die Aufrufe an verschiedene Datenquellen wie Couchbase, MYSQL zur Darstellung des Inhalts durchführt. Der einfache Code ist unten angegeben:So optimieren Sie Tomcat für Feed ziehen

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; 

Im Moment haben wir etwa 4-5 parallele Aufgaben pro Anfrage. Es wird jedoch erwartet, dass es zu fast 20-25 parallelen Aufgaben wachsen wird, wenn wir neue Arten von Futtermitteln einführen.

Meine Frage ist, wie kann ich dieses Design verbessern? Welche Art von Abstimmung ist in Tomcat erforderlich, um sicherzustellen, dass solche 20-25 parallelen Anrufe unter hoher Last optimal bedient werden können.

Ich verstehe, dass dies ein breites Thema ist, aber alle Vorschläge wären sehr hilfreich.

+0

ist es erforderlich, alle Daten in einer einzigen Anfrage zurück? – AdamSkywalker

+0

Ja, der komplette Feed wird zurückgegeben. In Zukunft kann es paginiert werden ... –

+0

@ madhur-ahuja: Es gibt viele Dinge, die verbessert werden können, um ein Design wie dieses besser zu machen - Es scheint mir, dass Sie versuchen, etwas wie [http://martinfowler.com/articles/microservices.html] (Microservices), um verschiedene Datenquellen zu einem Feed zu aggregieren. Problem ist ... Tomcat ist das kleinste Ihrer Probleme. Da jeder Remote-Dienst fehlschlagen kann, müssen Sie sich auf die Ausfallsicherheit des Systems konzentrieren, um ein Design wie dieses tatsächlich auszuführen. Leistungsschalter und Balancer sind das erste, was mir in den Sinn kommt, aber sie sind Off-Bereich der Frage :) –

Antwort

4

Ich verstehe, dass Sie dies aus einer mobilen App aufrufen und die Anzahl der Feeds könnte steigen.

Je nach Datenmenge, die zurückgegeben wird, wäre es möglich, die Ergebnisse einiger Feeds im selben Aufruf zurückzugeben? Auf diese Weise erledigt der Server die Arbeit. Sie haben die Kontrolle über den Server - Sie haben nicht die Kontrolle über das Gerät des Benutzers und ihre Verbindungsgeschwindigkeit.

Wie Nickebbit vorgeschlagen, sind Dinge wie DeperedResult wirklich einfach zu implementieren. ist es möglich, dass die Daten aus diesen Feeds nicht schnell aktualisiert werden? Wenn ja, sollten Sie die Verwendung von EHCache und der @Cacheable-Annotation untersuchen.

Sie könnten eine Lösung finden, bei der der Benutzer immer eine zwischengespeicherte Version Ihres Inhalts von Ihrem Tomcat-Server zieht. Aber Ihr Tomcat-Server aktualisiert diesen Cache ständig im Hintergrund.

Es ist ein zusätzliches Stück Arbeit - aber am Ende des Tages, wenn die User Experience ist nicht schnell - Benutzer nicht diese App nutzen wollen

7

Tomcat verwaltet nur die eingehenden HTTP-Verbindungen und schiebt die Bytes hin und her. Es gibt keine Tomcat-Optimierung, die durchgeführt werden kann, um Ihre Anwendung besser laufen zu lassen.

Wenn Sie für jede eingehende HTTP-Anforderung 25 parallele Prozesse ausführen müssen, und Sie denken, das ist verrückt, dann müssen Sie überdenken, wie Ihre Anwendung funktioniert.

Keine Tomcat-Konfiguration hilft bei dem, was Sie in Ihrer Frage dargestellt haben.

4

Es sieht so aus, als ob Sie Akka verwenden, aber das Actor-Modell nicht wirklich akzeptieren. Dies wird wahrscheinlich die Parallelität und damit die Skalierbarkeit Ihrer App erhöhen.

Wenn ich es wäre, würde ich Anfragen von meiner REST-API an einen einzelnen oder einen Pool von koordinierenden Akteuren übergeben, die die Anfrage asynchron verarbeiten. Mit Spring's RestController kann dies mit einem Callable oder DeferredResult getan werden, aber es wird offensichtlich ein Äquivalent in welchem ​​Framework Sie verwenden.

Dieser koordinierende Akteur würde dann wiederum die Verarbeitung an andere Akteure (dh Arbeiter) übergeben, die sich um die I/O-gebundenen Aufgaben kümmern (vorzugsweise mit ihrem eigenen Dispatcher, um sicherzustellen, dass andere CPU-gebundene Threads nicht blockiert werden) und reagieren an den Koordinator mit ihren Ergebnissen.

Sobald alle Worker ihre Daten abgerufen und dem Koordinator die Ergebnisse mitgeteilt haben, kann die ursprüngliche Anforderung mit dem vollständigen Ergebnissatz abgeschlossen werden.

Verwandte Themen