У меня есть служба, которая передает сообщения с довольно высокой скоростью.
В настоящее время она обслуживается akka-tcp и составляет 3,5 миллиона сообщений в минуту. Я решил попробовать grpc. К сожалению, это привело к гораздо меньшей пропускной способности: ~ 500 тыс. Сообщений в минуту и даже меньше.
Не могли бы вы порекомендовать, как его оптимизировать?
Мои настройки
Аппаратное обеспечение : 32 ядра, куча 24 ГБ.
версия grpc : 1,25.0
Формат сообщения и конечная точка
Сообщение в основном представляет собой двоичный двоичный объект. Клиент передает 100K - 1M и более сообщений в один и тот же запрос (асинхронно), сервер не отвечает ни на что, клиент использует наблюдателя без операций
service MyService {
rpc send (stream MyMessage) returns (stream DummyResponse);
}
message MyMessage {
int64 someField = 1;
bytes payload = 2; //not huge
}
message DummyResponse {
}
Проблемы: скорость передачи сообщений низкая по сравнению с реализацией akka,Я наблюдаю низкую загрузку ЦП, поэтому я подозреваю, что вызов grpc фактически блокируется внутри, несмотря на то, что он говорит об обратном. Вызов onNext()
действительно не сразу возвращается, но на столе также есть GC.
Я пытался породить больше отправителей, чтобы смягчить эту проблему, но не получил большого улучшения.
Мои выводы Grpc фактически выделяет 8-килобайтный буфер байтов для каждого сообщения при его сериализации. Смотрите трассировку стека:
java.lang.Thread.State: BLOCKED (на мониторе объекта) на com.google.common.io.ByteStreams.createBuffer (ByteStreams.java:58) на com.google. .common.io.ByteStreams.copy (ByteStreams.java:105) по адресу io.grpc.internal.MessageFramer.writeToOutputStream (MessageFramer.java:274) по адресу io.grpc.internal.MessageFramer.writeKnownLengthUncompressed: 2: наFFio.grpc.internal.MessageFramer.writeUncompressed (MessageFramer.java:168) в io.grpc.internal.MessageFramer.writePayload (MessageFramer.java:141) в io.grpc.internal.AbstractStream.writeMessage (AbstractStream.j::в io.grpc.internal.ForwardingClientStream.writeMessage (ForwardingClientStream.java:37) в io.grpc.internal.DelayedStream.writeMessage (DelayedStream.java:252) в io.grpc.internal.ClientCallImpl.l3 () в io.grpc.internal.ClientCallImpl.sendMessage (ClientCallImpl.java:457) в io.grpc.ForwardingClientCall.sendMessage (ForwardingClientCall.java:37) в io.grpc.ForwardingClientCall.sendMessage (ForwardingClientCall.java:37) по адресу io.grpc.stub.ClientCalls $ CallToStreamObserverAdapter.onNext (ClientCalls.java:346)
Любая помощь с высокой эффективностью на основе построения лучших практикклиенты grpc оценили.