2017-12-15 2 views
0

Die Anwendung, die wir erstellen, wird voraussichtlich eine hohe Anzahl gleichzeitiger Benutzer haben. Wir versuchen Spring MVC für den Aufbau unserer API-Ebene zu evaluieren.Leistungsunterschied zwischen Spring MVC nicht blockierend und blockierend

Die folgenden 2-Handler geschrieben wurden - eine Sperr- und eine andere nicht-blockierend:

@RequestMapping("/nblocking") 
public DeferredResult<String> nonBlockingProcessing() { 
    DeferredResult<String> deferredResult = new DeferredResult<>(); 
    executionService.execute(new Runnable() { 
     @Override 
     public void run() { 
      deferredResult.setResult(fetcher.load()); 
     } 
    }); 

    return deferredResult; 
} 

@RequestMapping("/blocking") 
public String blockingProcessing() { 
    return fetcher.load(); 
} 

Wir liefen Tests über Jmeter, jeden Endpunkt mit 3500 gleichzeitigen Benutzern zu treffen.

Ergebnisse mit blockierenden Anruf: enter image description here

Ergebnisse mit nicht-blockierenden Anruf: enter image description here

In dem obigen Code wird der fetcher.load Aufruf einer DB-Abfrage MySql machen (max Verbindungen auf 200) und Verbindungspool von maximaler Größe (50).

Insgesamt sind Durchsatz und durchschnittliche Zeiten bei nicht blockierenden Anrufen besser. Welche weiteren Verbesserungen können wir vornehmen oder welche Faktoren können wir berücksichtigen, um den Durchsatz noch zu verbessern?

+0

"Welche weiteren Verbesserungen können wir vornehmen oder welche Faktoren wir berücksichtigen können, um den Durchsatz noch zu verbessern?" Optimiere den Java-Code. Optimiere die MySQL-Abfrage. Optimiere die MySQL-Einstellungen. –

+0

Wie lange benutzt die 'fetcher.load()' Anweisung? Ich würde prüfen, ob es sich um ein Ladeproblem handelt. –

Antwort

0

1) Sie Server verwendet ein synchrones Request-Response-Modell

Nach den Ergebnissen, den Server basiert auf einem synchronen Request-Response-Modell und nicht auf einem asynchrones oder ereignisgesteuerten Modell.
Es ist der Fall für Tomcat, Apache, Weblogic, etc ... und die meisten Java-Anwendungen Server.
In diesem Modell ist die Anzahl der Anfragen im Allgemeinen auf einige Dutzend gleichzeitiger Anfragen beschränkt.
Sie haben 17.000 Anfrage in Ihrem Test ausgeführt.
Das bedeutet also, dass viele Anfragen zur Bearbeitung anstehen.
So wird die Verarbeitung der Anfragen nicht die Leistung verbessern, da der Server bereits voll ist.

2) Die Thread-Erstellung für jede neue Anfrage und die asynchrone Verarbeitung, wie die Antwort zurückgegeben werden muss, hat auch Kosten.

In der Tat muss die JVM in diesem Fall mehr Objekte erstellen und mehr Aufgaben ausführen, und der UC muss auch mehr Planungsaufgaben ausführen, da Sie mehr Threads haben.

Fazit: Die asynchrone Verarbeitung von Server-Seite kann die Leistung verbessern, aber nicht immer

Wie Sie einige der verfügbaren CPU-Threads auf dem Rechner hat, Dividieren Aufgaben, die von mehreren Threads ausgeführt werden sinnvoll, die Leistung zu verbessern.
Da Sie so viele Anfragen wie in Ihrem Fall ausführen, haben Sie keine verfügbare CPU.
Sie werden also nicht in der Leistung gewinnen, Sie werden nur in der Lage sein, mehrere Clients "parallel" zu bearbeiten, aber es wird die Leistung wegen UC-Scheduling und der im letzten Punkt erläuterten Objekterzeugung reduzieren.

Sie sollten so verstehen in Ihrem Fall, warum von Server-Seite die asynchrone Art und Weise langsamer als die synchrone Art und Weise ist.

+0

Ich habe Tomcat 8.5 für die Bereitstellung der App verwendet. Wird Spring nicht async Servlet 3.1 verwenden, wenn wir DeperedResult als Rückgabetyp verwenden? – singhspk

Verwandte Themen