Are there any possible ways to customize a global loadbalance rule while using zuul?
WilliamChen-luckbob opened this issue · 0 comments
Here I'm using zuul to develop a gateway which is able to do customized dynamic route and grey release.
So far, I'm stuck in customize the loadbalance rule.
The goal is to extends and make an overide in ZoneAvoidanceRule's choose method so I can judge some conditions while zuul doing it's routing job.
By debugging the source code I found that ribbon will configure a bunch of loadbalance factory things for all available services, so I think I need to change only the loadbalance rule and that may reach my goal.
I have noticed that a :
@Bean
@ConditionalOnMissingBean
public IRule ribbonRule(IClientConfig config) {
if (this.propertiesFactory.isSet(IRule.class, name)) {
return this.propertiesFactory.get(IRule.class, config, name);
}
ZoneAvoidanceRule rule = new ZoneAvoidanceRule();
rule.initWithNiwsConfig(config);
return rule;
}
There may be an easy way to customize a bean by overiding the source code by customized bean.
But here I'm quite confuzed.
It seems impossible to do so, while IClientConfig is unreachable from outside class and also property 'name' is unreachable from outside class.
While I'm using code like below, the application crashed with exception
Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'ribbon.client.name' in value "${ribbon.client.name}"
Here is my code:
import com.netflix.client.config.CommonClientConfigKey;
import com.netflix.client.config.DefaultClientConfigImpl;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.IRule;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.commons.httpclient.HttpClientConfiguration;
import org.springframework.cloud.netflix.ribbon.PropertiesFactory;
import org.springframework.cloud.netflix.ribbon.RibbonClientName;
import org.springframework.cloud.netflix.ribbon.apache.HttpClientRibbonConfiguration;
import org.springframework.cloud.netflix.ribbon.okhttp.OkHttpRibbonConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
/**
* @author william
* @description
* @Date: 2021-06-02 18:35
*/
@Configuration
@Import({HttpClientConfiguration.class,
OkHttpRibbonConfiguration.class,
HttpClientRibbonConfiguration.class})
public class GreyBalancedConfig {
@Autowired
private PropertiesFactory propertiesFactory;
/**
* Ribbon client default connect timeout.
*/
public static final int DEFAULT_CONNECT_TIMEOUT = 1000;
/**
* Ribbon client default read timeout.
*/
public static final int DEFAULT_READ_TIMEOUT = 1000;
/**
* Ribbon client default Gzip Payload flag.
*/
public static final boolean DEFAULT_GZIP_PAYLOAD = true;
@RibbonClientName
private String name = "client";
@Bean
public IClientConfig ribbonClientConfig() {
DefaultClientConfigImpl config = new DefaultClientConfigImpl();
config.loadProperties(this.name);
config.set(CommonClientConfigKey.ConnectTimeout, DEFAULT_CONNECT_TIMEOUT);
config.set(CommonClientConfigKey.ReadTimeout, DEFAULT_READ_TIMEOUT);
config.set(CommonClientConfigKey.GZipPayload, DEFAULT_GZIP_PAYLOAD);
return config;
}
@Bean
public IRule ribbonRule(IClientConfig config) {
if (this.propertiesFactory.isSet(IRule.class, name)) {
return this.propertiesFactory.get(IRule.class, config, name);
}
GreyBalancedRule rule = new GreyBalancedRule();
rule.initWithNiwsConfig(config);
return rule;
}
}
I know how to use @RibbonClient to do a customized loadbalance in a normal application, but that seems won't working with zuul.
And also, caused by toomany of the applications, I think that configuring @RibbonClient will leads to hard code while @RibbonClients will conflict with bean metadataAwareRule. If I mark my customized configuration as @Primay, the zuul gateway will crash as nether of the requests can pass the gateway nor my customized rule is invoked.
Which I need is a dynamic configuration from a config center that can change the rule of loadbalance dynamically by bean annotated with @RefreshScope. And all the service config will come from config center, I can change configurations without restarting any applications.
Are there any possible ways to do so ?