2020版本后使用loadbalancer

发布时间 2023-09-13 21:23:35作者: 此时不卷何时卷

1、导入依赖

如果使用了aliyun仓库找不到,可以在https://developer.aliyun.com/mvn/search查找

2、配置不要关掉

3、需要创建一个加载类,使用@LoadBalancerClient 不需要再这个类加配置的@Configuration

 返回的可以自定义一个类,ReactorServiceInstanceLoadBalancer继承了ReactorLoadBalancer<ServiceInstance>,所以实现ReactorServiceInstanceLoadBalancer接口,可以参照

 配置类:

public class CustomLoadBalancerConfiguration {

    @Bean
    ReactorLoadBalancer<ServiceInstance> MyLoadBalancer(Environment environment,
                                                            LoadBalancerClientFactory loadBalancerClientFactory) {
        String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
        return new MyLoadBalancer(loadBalancerClientFactory
                .getLazyProvider(name, ServiceInstanceListSupplier.class),
                name);
    }

}

自定义规则,仿照的轮询:

public class MyLoadBalancer implements ReactorServiceInstanceLoadBalancer {

    private static final Log log = LogFactory.getLog(RoundRobinLoadBalancer.class);

    final AtomicInteger position;

    final String serviceId;

    private static int count = 0;

    private static Response<ServiceInstance> myService = null;

    ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider;

    public MyLoadBalancer(ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider,
                          String serviceId) {
        this(serviceInstanceListSupplierProvider, serviceId, new Random().nextInt(1000));
    }

    public MyLoadBalancer(ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider,
                          String serviceId, int seedPosition) {
        this.serviceId = serviceId;
        this.serviceInstanceListSupplierProvider = serviceInstanceListSupplierProvider;
        this.position = new AtomicInteger(seedPosition);
    }

    @Override
    public Mono<Response<ServiceInstance>> choose(Request request) {
        ServiceInstanceListSupplier supplier = serviceInstanceListSupplierProvider
                .getIfAvailable(NoopServiceInstanceListSupplier::new);
        return supplier.get(request).next()
                .map(serviceInstances -> processInstanceResponse(supplier, serviceInstances));
    }

    private Response<ServiceInstance> processInstanceResponse(ServiceInstanceListSupplier supplier,
                                                              List<ServiceInstance> serviceInstances) {
        if (myService != null && count<= 4){
            count++;
            return myService;
        }

        Response<ServiceInstance> serviceInstanceResponse = getInstanceResponse(serviceInstances);
        if (supplier instanceof SelectedInstanceCallback && serviceInstanceResponse.hasServer()) {
            ((SelectedInstanceCallback) supplier).selectedServiceInstance(serviceInstanceResponse.getServer());
        }
        myService = serviceInstanceResponse;
        if (count > 4) {
            count = 0;
        }
        return serviceInstanceResponse;
    }

    private Response<ServiceInstance> getInstanceResponse(List<ServiceInstance> instances) {
        if (instances.isEmpty()) {
            if (log.isWarnEnabled()) {
                log.warn("No servers available for service: " + serviceId);
            }
            return new EmptyResponse();
        }

        if (instances.size() == 1) {
            return new DefaultResponse(instances.get(0));
        }

        int pos = this.position.incrementAndGet() & Integer.MAX_VALUE;

        ServiceInstance instance = instances.get(pos % instances.size());
        return new DefaultResponse(instance);
    }

}

4、负载均衡配置:

 

@Configuration
@LoadBalancerClient(name = "CLOUD-PAYMENT-SERVER", configuration = CustomLoadBalancerConfiguration.class)
public class ApplicationContextConfig {

    @Bean
    @LoadBalanced
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }

}

5、使用:

@RestController
@Slf4j
@RequestMapping("/consumer")
public class OrderController {

    private RestTemplate restTemplate;

    private static final String URI = "http://CLOUD-PAYMENT-SERVER";

    @PostMapping("/payment/create")
    public Response create(@RequestBody Payment payment){
        log.info("=====开始创建=====");
        return restTemplate.postForObject(URI+"/payment/create", payment, Response.class);
    }

    @GetMapping("/payment/{id}")
    public Response<Payment> getById(@PathVariable("id") Long id){
        log.info("=====开始查询=====");
        return restTemplate.getForObject(URI+"/payment/"+id, Response.class);
    }

    @Autowired
    public void setRestTemplate(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }
}