spring cloud 的自定义ribbon路由错误

1、错误消息

Error creating bean with name 'ribbonLoadBalancingHttpClient' defined in org.springframework.cloud.netflix.ribbon.apache.HttpClientRibbonConfiguration: Unsatisfied dependency expressed through method 'ribbonLoadBalancingHttpClient' parameter 2; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'ribbonLoadBalancer' defined in org.springframework.cloud.netflix.ribbon.RibbonClientConfiguration: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.netflix.loadbalancer.ILoadBalancer]: Factory method 'ribbonLoadBalancer' threw exception; nested exception is java.lang.RuntimeException: Unexpected exception creating rule for ZoneAwareLoadBalancer

2、IRule接口是实现要加无参数构造

IRule接口是实现类要加无惨构造,不然启动没有问题,调用就无法找到路由。

3、正确实例

package com.abc.balance;

import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.Server;

import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;

public class CustomRule  implements IRule {
    private ILoadBalancer ib;
    private List<Integer> excludePorts;


    public CustomRule() {
    }

    public CustomRule(List<Integer> excludePorts) {
        this.excludePorts = excludePorts;
    }

    @Override
    public Server choose(Object o) {
        List<Server> servers = ib.getReachableServers();
        List<Server> availableServices = getAvailableServices(servers);
        return getRandomService(availableServices);
    }

    private Server getRandomService(List<Server> availableServices) {
        int index = new Random().nextInt(availableServices.size());
        return availableServices.get(index);
    }

    private List<Server> getAvailableServices(List<Server> servers) {
        if (excludePorts == null || excludePorts.isEmpty()){
            return servers;
        }
        return servers.stream().filter(server -> excludePorts.stream().noneMatch(port->port==server.getPort())).collect(Collectors.toList());
    }

    @Override
    public void setLoadBalancer(ILoadBalancer iLoadBalancer) {
        this.ib = iLoadBalancer;
    }

    @Override
    public ILoadBalancer getLoadBalancer() {
        return this.ib;
    }
}

4、错误示例

package com.abc.balance;

import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.Server;

import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;

public class CustomRule  implements IRule {
    private ILoadBalancer ib;
    private List<Integer> excludePorts;


    //public CustomRule() {
    //}

    public CustomRule(List<Integer> excludePorts) {
        this.excludePorts = excludePorts;
    }

    @Override
    public Server choose(Object o) {
        List<Server> servers = ib.getReachableServers();
        List<Server> availableServices = getAvailableServices(servers);
        return getRandomService(availableServices);
    }

    private Server getRandomService(List<Server> availableServices) {
        int index = new Random().nextInt(availableServices.size());
        return availableServices.get(index);
    }

    private List<Server> getAvailableServices(List<Server> servers) {
        if (excludePorts == null || excludePorts.isEmpty()){
            return servers;
        }
        return servers.stream().filter(server -> excludePorts.stream().noneMatch(port->port==server.getPort())).collect(Collectors.toList());
    }

    @Override
    public void setLoadBalancer(ILoadBalancer iLoadBalancer) {
        this.ib = iLoadBalancer;
    }

    @Override
    public ILoadBalancer getLoadBalancer() {
        return this.ib;
    }
}


版权声明:本文为zhaoqian19921029原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。