spring-cloud / spring-cloud-commons

Common classes used in different Spring Cloud implementations
Apache License 2.0
701 stars 697 forks source link

Can change LoadBalancer of Gateway Filter? #1309

Closed apollyon4 closed 6 months ago

apollyon4 commented 8 months ago

I tried changing LoadBalancer in ReactiveLoadBalancerClientFilter to override Mono<Response<ServiceInstance>> choose(Request request) to route to instances based on user request information and eureka metadata, but it was difficult.

To change the LoadBalancer, I tried injecting a bean that inherited LoadBalancerClientFactory, but the LoadBalancerClientConfiguration configuration class is specified in the factory constructor.

Even if ServiceInstanceListSupplier is provided using the withBase method of ServiceInstanceListSupplierBuilder, it is difficult to set serviceId because is not dynamically created through NamedContextFactory.

OlgaMaciaszek commented 7 months ago

Hello @apollyon4, you should be able to modify the behaviour by providing custom ServiceInstanceListSupplier or ReactorLoadBalancer bean as described in the docs without having to modify anything in ReactiveLoadBalancerClientFilter. If you're still facing an issue after trying that, please provide a minimal, complete, verifiable example that reproduces the issue. Please make sure it's against Spring Cloud 2023.0.0, as it's the only version with OSS support at this point.

spring-cloud-issues commented 7 months ago

If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.

spring-cloud-issues commented 7 months ago

Closing due to lack of requested feedback. If you would like us to look at this issue, please provide the requested information and we will re-open the issue.

apollyon4 commented 6 months ago

https://github.com/apollyon4/spring-cloud-netflix-issue Through debugging, I checked which loadbalancer was called.

But since it's not a functional bug, I don't think a project is needed. '--

@OlgaMaciaszek Thank you for your response.

I didn't know that naming it @LoadBalancerClient would connect to lb://{id}.

But what I want is to register new route definitions through config-api so that it can be refreshed without deployment.

However, if I want to register the name of @LoadBalancerClient for the added route definition, I need to deploy the server.

I would like to be able to change the default RoundLoabinLoadBalancer.

OlgaMaciaszek commented 6 months ago

@apollyon4 You can change the default RoundRobinLoadBalancer; you just need to create your own configuration class where you create instances of the beans you'd like to use with @Bean-annotated methods, and pass the configuration via @LoadBalancerClient or @LoadBalancerClients annotation, for example over a @Configuration class. It's all described in the docs I've linked, please take a look. You can also see an example here: https://github.com/spring-cloud-samples/spring-cloud-intro-demo/blob/main/card-service/src/main/java/org/example/excluded/CustomLoadBalancerConfiguration.java - we're providing a custom ServiceInstanceListSupplier, but you could provide a custom ReactorLoadBalancer bean instead.

apollyon4 commented 6 months ago

@OlgaMaciaszek I understood your answer to mean that some serviceId(name or value of the client) could changed to @LoadBalancerClient. I was already able to change RoundRobinLoadBalancer through @LoadBalancerClient in my example project, but it's not what I want.

I cannot change the default RoundRobinLoadBalancer. I can only change what is declared in @LoadBalancerClient.

I want to set default another LoadBalancer instead of RoundRobinLoadBalancer without specifying @LoadBalancerClient because serviceId is unknown in build time.

OlgaMaciaszek commented 6 months ago

Hell @apollyon4, you'd need to use @LoadBalancerClients annotation's defaultConfiguration attribute to pass your configuration class. Does this solve your issue?

apollyon4 commented 6 months ago

@OlgaMaciaszek Thank you! This is the option I was looking for. I should have looked it up better, I'm sorry.

OlgaMaciaszek commented 6 months ago

No problem. Closing as question answered.