Я пытался заставить балансировку нагрузки GRPC работать в моем приложении Java, развернутом в кластере Kubernetes, но у меня не было особого успеха. Кажется, что по этому поводу не слишком много документации, но из примеров в Интернете я вижу, что теперь я могу использовать '.defaultLoadBalancingPolicy (round_robin)' при настройке ManagedChannel (в более поздних версиях GRPC Java lib).
Чтобы быть более конкретным, я использую версию 1.34.1 библиотек Java GRPC. Я создал два приложения Spring Boot (v2.3.4), одно называется grpc-sender, а второе grpc-Receiver.
grpc-sender действует как клиент GRPC и определяет (Netty) ManagedChannel как:
@Bean
public ManagedChannel greetingServiceManagedChannel() {
String host = "grpc-receiver";
int port = 6565;
return NettyChannelBuilder.forAddress(host, port)
.defaultLoadBalancingPolicy("round_robin")
.usePlaintext().build();
}
Тогда grpc-Receiver действует как сервер GRPC:
Server server = ServerBuilder.forPort(6565)
.addService(new GreetingServiceImpl()).build();
Я развертываю эти приложения в кластере Kubernetes (пока работает локально в minikube), и я создал сервис для приложения grpc-Receiver как безголовый сервис:
kind: Service
apiVersion: v1
metadata:
name: grpc-receiver
spec:
clusterIP: None
selector:
app: grpc-receiver
ports:
- name: 'grpc'
port: 6565
protocol: 'TCP'
targetPort: 6565
Однако, когда я пытаюсь отправить сообщение от grpc-sender к grpc-Receiver, я просто вижу это исключение в журналах grpc-sender:
2021-01-08 17:46:24.494 ERROR 1 --- [ault-executor-0] io.grpc.internal.ManagedChannelImpl : [Channel<1>: (grpc-receiver:6565)] Uncaught exception in the SynchronizationContext. Panic!
java.lang.NoSuchFieldError: NAME_RESOLVER_SERVICE_CONFIG
at io.grpc.services.HealthCheckingLoadBalancerFactory$HealthCheckingLoadBalancer.handleResolvedAddresses(HealthCheckingLoadBalancerFactory.java:186) ~[grpc-services-1.25.0.jar!/:1.25.0]
at io.grpc.internal.AutoConfiguredLoadBalancerFactory$AutoConfiguredLoadBalancer.tryHandleResolvedAddresses(AutoConfiguredLoadBalancerFactory.java:154) ~[grpc-core-1.34.1.jar!/:1.34.1]
at io.grpc.internal.ManagedChannelImpl$NameResolverListener$1NamesResolved.run(ManagedChannelImpl.java:1668) ~[grpc-core-1.34.1.jar!/:1.34.1]
at io.grpc.SynchronizationContext.drain(SynchronizationContext.java:95) ~[grpc-api-1.34.1.jar!/:1.34.1]
at io.grpc.SynchronizationContext.execute(SynchronizationContext.java:127) ~[grpc-api-1.34.1.jar!/:1.34.1]
at io.grpc.internal.ManagedChannelImpl$NameResolverListener.onResult(ManagedChannelImpl.java:1682) ~[grpc-core-1.34.1.jar!/:1.34.1]
at io.grpc.internal.DnsNameResolver$Resolve.run(DnsNameResolver.java:333) ~[grpc-core-1.34.1.jar!/:1.34.1]
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) ~[na:na]
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) ~[na:na]
at java.base/java.lang.Thread.run(Thread.java:834) ~[na:na
Может ли кто-нибудь подсказать мне, что я делаю неправильно или чего мне не хватает?
Кстати, мне известны альтернативные подходы к балансировке нагрузки с помощью GRPC, такие как Service Mesh, например Linkerd или Istio, или просто использование прокси-сервера Envoy, но я очень хочу, чтобы что-то работало с использованием встроенных функций балансировки нагрузки GRPC, таких как точка сравнения между различными подходами.
Спасибо большое!
grpclb
гораздо более надежна, и ее следует использовать вместо нее, если это возможно. - person morgwai   schedule 13.05.2021