Open cyuegit opened 2 years ago
FFR:
I would like to confirm whether I understand your problem correctly.
1) You don't have access to the ServiceInstance
's Metadata
and thus cannot customize the LoadBalancer
behavior?
2) Or the attributes won't get updated unless the service instance list actually changes?
Neither of the above 2. i can get the ServiceInstance's Metadata with Reflect. i customize my LoadBalancer ,but depend on the onSubchannelState. but onSubchannelState depend on needsToUpdateConnections。
please look up net.devh.boot.grpc.client.nameresolver.DiscoveryClientNameResolver.Resolve#resolveInternal
needsToUpdateConnections do not Compare ServiceInstance's Metadata, eg nacos.weight.
The logic for updating the gRPC server list using a discovery client Creates a new Resolve that stores a snapshot of the relevant states of the resolver. 兄弟 我是中国人,可以中文交流吗。 https://github.com/cyuegit/spring-boot-grpc needsToUpdateConnections 没监控元数据的变化,我在nacos控制页面改了权重,不能触发onSubchannelState变动。后面我的负载均衡策略没拿到onSubchannelState事件,没法更新ServiceInstanceList。 我自己后面写了CustomDiscoveryClientNameResolver,CustomDiscoveryClientResolverFactory ,重构了needsToUpdateConnections 方法,但是没法替换默认的DiscoveryClientResolverFactory。
GrpcDiscoveryClientAutoConfiguration 这个类我也看了,请指教
Okay, from your description it looks like you dont get the updated metadata (weight).
I think we have to use the hash of the metadata in the check as well to ensure it does get updated correctly.
If you want to provide your own fix, make sure you register it with a higher priority than my resolver.
And make sure you register it in the default registry
Writing in chinese is fine. IMO its easier to read the google translated text because I can check the additional context/meanings to decipher the content. If its pre translated then the meaning is already lost and I have to guess it.
step1:I customized the NameResolverProvider and set priority equal to 7. step2:I use the spi to load my customResolverProvider But start error. how to register it in the default registry?
Please always post the stacktrace of the error. Otherwise I dont know what went wrong.
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'grpcNameResolverRegistration' defined in class path resource [net/devh/boot/grpc/client/autoconfigure/GrpcClientAutoConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [net.devh.boot.grpc.client.nameresolver.NameResolverRegistration]: Factory method 'grpcNameResolverRegistration' threw exception; nested exception is java.util.ServiceConfigurationError: io.grpc.NameResolverProvider: Provider com.xcbeyond.springboot.grpc.nameresolver.CustomDiscoveryClientResolverFactory could not be instantiated
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:658) ~[spring-beans-5.3.15.jar:5.3.15]
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:638) ~[spring-beans-5.3.15.jar:5.3.15]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1352) ~[spring-beans-5.3.15.jar:5.3.15]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1195) ~[spring-beans-5.3.15.jar:5.3.15]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582) ~[spring-beans-5.3.15.jar:5.3.15]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) ~[spring-beans-5.3.15.jar:5.3.15]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.15.jar:5.3.15]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.15.jar:5.3.15]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.15.jar:5.3.15]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:233) ~[spring-beans-5.3.15.jar:5.3.15]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveNamedBean(DefaultListableBeanFactory.java:1282) ~[spring-beans-5.3.15.jar:5.3.15]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveNamedBean(DefaultListableBeanFactory.java:1243) ~[spring-beans-5.3.15.jar:5.3.15]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveBean(DefaultListableBeanFactory.java:494) ~[spring-beans-5.3.15.jar:5.3.15]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:349) ~[spring-beans-5.3.15.jar:5.3.15]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:342) ~[spring-beans-5.3.15.jar:5.3.15]
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1172) ~[spring-context-5.3.15.jar:5.3.15]
at net.devh.boot.grpc.client.inject.GrpcClientBeanPostProcessor.getChannelFactory(GrpcClientBeanPostProcessor.java:200) ~[grpc-client-spring-boot-autoconfigure-2.13.1.RELEASE.jar:2.13.1.RELEASE]
at net.devh.boot.grpc.client.inject.GrpcClientBeanPostProcessor.processInjectionPoint(GrpcClientBeanPostProcessor.java:175) ~[grpc-client-spring-boot-autoconfigure-2.13.1.RELEASE.jar:2.13.1.RELEASE]
... 34 common frames omitted
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [net.devh.boot.grpc.client.nameresolver.NameResolverRegistration]: Factory method 'grpcNameResolverRegistration' threw exception; nested exception is java.util.ServiceConfigurationError: io.grpc.NameResolverProvider: Provider com.xcbeyond.springboot.grpc.nameresolver.CustomDiscoveryClientResolverFactory could not be instantiated
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185) ~[spring-beans-5.3.15.jar:5.3.15]
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:653) ~[spring-beans-5.3.15.jar:5.3.15]
... 51 common frames omitted
Caused by: java.util.ServiceConfigurationError: io.grpc.NameResolverProvider: Provider com.xcbeyond.springboot.grpc.nameresolver.CustomDiscoveryClientResolverFactory could not be instantiated
at java.util.ServiceLoader.fail(ServiceLoader.java:232) ~[na:1.8.0_291]
at java.util.ServiceLoader.access$100(ServiceLoader.java:185) ~[na:1.8.0_291]
at java.util.ServiceLoader$LazyIterator.nextService(ServiceLoader.java:384) ~[na:1.8.0_291]
at java.util.ServiceLoader$LazyIterator.next(ServiceLoader.java:404) ~[na:1.8.0_291]
at java.util.ServiceLoader$1.next(ServiceLoader.java:480) ~[na:1.8.0_291]
at io.grpc.ServiceProviders.loadAll(ServiceProviders.java:67) ~[grpc-api-1.45.0.jar:1.45.0]
at io.grpc.NameResolverRegistry.getDefaultRegistry(NameResolverRegistry.java:115) ~[grpc-api-1.45.0.jar:1.45.0]
at net.devh.boot.grpc.client.autoconfigure.GrpcClientAutoConfiguration.grpcNameResolverRegistration(GrpcClientAutoConfiguration.java:119) ~[grpc-client-spring-boot-autoconfigure-2.13.1.RELEASE.jar:2.13.1.RELEASE]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_291]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_291]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_291]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_291]
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154) ~[spring-beans-5.3.15.jar:5.3.15]
... 52 common frames omitted
Caused by: java.lang.InstantiationException: com.xcbeyond.springboot.grpc.nameresolver.CustomDiscoveryClientResolverFactory
at java.lang.Class.newInstance(Class.java:427) ~[na:1.8.0_291]
at java.util.ServiceLoader$LazyIterator.nextService(ServiceLoader.java:380) ~[na:1.8.0_291]
... 62 common frames omitted
Caused by: java.lang.NoSuchMethodException: com.xcbeyond.springboot.grpc.nameresolver.CustomDiscoveryClientResolverFactory.<init>()
at java.lang.Class.getConstructor0(Class.java:3082) ~[na:1.8.0_291]
at java.lang.Class.newInstance(Class.java:412) ~[na:1.8.0_291]
... 63 common frames omitted
If you use the ServiceLoader API you cannot use constructor parameters or bean injection.
Thats why we create it as a spring bean:
you mean i define AutoConfiguration in spring.factories by myself? But how do I make GrpcDiscoveryClientAutoConfiguration ineffective?
A simple @Configuration
should work as well.
You don't have to exclude GrpcDiscoveryClientAutoConfiguration
, but you can do so using any of these variants:
https://www.baeldung.com/spring-data-disable-auto-config
Thanks, it's resolved
nacos NameResolver can not analyze metadata.for example,i change the weight of serviceinstance on nacos consoleui,but needsToUpdateConnections compare host and port,never care the weight。 i suggest make md5 for instanceList,this is a quick Comparators