Ho un servizio che trasferisce i messaggi a un ritmo piuttosto elevato.
Attualmente è servito da Akka-TCPC e invia 3,5 milioni di messaggi al minuto. Ho deciso di provare grpc. Sfortunatamente ha prodotto un throughput molto più piccolo: ~ 500k messaggi al minuto ancora meno.
Potresti consigliarmi come ottimizzarlo?
La mia configurazione
Hardware : 32 core, heap da 24 GB.
versione di grpc: 1.25.0
Formato e endpoint del messaggio
Il messaggio è fondamentalmente un BLOB binario. Il client trasmette 100 K - 1 M e più messaggi nella stessa richiesta (in modo asincrono), il server non risponde con nulla, il client utilizza un osservatore no-op
service MyService {
rpc send (stream MyMessage) returns (stream DummyResponse);
}
message MyMessage {
int64 someField = 1;
bytes payload = 2; //not huge
}
message DummyResponse {
}
Problemi: la velocità dei messaggi è bassa rispetto all'implementazione akka. Osservo un basso utilizzo della CPU, quindi sospetto che la chiamata grpc stia effettivamente bloccando internamente nonostante dice diversamente. La chiamata onNext()
infatti non ritorna immediatamente ma c'è anche GC sul tavolo.
Ho provato a generare più mittenti per mitigare questo problema ma non ho ottenuto molti miglioramenti.
Le mie scoperte Grpc alloca effettivamente un buffer di byte da 8 KB su ciascun messaggio quando lo serializza. Vedi lo stacktrace:
java.lang.Thread.State: BLOCKED (sul monitor oggetti) su com.google.common.io.ByteStreams.createBuffer (ByteStreams.java:58) su com.google.common.io.ByteStreams.copy (ByteStreams.java: 105) at io.grpc.internal.MessageFramer.writeToOutputStream (MessageFramer.java:274) at io.grpc.internal.MessageFramer.writeKnownLengthUncompressed (MessageFramer.java:230) at io.grpc.internal.MessageFramerwram : 168) at io.grpc.internal.MessageFramer.writePayload (MessageFramer.java:141) at io.grpc.internal.AbstractStream.writeMessage (AbstractStream.java:53) at io.grpc.internal.ForwardingClientStream.writeMessage (Forwarding. java: 37) su io.grpc.internal.DelayedStream.writeMessage (DelayedStream.java:252) su io.grpc.internal.ClientCallImpl.sendMessageInternal (ClientCallImpl.java:473) at io.grpc.internal.ClientCallImpl.sendMessage (ClientCallImpl.java:457) at io.grpc.ForwardingClientCall.sendMessage (ForwardingClientCall.jgr.C37 (ForwardingClientCall.java:37) at io.grpc.stub.ClientCalls $ CallToStreamObserverAdapter.onNext (ClientCalls.java:346)
Apprezzato qualsiasi aiuto con le migliori pratiche per la creazione di client grpc ad alto rendimento.
scalapb
. Probabilmente questo stacktrace proveniva davvero dal codice generato da scalapb. Ho rimosso tutto ciò che riguarda scalapb ma non ha aiutato molto le prestazioni di wrt.