Ribbon细粒度配置

1、java代码配置

单独建包,不然会产生spring父子上下文重叠,导致该配置为全局配置

package configuration;

import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
* @author: yangchun
* @description:
* @date: Created in 2020-02-19 7:49
*/
@Configuration
public class RibbonConfiguration {
@Bean
public IRule ribbonRule(){
return new RandomRule();
}
}
package com.fj.xiaofeiyang.pay.api.configuration;

import configuration.RibbonConfiguration;
import org.springframework.cloud.netflix.ribbon.RibbonClient;
import org.springframework.context.annotation.Configuration;

/**
* @author: yangchun
* @description:
* @date: Created in 2020-02-19 7:51
*/
@RibbonClient(name = "pay",configuration = RibbonConfiguration.class)
public class PayRibbonConfiguration {
}

2、配置文件配置

pay:
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

3、最佳实践总结

配置方式 优点 缺点
代码配置           基于代码,更加灵活         有小坑(父子上下文),线上修改得重新打包、发包
属性配置 易上手,配置更加直观,线上修改无需重新打包发布,优先级更高 极端场景下没有代码配置灵活

 

 

尽量使用属性配置,属性配置不了采用代码配置,属性配置实现不了的采用代码配置。

4、全局配置

1、让前面的configuration包可以被应用扫描到,让父子上下文重叠

2、第二种如下

package com.fj.xiaofeiyang.pay.api.configuration;

import org.springframework.cloud.netflix.ribbon.RibbonClient;
import org.springframework.cloud.netflix.ribbon.RibbonClients;

/**
* @author: yangchun
* @description:
* @date: Created in 2020-02-19 7:51
*/
@RibbonClients(defaultConfiguration = configuration.RibbonConfiguration.class)
public class RibbonConfiguration {}
5、支持的配置项
接口                             作用                             默认值                                    
IClientConfig 读取配置 DefaultClientConfigImpl
IRule  负载均衡规则,选择实例  ZoneAvoidanceRule
IPing 筛选Ping不通的实例  DummyPing 
ServerList<Server> 交给Ribbon的实例列表  Ribbon:ConfigurationBasedServerList,Spring Cloud Alibaba :NacosServerList 
ServerListFilter<Server> 过滤掉不符合条件的实例   ZonePreferenceServerListFilter
ILoadBalancer Ribbon的入口 ZoneAwareLoadBalancer
ServerListUpdater 更新交给Ribbon的List的策略 PollingServerListUpdater







java代码配置如下
@Bean
public IRule ribbonRule(){
return new RandomRule();
}

属性配置如下
<clientName>.ribbon.如下属性:
NFLoadBalancerClassName:ILoaderBalancer实现类
NFLoadBalancerRuleClassName:IRule实现类
NFLoadBalancerPingClassName:IPing实现类
NIWSServerListClassName:ServerList实现类
NIWSServerListFilterClassName:ServerListFilter实现类
6、ribbon开启饥饿加载
ribbon:
eager-load:
enabled: true
clients: pay
7、扩展ribbon支持权重选择
spring cloud commons --定义了标准
spring cloud loadbalancer --没有定义权重

 

 先将两个服务实例权重进行修改,


public class NacosWeightRule extends AbstractLoadBalancerRule {
@Autowired
private NacosDiscoveryProperties nacosDiscoveryProperties;
@Override
public void initWithNiwsConfig(IClientConfig iClientConfig) {

}

@Override
public Server choose(Object key) {
BaseLoadBalancer baseLoadBalancer = (BaseLoadBalancer)this.getLoadBalancer();
String name = baseLoadBalancer.getName();
NamingService nameingService = nacosDiscoveryProperties.namingServiceInstance();
try {
Instance instance= null;
instance = nameingService.selectOneHealthyInstance(name);
return new NacosServer(instance);
} catch (NacosException e) {
return null;
}
}
}
然后采用属性
pay:
ribbon:
NFLoadBalancerRuleClassName: com.fj.xiaofeiyang.pay.api.configuration.NacosWeightRule
配置的方式
扩展同一个集群下的服务器实例同时选择
package com.fj.xiaofeiyang.pay.api.configuration;

import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.alibaba.nacos.client.naming.core.Balancer;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.BaseLoadBalancer;
import com.netflix.loadbalancer.Server;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.alibaba.nacos.NacosDiscoveryProperties;
import org.springframework.cloud.alibaba.nacos.ribbon.NacosServer;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
* @author: yangchun
* @description:
* @date: Created in 2020-02-19 9:09
*/
public class NacosClusterRule extends AbstractLoadBalancerRule {
@Autowired
private NacosDiscoveryProperties nacosDiscoveryProperties;
@Override
public void initWithNiwsConfig(IClientConfig iClientConfig) {

}

@Override
public Server choose(Object key) {
BaseLoadBalancer baseLoadBalancer = (BaseLoadBalancer)this.getLoadBalancer();
String name = baseLoadBalancer.getName();
String clusterName = nacosDiscoveryProperties.getClusterName();
NamingService namingService = nacosDiscoveryProperties.namingServiceInstance();
try {
List<Instance> instances= namingService.selectInstances(name,true);
List<Instance> sameClusterInstances = instances.stream().filter(instance -> Objects.equals(instance.getClusterName(),clusterName))
.collect(Collectors.toList());
List<Instance> instancesToBchosen = new ArrayList<>();
if(CollectionUtils.isEmpty(sameClusterInstances)){
instancesToBchosen = instances;
}else {
instancesToBchosen = sameClusterInstances;
}
Instance instance= ExtendBalancer.getHostByRandomWeight2(instancesToBchosen);
return new NacosServer(instance);
} catch (NacosException e) {
return null;
}
}
}
class ExtendBalancer extends Balancer{
public static Instance getHostByRandomWeight2(List<Instance> instances){
return getHostByRandomWeight(instances);
}
}

然后采用属性

pay:
ribbon:
NFLoadBalancerRuleClassName: com.fj.xiaofeiyang.pay.api.configuration.NacosClusterRule
扩展通过元数据版本来实现
package com.fj.xiaofeiyang.pay.api.configuration;

import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.BaseLoadBalancer;
import com.netflix.loadbalancer.Server;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.alibaba.nacos.NacosDiscoveryProperties;
import org.springframework.cloud.alibaba.nacos.ribbon.NacosServer;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
* @author: yangchun
* @description:
* @date: Created in 2020-02-19 9:09
*/
public class NacosVersionRule extends AbstractLoadBalancerRule {
@Autowired
private NacosDiscoveryProperties nacosDiscoveryProperties;
@Override
public void initWithNiwsConfig(IClientConfig iClientConfig) {

}

@Override
public Server choose(Object key) {
BaseLoadBalancer baseLoadBalancer = (BaseLoadBalancer)this.getLoadBalancer();
String name = baseLoadBalancer.getName();
String targetVesion = nacosDiscoveryProperties.getMetadata().get("target-version");
NamingService namingService = nacosDiscoveryProperties.namingServiceInstance();
try {
List<Instance> instances= namingService.selectInstances(name,true);
List<Instance> sameClusterInstances = instances.stream().filter(instance -> Objects.equals(instance.getMetadata().get("version"),targetVesion))
.collect(Collectors.toList());
List<Instance> instancesToBchosen = new ArrayList<>();
if(CollectionUtils.isEmpty(sameClusterInstances)){
instancesToBchosen = instances;
}else {
instancesToBchosen = sameClusterInstances;
}
Instance instance= ExtendBalancer.getHostByRandomWeight2(instancesToBchosen);
return new NacosServer(instance);
} catch (NacosException e) {
return null;
}
}

}

 

 

 
posted on 2020-02-19 15:23  清浊  阅读(690)  评论(0)    收藏  举报