Tôi có một dịch vụ chuyển tin nhắn với tốc độ khá cao.
Hiện tại nó được phục vụ bởi akka-tcp và nó tạo ra 3,5 triệu tin nhắn mỗi phút. Tôi quyết định thử grpc. Thật không may, nó dẫn đến thông lượng nhỏ hơn nhiều: ~ 500 nghìn tin nhắn mỗi phút thậm chí còn ít hơn.
Bạn có thể vui lòng giới thiệu làm thế nào để tối ưu hóa nó?
Thiết lập của tôi
Phần cứng : 32 lõi, heap 24Gb.
phiên bản grpc: 1.25.0
Định dạng tin nhắn và điểm cuối
Thông điệp về cơ bản là một blob nhị phân. Máy khách truyền 100K - 1M và nhiều tin nhắn hơn vào cùng một yêu cầu (không đồng bộ), máy chủ không phản hồi với bất cứ điều gì, khách hàng sử dụng trình quan sát không hoạt động
service MyService {
rpc send (stream MyMessage) returns (stream DummyResponse);
}
message MyMessage {
int64 someField = 1;
bytes payload = 2; //not huge
}
message DummyResponse {
}
Vấn đề: Tỷ lệ tin nhắn thấp so với thực hiện akka. Tôi quan sát việc sử dụng CPU thấp nên tôi nghi ngờ rằng cuộc gọi grpc thực sự đang chặn bên trong mặc dù nó nói khác đi. Gọi onNext()
thực sự không trở lại ngay lập tức nhưng cũng có GC trên bàn.
Tôi đã cố gắng sinh ra nhiều người gửi hơn để giảm thiểu vấn đề này nhưng không được cải thiện nhiều.
Phát hiện của tôi Grpc thực sự phân bổ bộ đệm byte 8KB cho mỗi thông báo khi tuần tự hóa nó. Xem stacktrace:
java.lang.Thread.State: BLOCKED (trên màn hình đối tượng) tại com.google.common.io.ByteStreams.createBuffer (ByteStreams.java:58) tại com.google.common.io.ByteStreams.copy (ByteStreams.java: 105) tại io.grpc.iternal.MessageFramer.writeToOutputStream (MessageFramer.java:274) tại io.grpc.iternal.MessageFramer.writeKnownL wavelUncompression (MessageFramer.java:2). : 168) tại io.grpc.iternal.MessageFramer.writePayload (MessageFramer.java:141) tại io.grpc.i INTERNal.AbaugeStream.writeMessage (AbstractStream.java:53) tại io.grpc.i INTERNal java: 37) tại io.grpc.iternal.DelayedStream.writeMessage (DelayedStream.java:252) tại io.grpc.iternal.ClientCallImpl.sendMessageI Internalal (ClientCallImpl.java:473) tại io.grpc.i INTERNal.ClientCallImpl.sendMessage (ClientCallImpl.java: iat (ForwardingClientCall.java:37) tại io.grpc.stub.ClientCalls $ CallToStreamObserverAd Module.onNext (ClientCalls.java:346)
Bất kỳ trợ giúp với thực tiễn tốt nhất về xây dựng khách hàng grpc thông lượng cao đánh giá cao.
scalapb
. Có lẽ stacktrace này thực sự là từ mã được tạo bằng scalapb. Tôi đã loại bỏ mọi thứ liên quan đến scalapb nhưng nó không giúp ích nhiều cho hiệu suất wrt.