2020版本后使用loadbalancer
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; } }