Spring Cloud Document翻譯(二)--Spring Cloud Commons

原文鏈接:https://cloud.spring.io/spring-cloud-static/Greenwich.SR2/multi/multi__spring_cloud_commons_common_abstractions.html

3. Spring Cloud Commons:共通的抽象

服務發現,負載平衡和斷路器等模式是所有Spring Cloud客戶端可以使用的公共抽象層,與實現無關(例如,使用Eureka或Consul進行發現)。

3.1 @EnableDiscoveryClient

Spring Cloud Commons提供了@EnableDiscoveryClient註解。這將用META-INF/spring.factories查找DiscoveryClient接口的實現。Discovery Client的實現在spring.factories的org.springframework.cloud.client.discovery.EnableDiscoveryClient key下添加一個配置類。DiscoveryClient實現的例子包括Spring Cloud Netflix EurekaSpring Cloud Consul DiscoverySpring Cloud Zookeeper Discovery

默認情況下,DiscoveryClient的實現類使用遠程發現服務器自動註冊本地Spring Boot服務器。這種行爲可以通過在@EnableDiscoveryClient設置autoRegister=false被禁用。

[注意]

@EnableDiscoveryClient不再必要。您可以在類路徑上放置一個DiscoveryClient實現,以使Spring Boot應用程序向服務發現服務器註冊。

3.1.1 健康指示

Commons創建了一個Spring Boot HealthIndicatorDiscoveryClient實現可以通過實現DiscoveryHealthIndicator參與。要禁用複合HealthIndicator,請設置spring.cloud.discovery.client.composite-indicator.enabled=false。一個基本的基於DiscoveryClient的HealthIndicator會被自動配置(DiscoveryClientHealthIndicator)。要禁用它,請設置spring.cloud.discovery.client.health-indicator.enabled=false。要禁用DiscoveryClientHealthIndicator的描述字段,請設置spring.cloud.discovery.client.health-indicator.include-description=false。否則,它會在rolled up HealthIndicator中冒出來描述。

3.1.2 給DiscoveryClient實例排序

DiscoveryClient接口擴展Ordered。這在使用多個DiscoveryClient時很有用,因爲它允許您定義返回的DiscoveryClient的順序,類似於您可以如何排序Spring應用程序加載的bean。默認情況下,任意DiscoveryClient設置的順序爲 0。如果要爲自定義DiscoveryClient實現設置不同的順序,則只需覆蓋該getOrder()方法,以便返回適合您的設置的值。除了這個,你可以使用屬性來設置Spring Cloud提供的DiscoveryClient實現的順序,如ConsulDiscoveryClientEurekaDiscoveryClient和 ZookeeperDiscoveryClient。爲此,您只需將spring.cloud.{clientIdentifier}.discovery.order(或爲Eureka設置eureka.client.order)屬性設置爲所需的值即可。

3.2 ServiceRegistry

Commons現在提供了一個ServiceRegistry接口,它提供諸如register(Registration)deregister(Registration),它允許您提供自定義註冊服務。 Registration是一個標記接口。

以下示例顯示ServiceRegistry正在使用中:

@Configuration
@EnableDiscoveryClient(autoRegister=false)
public class MyConfiguration {
    private ServiceRegistry registry;

    public MyConfiguration(ServiceRegistry registry) {
        this.registry = registry;
    }

    // called through some external process, such as an event or a custom actuator endpoint
    public void register() {
        Registration registration = constructRegistration();
        this.registry.register(registration);
    }
}

每個ServiceRegistry實現都有自己的Registry實現。

  • ZookeeperRegistration 用於 ZookeeperServiceRegistry
  • EurekaRegistration 用於 EurekaServiceRegistry
  • ConsulRegistration 用於 ConsulServiceRegistry

如果您正在使用ServiceRegistry接口,則需要爲正在使用的ServiceRegistry實現傳遞正確的Registry實現。

3.2.1 ServiceRegistry自動註冊

默認情況下,ServiceRegistry實現會自動註冊正在運行的服務。要禁用該行爲,您可以設置:* @EnableDiscoveryClient(autoRegister=false)永久禁用自動註冊。* spring.cloud.service-registry.auto-registration.enabled=false通過配置禁用行爲。

ServiceRegistry自動註冊事件

當服務自動註冊時,將觸發兩個事件。名爲InstancePreRegisteredEvent的第一個事件 在註冊服務之前被觸發。第二個事件叫做InstanceRegisteredEvent,在服務註冊後被觸發。您可以註冊一個 ApplicationListener(s)來收聽並回應這些事件。

[注意]

如果spring.cloud.service-registry.auto-registration.enabled設置爲,則不會觸發這些事件false

3.2.2 服務註冊Actuator端點(Service Registry Actuator Endpoint)

Spring Cloud Commons提供/service-registry執行器端點。此端點依賴於Registration bean,它處於Spring Application Context中。/service-registry使用GET 調用返回Registration的狀態。將POST用於具有JSON主體的同一端點會將當前狀態更改Registration爲新值。JSON主體必須包含status具有首選值的字段。ServiceRegistry更新狀態和爲狀態返回的值時,請參閱您用於允許值的實現的文檔。例如,Eureka支持的狀態是UPDOWNOUT_OF_SERVICE,和UNKNOWN

 

3.3 Spring RestTemplate作爲負載均衡器客戶端

RestTemplate可以自動配置爲使用ribbon。要創建負載均衡的RestTemplate,請創建RestTemplate @Bean並使用@LoadBalanced限定符,如以下示例所示。

@Configuration
public class MyConfiguration {

    @LoadBalanced
    @Bean
    RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

public class MyClass {
    @Autowired
    private RestTemplate restTemplate;

    public String doOtherStuff() {
        String results = restTemplate.getForObject("http://stores/stores", String.class);
        return results;
    }
}
  警告

RestTemplate bean不再通過自動配置創建。應用程序必須自己創建它。

URI需要使用虛擬主機名(即服務名稱,而不是主機名)。Ribbon客戶端用於創建完整的物理地址。有關如何設置RestTemplate的詳細信息,請參見RibbonAutoConfiguration

3.4 Spring WebClient作爲負載均衡器客戶端

WebClient可以自動配置使用LoadBalancerClient。要創建負載平衡WebClient,請創建WebClient.Builder @Bean並使用@LoadBalanced限定符,如以下示例所示:

@Configuration
public class MyConfiguration {

	@Bean
	@LoadBalanced
	public WebClient.Builder loadBalancedWebClientBuilder() {
		return WebClient.builder();
	}
}

public class MyClass {
    @Autowired
    private WebClient.Builder webClientBuilder;

    public Mono<String> doOtherStuff() {
        return webClientBuilder.build().get().uri("http://stores/stores")
        				.retrieve().bodyToMono(String.class);
    }
}

URI需要使用虛擬主機名(即服務名稱,而不是主機名)。Ribbon客戶端用於創建完整的物理地址。

3.4.1重試失敗的請求

負載均衡的RestTemplate可以被配置爲重試失敗的請求。默認情況下,此邏輯被禁用。您可以通過添加Spring Retry到應用程序的類路徑來啓用它。負載平衡RestTemplate擁有一些與重試失敗請求相關的Ribbon配置值。您可以使用client.ribbon.MaxAutoRetriesclient.ribbon.MaxAutoRetriesNextServerclient.ribbon.OkToRetryOnAllOperations屬性。如果要在類路徑上使用Spring Retry禁用重試邏輯,則可以設置spring.cloud.loadbalancer.retry.enabled=false。有關這些屬性的說明,請參閱Ribbon文檔

如果要在重試中實現BackOffPolicy,則需要創建 LoadBalancedRetryFactory類型的bean並覆蓋該createBackOffPolicy方法:

Configuration
public class MyConfiguration {
    @Bean
    LoadBalancedRetryFactory retryFactory() {
        return new LoadBalancedRetryFactory() {
            @Override
            public BackOffPolicy createBackOffPolicy(String service) {
        		return new ExponentialBackOffPolicy();
        	}
        };
    }
}
[注意]

在上面的示例中的client,應被替換爲你的Ribbon客戶端的名稱。

如果要爲重試功能中添加一個或多個RetryListener實現,則需要創建一個LoadBalancedRetryListenerFactory類型的bean 並返回用於給定服務的RetryListener數組,如以下示例所示:

@Configuration
public class MyConfiguration {
    @Bean
    LoadBalancedRetryListenerFactory retryListenerFactory() {
        return new LoadBalancedRetryListenerFactory() {
            @Override
            public RetryListener[] createRetryListeners(String service) {
                return new RetryListener[]{new RetryListener() {
                    @Override
                    public <T, E extends Throwable> boolean open(RetryContext context, RetryCallback<T, E> callback) {
                        //TODO Do you business...
                        return true;
                    }

                    @Override
                     public <T, E extends Throwable> void close(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {
                        //TODO Do you business...
                    }

                    @Override
                    public <T, E extends Throwable> void onError(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {
                        //TODO Do you business...
                    }
                }};
            }
        };
    }
}

3.5 多個RestTemplate對象

如果你想要一個不負載平衡的RestTemplate,創建一個RestTemplatebean並注入它。要訪問負載平衡的RestTemplate,請在創建@Bean時使用限定符@LoadBalanced,如以下示例所示:

@Configuration
public class MyConfiguration {

    @LoadBalanced
    @Bean
    RestTemplate loadBalanced() {
        return new RestTemplate();
    }

    @Primary
    @Bean
    RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

public class MyClass {
    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    @LoadBalanced
    private RestTemplate loadBalanced;

    public String doOtherStuff() {
        return loadBalanced.getForObject("http://stores/stores", String.class);
    }

    public String doStuff() {
        return restTemplate.getForObject("https://example.com", String.class);
    }
}
[重要] 重要

請注意在前面示例中給簡單RestTemplate聲明使用@Primary註解,用來消除@Autowired注入產生的歧義。

[Tip]

如果您看到錯誤java.lang.IllegalArgumentException: Can not set org.springframework.web.client.RestTemplate field com.my.app.Foo.restTemplate to com.sun.proxy.$Proxy89,請嘗試注入RestOperations或設置spring.aop.proxyTargetClass=true

3.6 Spring WebFlux WebClient作爲負載均衡器客戶端

WebClient可以配置爲使用LoadBalancerClient。如果spring-webflux在類路徑上,LoadBalancerExchangeFilterFunction將被自動配置。以下示例顯示如何配置一個WebClient以使用負載均衡器:

public class MyClass {
    @Autowired
    private LoadBalancerExchangeFilterFunction lbFunction;

    public Mono<String> doOtherStuff() {
        return WebClient.builder().baseUrl("http://stores")
            .filter(lbFunction)
            .build()
            .get()
            .uri("/stores")
            .retrieve()
            .bodyToMono(String.class);
    }
}

URI需要使用虛擬主機名(即服務名稱,而不是主機名)。將LoadBalancerClient用於創建一個完整的物理地址。

3.7忽略網絡接口

有時,忽略某些名稱的網絡接口以便從服務發現註冊中排除它們(例如,在Docker容器中運行時)是有用的。可以設置一個正則表達式列表以使所需的網絡接口被忽略。以下配置忽略docker0接口和所有以veth開頭的接口:

application.yml。 

spring:
  cloud:
    inetutils:
      ignoredInterfaces:
        - docker0
        - veth.*

您還可以使用正則表達式列表強制僅使用指定的網絡地址,如以下示例所示:

bootstrap.yml。 

spring:
  cloud:
    inetutils:
      preferredNetworks:
        - 192.168
        - 10.0

您還可以強制僅使用站點本地地址,如以下示例所示:.application.yml

spring:
  cloud:
    inetutils:
      useOnlySiteLocalInterfaces: true

有關構成站點本地地址的更多詳細信息,請參閱Inet4Address.html.isSiteLocalAddress()

3.8 HTTP客戶端工廠

Spring Cloud Commons提供了用於創建Apache HTTP客戶端(ApacheHttpClientFactory)和OK HTTP客戶端(OkHttpClientFactory)的bean 。僅當OK HTTP jar在classpath中OkHttpClientFactory才能被創建。此外,Spring Cloud Commons提供了用於創建兩個客戶端使用的連接管理器的bean:

   ApacheHttpClientConnectionManagerFactory 用於Apache HTTP客戶端

   OkHttpClientConnectionPoolFactory 用於OK HTTP客戶端。

如果要自定義在下游項目中創建HTTP客戶端的方式,可以提供自己的這些bean的實現。此外,如果您提供HttpClientBuilderOkHttpClient.Builder類型的Bean,默認的工廠使用這些Builder作爲Builder的基礎返回給下游項目。您還可以通過設置spring.cloud.httpclientfactories.apache.enabledspring.cloud.httpclientfactories.ok.enabled爲false,來禁用這些bean的創建。

3.9啓用特性

Spring Cloud Commons提供/features actuator端點。此端點返回類路徑上可用的功能以及它們是否已啓用。返回的信息包括功能類型,名稱,版本和供應商。

3.9.1特性類型

有兩種類型的'特性':抽象和命名。

抽象特性是指接口或抽象類的定義以及它們的一個實現,例如DiscoveryClientLoadBalancerClient,或LockService。抽象類或接口用於在上下文中查找該類型的bean。下面的代碼可以顯示版本。bean.getClass().getPackage().getImplementationVersion()

命名特性是指一些沒有特定實現類的特性,例如“斷路器”,“API網關”,“Spring Cloud Bus”等。這些功能需要一個名稱和bean類型。

3.9.2聲明特性

任何模塊都可以聲明任意數量的HasFeature bean,如以下示例所示:

@Bean
public HasFeatures commonsFeatures() {
  return HasFeatures.abstractFeatures(DiscoveryClient.class, LoadBalancerClient.class);
}

@Bean
public HasFeatures consulFeatures() {
  return HasFeatures.namedFeatures(
    new NamedFeature("Spring Cloud Bus", ConsulBusAutoConfiguration.class),
    new NamedFeature("Circuit Breaker", HystrixCommandAspect.class));
}

@Bean
HasFeatures localFeatures() {
  return HasFeatures.builder()
      .abstractFeature(Foo.class)
      .namedFeature(new NamedFeature("Bar Feature", Bar.class))
      .abstractFeature(Baz.class)
      .build();
}

這些Bean中的每一個都應該得到@Configuration適當的保護。

3.10 Spring Cloud兼容性驗證

由於某些用戶在創建Spring Cloud應用程序時遇到問題,我們決定添加兼容性驗證機制。如果您當前的設置與Spring Cloud的要求不兼容,它將會中斷,並且報告出現了什麼問題,。

目前我們驗證哪個版本的Spring Boot被添加到您的類路徑中。

報告示例

***************************
APPLICATION FAILED TO START
***************************

Description:

Your project setup is incompatible with our requirements due to following reasons:

- Spring Boot [2.1.0.RELEASE] is not compatible with this Spring Cloud release train


Action:

Consider applying the following actions:

- Change Spring Boot version to one of the following versions [1.2.x, 1.3.x] .
You can find the latest Spring Boot versions here [https://spring.io/projects/spring-boot#learn].
If you want to learn more about the Spring Cloud Release train compatibility, you can visit this page [https://spring.io/projects/spring-cloud#overview] and check the [Release Trains] section.

要禁用此功能,請設置spring.cloud.compatibility-verifier.enabledfalse。如果要覆蓋兼容的Spring Boot版本,只需使用逗號分隔的兼容Spring Boot版本的列表設置該spring.cloud.compatibility-verifier.compatible-boot-versions屬性即可。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章