Giriş
Açıklaması şöyle
Spring Cloud provides several ways to implement load balancing, including Ribbon, Spring Cloud Load Balancer, Spring Cloud Gateway, and Kubernetes Load Balancer.
Bu proje, WebClient ile client side load balancing yapmak içindir.
Maven
Şu satırı dahil ederiz
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-loadbalancer</artifactId></dependency>
LoadBalancerClientFactory Sınıfı
Örnek
Şöyle yaparız
@Bean public ReactorLoadBalancer<ServiceInstance> reactorServiceInstanceLoadBalancer( Environment environment, LoadBalancerClientFactory loadBalancerClientFactory) { String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME); return new RoundRobinLoadBalancer( loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name); }
@LoadBalancedAnotasyonu
@LoadBalancedAnotasyonu yazısına taşıdım
@LoadBalancerClient Anotasyonu
configuration Alanı
Load Balancing için iki gerçekleştirim var
1. RoundRobinLoadBalancer
2. RandomLoadBalancer
Örnek - RoundRobinLoadBalancer
Şöyle yaparız
import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClient; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.reactive.function.client.WebClient; @Configuration @LoadBalancerClient(name = WebClientConfig.CLIENT_NAME, configuration = IgniteLoadBalancerConfiguration.class) public class WebClientConfig { public static final String CLIENT_NAME = "client"; @Bean @LoadBalanced public WebClient.Builder usersClientBuilder() { return WebClient.builder() .defaultHeader("affinity-cache-name", "UserCache"); } }
Yardımcı kod şöyledir
@Configuration public class IgniteLoadBalancerConfiguration { public static final String SERVICE_ID = "example"; @Bean @Primary public ServiceInstanceListSupplier serviceInstanceListSupplier(IgniteEx ignite) { return new IgniteServiceInstanceListSuppler(ignite); } @Bean public ReactorLoadBalancer<ServiceInstance> reactorServiceInstanceLoadBalancer( Environment environment, LoadBalancerClientFactory loadBalancerClientFactory) { String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME); return new RoundRobinLoadBalancer( loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name); } }
Açıklaması şöyle
IgniteServiceInstanceListSuppler will return instances based on the request key.
Örnek
Elimizde şöyle bir kod olsun. locahhost üzerinde çalışan 4 tane port döndürür
@Bean public ReactiveDiscoveryClient customDiscoveryClient() { return new ReactiveDiscoveryClient() { @Override public String description() { return "Calling another API example"; } @Override public Flux<ServiceInstance> getInstances(String serviceId) { log.debug("getInstances: {}", serviceId); return Flux.just(8080, 8081, 8082) .map(port -> new DefaultServiceInstance(serviceId + "-" + port, serviceId, "localhost", port, false)); } @Override public Flux<String> getServices() { return Flux.just("ExampleApi"); } }; }
Açıklaması şöyle
Implement theReactiveDiscoveryClient . It allows us to return a list of instances that can be used when a specific call is triggered.
Şöyle yaparız
@Service public class AccountsService { private static final String API = "ExampleApi"; private final WebClient apiClient; public AccountsService(WebClient.Builder loadBalancedWebClientBuilder) { this.apiClient = loadBalancedWebClientBuilder .build(); } public Mono<String> login(String username) { return apiClient.post() .uri(uriBuilder -> uriBuilder .host(API) .path("/login") .build()) .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) .header("username", username) .exchangeToMono(r -> handleResponse(r)); } private Mono<String> handleResponse(ClientResponse r) { if (r.statusCode().is2xxSuccessful()) { return r.bodyToMono(String.class); } return r.bodyToMono(String.class) .switchIfEmpty(Mono.error(new IllegalStateException("Failed: " + r.statusCode()))) .flatMap(response -> Mono.error(new IllegalStateException("Failed: " + r.statusCode() + ", " + response))); } }
Hiç yorum yok:
Yorum Gönder