SpringCloud Ribbon 부분 소스

8359 단어
1:ribbon은 서비스 Id를 통해 서비스에 접근하는 능력을 제공하고 부하 균형 능력을 제공한다.springcloud에는 로드 클래스 LoadBalancer AutoConfiguration 2개와 Ribbon AutoConfiguration이 자동으로 설정되어 있습니다.LoadBalancer AutoConfiguration은 주로 RestTemplate 대상에 대한 부하 균형 접근을 완성하고 Ribbon AutoConfiguration은 주로 Ribbon에 필요한 구성 요소에 대한 실례화입니다.스프링클라우드-common과 넷플릭스-core의 스프링.foctories 파일에
org.springframework.boot.autoconfigure.EnableAutoConfiguration=
org.springframework.cloud.netflix.hystrix.HystrixAutoConfiguration,
org.springframework.cloud.netflix.hystrix.security.HystrixSecurityAutoConfiguration,
org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration,
org.springframework.cloud.netflix.rx.RxJavaAutoConfiguration,

org.springframework.boot.autoconfigure.EnableAutoConfiguration=
org.springframework.cloud.client.CommonsClientAutoConfiguration,
org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration,
org.springframework.cloud.client.serviceregistry.ServiceRegistryAutoConfiguration, 

2:Ribbon Auto Configuration은 주로 리본 구성 요소에 대한 실례화이다. 그 대응 관계는 다음과 같다. IClient Config -->Default Client Config Implirule --> Zone AvoidanceRule IPing --> Dummy Ping Server List Server List Updater -->Polling Server List Updater -->Polling Server List Updater Iload Balancer --> Zone Aware Load Balancer Balancer --Balancer Lient Balancer Lient Balancer --와 동시에, Balancer Lalancer Balancer또한 작성됩니다: SpringClientFactory 객체.
3: LoadBalancer AutoConfiguration은 주로 RestTemplate에 대해 부하 균형을 맞추어 설정합니다.주로 차단기 LoadBalancerInterceptor를 생성합니다.그런 다음 다음과 같은 RestTemplate를 사용자 정의하여 구성합니다.
@Bean
    public SmartInitializingSingleton loadBalancedRestTemplateInitializer(
            final List customizers) {
        return new SmartInitializingSingleton() {
            @Override
            public void afterSingletonsInstantiated() {
                for (RestTemplate restTemplate : LoadBalancerAutoConfiguration.this.restTemplates) {
                    for (RestTemplateCustomizer customizer : customizers) {
                        customizer.customize(restTemplate);
                    }
                }
            }
        };
    }
@Configuration
    @ConditionalOnMissingClass("org.springframework.retry.support.RetryTemplate")
    static class LoadBalancerInterceptorConfig {
        @Bean
        public LoadBalancerInterceptor ribbonInterceptor(
                LoadBalancerClient loadBalancerClient,
                LoadBalancerRequestFactory requestFactory) {
            return new LoadBalancerInterceptor(loadBalancerClient, requestFactory);
        }

        @Bean
        @ConditionalOnMissingBean
        public RestTemplateCustomizer restTemplateCustomizer(
                final LoadBalancerInterceptor loadBalancerInterceptor) {
            return new RestTemplateCustomizer() {
                @Override
                public void customize(RestTemplate restTemplate) {
                    List list = new ArrayList<>(
                            restTemplate.getInterceptors());
                    list.add(loadBalancerInterceptor);
                    restTemplate.setInterceptors(list);
                }
            };
        }
    } 

위 코드에 추가된 차단기 클래스는 LoadBalancerInterceptor입니다.LoadBalancer 클라이언트 인터페이스의 실현 유형은 리본 LoadBalancer 클라이언트입니다.
4: RestTemplate를 사용하여 POST를 진행하고 GET 요청을 할 때 최종적으로 실행하는 방법은 다음과 같다. LoadBalancerInterceptor#intercept.이 방법에서 호출 방법:Ribbon LoadBalancer Client#execute(String, LoadBalancer Request)
@Override
    public ClientHttpResponse intercept(final HttpRequest request, final byte[] body,
            final ClientHttpRequestExecution execution) throws IOException {
        final URI originalUri = request.getURI();
        String serviceName = originalUri.getHost();
        Assert.state(serviceName != null, "Request URI does not contain a valid hostname: " + originalUri);
        return this.loadBalancer.execute(serviceName, requestFactory.createRequest(request, body, execution));
    } 

5:execute 방법에서 주로 부하 균형기를 얻고 서비스 제공자의 접근 경로를 얻으며 접근한다
@Override
    public  T execute(String serviceId, LoadBalancerRequest request) throws IOException {
        ILoadBalancer loadBalancer = getLoadBalancer(serviceId);  // 
        Server server = getServer(loadBalancer);  // , IP 
        if (server == null) {
            throw new IllegalStateException("No instances available for " + serviceId);
        }
        RibbonServer ribbonServer = new RibbonServer(serviceId, server, isSecure(server,
                serviceId), serverIntrospector(serviceId).getMetadata(server));

        return execute(serviceId, ribbonServer, request); // 
    } 

6:SpringClientFactory#getLoadBalancer에서 얻은 것은 인터페이스 IloadBalancer의 실례이다.그 실현은 Spring의 상하문 대상인 AnnotationConfigApplicationContext를 구성하고 설정 클래스를 불러오는 것입니다: RibbonClientConfiguration.Ribbon Client Configuration 클래스에서는 Zone Aware Load Balancer 대상을 실례화합니다.IloadBalancer의 단일 모드를 가져오면 메모리에 캐시됩니다.
public ILoadBalancer getLoadBalancer(String name) {
        return getInstance(name, ILoadBalancer.class);
    }

protected AnnotationConfigApplicationContext getContext(String name) {
        if (!this.contexts.containsKey(name)) {
            synchronized (this.contexts) {
                if (!this.contexts.containsKey(name)) {
                    this.contexts.put(name, createContext(name));
                }
            }
        }
        return this.contexts.get(name);
    }

@Bean
    @ConditionalOnMissingBean
    public ILoadBalancer ribbonLoadBalancer(IClientConfig config,
            ServerList serverList, ServerListFilter serverListFilter,
            IRule rule, IPing ping, ServerListUpdater serverListUpdater) {
        if (this.propertiesFactory.isSet(ILoadBalancer.class, name)) {
            return this.propertiesFactory.get(ILoadBalancer.class, config, name);
        }
        return new ZoneAwareLoadBalancer<>(config, rule, ping, serverList,
                serverListFilter, serverListUpdater);
    } 

7:Zone Aware Load Balancer는 Zone Avoidance Rule의 choose () 방법을 호출합니다.이 방법에서는 부하 균형기를 통해 모든 서비스 노드를 가져옵니다. (IRule 실례의 부하 균형기는 Zone Aware Load Balancer 실례화할 때 설정됩니다.)lb.getAllServers () 방법은 캐시 대상 allServerList를 가져옵니다.
@Override
    public Server choose(Object key) {
        ILoadBalancer lb = getLoadBalancer();
        Optional server = getPredicate().chooseRoundRobinAfterFiltering(lb.getAllServers(), key);
        if (server.isPresent()) {
            return server.get();
        } else {
            return null;
        }       
    } 

8: 서비스 목록을 가져오면 Zone AvoidanceRule 뒤에choose Round Robin After Filtering () 을 사용하여 서비스를 선택하고 코드에 따라 순환 알고리즘으로 서버를 선택합니다
public Optional chooseRoundRobinAfterFiltering(List servers, Object loadBalancerKey) {
        List eligible = getEligibleServers(servers, loadBalancerKey);
        if (eligible.size() == 0) {
            return Optional.absent();
        }
        return Optional.of(eligible.get(nextIndex.getAndIncrement() % eligible.size()));
    } 

9: Server 객체를 선택하면 액세스한 인스턴스의 IP 및 포트 정보가 표시됩니다.는 httpClient 객체를 사용하여 객체의 노드에 액세스합니다.코드는 다음과 같습니다.
public LoadBalancerRequest createRequest(final HttpRequest request,
            final byte[] body, final ClientHttpRequestExecution execution) {
        return new LoadBalancerRequest() {
            @Override
            public ClientHttpResponse apply(final ServiceInstance instance)
                    throws Exception {
                HttpRequest serviceRequest = new ServiceRequestWrapper(request, instance, loadBalancer);
                if (transformers != null) {
                    for (LoadBalancerRequestTransformer transformer : transformers) {
                        serviceRequest = transformer.transformRequest(serviceRequest, instance);
                    }
                }
                return execution.execute(serviceRequest, body);
            }

        };
    }

좋은 웹페이지 즐겨찾기