Ich versuche, die Antwortzeit meiner REST-APIs zu verbessern (ich verwende SpringBoot 2.1.3 mit Groovy 2.4.14 und MSSQL). Mir ist aufgefallen, dass die populärere GET-API in bestimmten Zeiträumen viel länger dauert als sie sollte (> 4 Sekunden im Gegensatz zu 0,3 Sekunden). Ich habe mich mit CPU-Auslastung, Speicher, Blockieren von Threads, Blockieren von DBs, DeferredResult, Abrufen von Schemata, SpringBoot- und JPA-Einstellungen usw. befasst. Keines davon war ein Engpass oder einfach nicht relevant (die Datenbanksuche ist ein einfaches Repository.findById () für ein Domänenobjekt mit einigen primitiven Feldern).

List<Object> getObjectForId(String id) {
    curCallCount++
    List<Object> objList = objectRepository.findAllById(id)
    curCallCount--
    objList
}

Das Problem scheint zu sein, dass die Antwortzeit des API-Aufrufs umso länger ist, je mehr Aufrufe an den Dienst vorhanden sind, die zum Zeitpunkt des Aufrufs noch nicht beendet wurden (es gibt fast eine lineare Korrelation, wenn 50 Aufrufe an den Dienst vorhanden sind , repository.findbyId () dauert 5 Sekunden, und wenn 200 vorhanden sind, dauert es 20 Sekunden. Während 200 Aufrufe gleichzeitig ausgeführt werden, ist die manuelle Datenbankabfrage immer noch schnell (0,3 Sekunden).

Wird dies für die Spring-Repository-Aufrufe erwartet? Woher kommt dieser Overhead von repository.findById () in einer Umgebung, in der viele Dienste gleichzeitig aufgerufen werden, obwohl die Leistung der manuellen Datenbanksuche nicht beeinträchtigt wird?

0
JK Sung 6 Okt. 2020 im 04:10

2 Antworten

Beste Antwort

Das Problem war, dass die Größe des Hikari-Pools zu klein war (standardmäßig 10, sodass Prozesse bei mehr als 10 gleichzeitigen Aufrufen auf einen freien Thread warten müssen). Durch Erhöhen dieser Option (z. B. auf 150) wurde dieses Problem behoben.

0
JK Sung 10 Okt. 2020 im 00:08

Ich weiß nichts über die API-Seite, aber ich würde auf jeden Fall zunächst die Kompilierungs- / Neukompilierungsrate in SQL Server und Ihre Plan-Cache-Nutzung betrachten. Wenn Sie eine Zeichenfolgenvariable verwenden, werden möglicherweise alle Ihre Parameter als nvarchar (max) übergeben und die Wiederverwendung Ihrer Abfragepläne eingeschränkt.

0
Martin Cairney 6 Okt. 2020 im 01:32