Latenz in der Java-Clientbibliothek beheben

Einführung

Wenn in Ihrer App eine höhere als die übliche Latenz, ein geringer Durchsatz oder Zeitüberschreitungen mit dem Java Datastore-Client auftreten, liegt das Problem möglicherweise an der clientseitigen gRPC-Konfiguration und nicht am Firestore-/Datastore-Backend. In diesem Leitfaden erfahren Sie, wie Sie häufige Probleme mit clientseitiger Drosselung, falsche Channelpool-Einstellungen und übermäßigen Channel-Churn diagnostizieren und beheben.

Diagnose

Bei der Verwendung von Java-Clients ist es wichtig, das ausführliche gRPC- und gax-java-Logging zu aktivieren, um die Dynamik des Channel-Pools zu überwachen, Drosselungsprobleme, Probleme mit der Wiederverwendung von Verbindungen oder übermäßigen Channel-Churn zu diagnostizieren.

Logging für Java-Clients aktivieren

So aktivieren Sie die detaillierte Protokollierung:logging.properties

## This tracks the lifecycle events of each grpc channel 
io.grpc.ChannelLogger.level=FINEST
## Tracks channel pool events(resizing, shrinking) from GAX level
com.google.api.gax.grpc.ChannelPool.level=FINEST

Aktualisieren Sie außerdem die Ausgabelogebene in logging.properties, um diese Logs zu erfassen:


# This could be changed to a file or other log output
handlers=java.util.logging.ConsoleHandler
java.util.logging.ConsoleHandler.level=FINEST
java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter

Wenden Sie die Konfiguration an

Die logging.properties-Datei kann auf zwei Arten angewendet werden:

1. Über eine JVM-Systemeigenschaft

Fügen Sie dieses Argument beim Starten der Java-Anwendung hinzu:

-Djava.util.logging.config.file=/path/to/logging.properties

2. Programmatisch laden

Diese Methode ist nützlich für Integrationstests oder Anwendungen, bei denen die Protokollierungskonfiguration im Code verwaltet wird. Achten Sie darauf, dass dieser Code früh im Lebenszyklus der Anwendung ausgeführt wird.

LogManager logManager = LogManager.getLogManager();
  try (final InputStream is = Main.class.getResourceAsStream("/logging.properties")) {
logManager.readConfiguration(is);
}

Beispiel für das Logging

Nachdem Sie das ausführliche Logging aktiviert haben, sehen Sie eine Mischung aus Nachrichten von com.google.api.gax.grpc.ChannelPool und io.grpc.ChannelLogger:

Kanäle mit zu geringer Bereitstellung, die eine Erweiterung des Channel-Pools ausgelöst haben:

09:15:30.123 [pool-1-thread-1] DEBUG com.google.api.gax.grpc.ChannelPool - Detected throughput peak of 40, expanding channel pool size: 4 -> 6. 
09:15:30.124 [grpc-nio-worker-ELG-1-5] DEBUG io.grpc.ChannelLogger - [Channel<5>: (datastore.googleapis.com:443)] Entering IDLE state 
09:15:30.124 [grpc-nio-worker-ELG-1-5] DEBUG io.grpc.ChannelLogger - [Channel<6>: (datastore.googleapis.com:443)] Entering IDLE state 
09:15:30.125 [grpc-nio-worker-ELG-1-5] TRACE io.grpc.ChannelLogger - [Channel<5>: (datastore.googleapis.com:443)] newCall() called 
09:15:30.126 [grpc-nio-worker-ELG-1-5] DEBUG io.grpc.ChannelLogger - [Channel<5>: (datastore.googleapis.com:443)] Entering CONNECTING state 09:15:30.127 [grpc-nio-worker-ELG-1-5] DEBUG io.grpc.ChannelLogger - [Channel<5>: (datastore.googleapis.com:443)] Entering READY state with picker: Picker{result=PickResult{subchannel=Subchannel<7>: (datastore.googleapis.com:443), streamTracerFactory=null, status=Status{code=OK, description=null, cause=null}, drop=false, authority-override=null}} 
09:15:31.201 [grpc-nio-worker-ELG-1-6] TRACE io.grpc.ChannelLogger - [Channel<6>: (datastore.googleapis.com:443)] newCall() called 
09:15:31.202 [grpc-nio-worker-ELG-1-6] DEBUG io.grpc.ChannelLogger - [Channel<6>: (datastore.googleapis.com:443)]