002-Spring Cloud 功能簡介

1、主要功能

  分佈式/版本化配置、服務註冊與發現、路由、服務間調用、負載均衡、斷路器、分佈式消息傳遞html

一、雲本地應用【Cloud Native Applications】

  Spring Cloud Context  上下文和Spring Cloud Commons。Spring Cloud Context爲Spring Cloud應用程序的ApplicationContext(引導上下文、加密、刷新範圍和環境端點)提供實用程序和特殊服務。Spring Cloud Commons是不一樣的Spring Cloud實現的一套抽象和公共類集合(好比Spring Cloud Netflix和Spring Cloud Consul)。java

注意:若是因爲「非法密鑰大小Illegal key size」而得到異常,而且使用Sun的JDK,則須要安裝Java加密擴展(JCE)無限強度管轄權策略文件。:git

  不管JRE/JDK x64/x86版本,請放置在JDK/jre/lib/securitygithub

github地址:https://github.com/spring-cloudweb

1.一、Spring雲上下文:應用上下文服務

1.1.一、The Bootstrap Application Context【引導上下文】

  用於應用程序上下文的引導階段。它一般用於「使用Spring Cloud Config Server時,應在bootstrap.yml中指定spring.application.name和spring.cloud.config.server.git.uri」以及一些加密/解密信息。技術上,bootstrap.yml由父Spring ApplicationContext加載。父ApplicationContext被加載到使用application.yml的以前。spring

  例如,當使用Spring Cloud時,一般從服務器加載「real」配置數據。爲了獲取URL(和其餘鏈接配置,如密碼等),您須要一個較早的或「bootstrap」配置。所以,您將配置服務器屬性放在bootstrap.yml中,該屬性用於加載實際配置數據(一般覆蓋application.yml [若是存在]中的內容)。數據庫

  bootstrap.yml(bootstrap.properties)用來程序引導時執行,應用於更加早期配置信息讀取,如可使用來配置application.yml中使用到參數等bootstrap

  application.yml(application.properties) 應用程序特有配置信息,能夠用來配置後續各個模塊中需使用的公共參數等。api

  bootstrap.yml 先於 application.yml 加載數組

spring: application: name: foo cloud: config: uri: ${SPRING_CONFIG_URI:http://localhost:8888}

  您能夠經過設置spring.cloud.bootstrap.enabled=false(例如在系統屬性中)來徹底禁用引導過程。

1.1.二、Application Context Hierarchies【應用上下文層次結構】

  若是您從SpringApplication或SpringApplicationBuilder構建應用程序上下文,則將Bootstrap上下文添加爲該上下文的父級。

  這是一個Spring的功能,即子上下文從其父進程繼承屬性源和配置文件,所以與不使用Spring Cloud Config構建相同上下文相比,「主」應用程序上下文將包含其餘屬性源。額外的屬性來源是:

  「bootstrap」:若是在Bootstrap上下文中找到任何PropertySourceLocators,則可選CompositePropertySource顯示爲高優先級,而且具備非空屬性。

  一個例子是來自Spring Cloud Config服務器的屬性。

    「applicationConfig:[classpath:bootstrap.yml]」(若是Spring配置文件處於活動狀態,則爲朋友)。若是您有一個bootstrap.yml(或屬性),那麼這些屬性用於配置引導上下文,而後在父進程設置時將它們添加到子上下文中。它們的優先級低於application.yml(或.properties)以及做爲建立Spring Boot應用程序的過程的正常部分添加到子級的任何其餘屬性源。

  因爲屬性源的排序規則,「bootstrap」條目優先,但請注意,這些條目不包含來自bootstrap.yml的任何數據,它具備很是低的優先級,但可用於設置默認值。

  說明:

    bootstrap.yml  和application.yml  均可以用來配置參數

    bootstrap.yml能夠理解成系統級別的一些參數配置,這些參數通常是不會變更的(Spring cloud)

    application.yml 能夠用來定義應用級別的,若是搭配spring-cloud-config使用 application.yml裏面定義的文件能夠實現動態替換

   您能夠經過簡單地設置您建立的任何ApplicationContext的父上下文來擴展上下文層次結構,例如使用本身的界面,或使用SpringApplicationBuilder方便方法(parent(),child()和sibling())。

  說明:

    若是SpringApplication沒法知足要求,你能夠本身建立一個局部實例,而後對其進行設置:

public static void main(String[] args) { SpringApplication app = new SpringApplication(MySpringConfiguration.class); //關閉Banner打印
 app.setBannerMode(Banner.Mode.OFF); //添加監聽器 
    app.addListeners(new MyListener()); //... 
 app.run(args); }

    SpringApplication的相關配置將會被@Configuration註解的類,XML配置文件,以及Spring掃描的包引用。

    你也能夠經過SpringApplicationBuilder來對SpringApplication的屬性進行配置,這樣的結構更有層次感。SpringApplicationBuilder爲構 建 SpringApplication 和 ApplicationContext 實例提供了一套便利的流式API:

new SpringApplicationBuilder() .sources(Parent.class) .child(Application.class) .bannerMode(Banner.Mode.OFF) .listeners(new MyListener()) ... .run(args);

    SpringApplication將會根據須要建立一個ApplicationContext,默認狀況下,若是是非web應用,則會建立一個AnnotationConfigApplicationContext上下文,若是是web應用,則會建立一個AnnotationConfigEmbeddedWebApplicationContext上下文。固然,你也能夠經過setWebEnvironment(boolean webEnvironment)來覆蓋默認的設置。

  引導環境將是您建立本身的最高級祖先的父級。層次結構中的每一個上下文都將有本身的「bootstrap」屬性源(可能爲空),以免無心中將值從父級升級到其後代。層次結構中的每一個上下文(原則上)也能夠具備不一樣的spring.application.name,所以若是存在配置服務器,則不一樣的遠程屬性源。

  普通的Spring應用程序上下文行爲規則適用於屬性解析:子環境中的屬性經過名稱和屬性源名稱覆蓋父項中的屬性(若是子級具備與父級名稱相同的屬性源,一個來自父母的孩子不包括在孩子中)。

  請注意,SpringApplicationBuilder容許您在整個層次結構中共享Environment,但這不是默認值。所以,尤爲不須要具備相同的資料或財產來源,儘管它們與父級共享共同點。

1.1.三、Changing the Location of Bootstrap Properties(改變引導位置Properties)

  可使用spring.cloud.bootstrap.name(默認「bootstrap」)或spring.cloud.bootstrap.location(默認爲空)指定bootstrap.yml(或.properties)位置,例如在系統屬性中。這些屬性的行爲相似於具備相同名稱的spring.config.*變體,實際上它們用於經過在其Environment中設置這些屬性來設置引導ApplicationContext。若是在正在構建的上下文中有活動的配置文件(來自spring.profiles.active或經過Environment API)),則該配置文件中的屬性也將被加載,就像常規的Spring Boot應用程序,例如來自bootstrap-development.properties的「develop」配置,根據不一樣的環境配置不一樣的字段屬性。

1.1.四、重寫Remote Properties的值

  經過引導上下文添加到應用程序中的屬性源一般是「遠程」的(例如來自SpringCloudConfig Server)。默認狀況下,它們不能在本地被重寫。若是您想讓應用程序使用本身的系統屬性或配置文件覆蓋遠程屬性,則遠程屬性源必須經過設置Spring.Cloud.config.發給它權限(它不能在本地設置此屬性)來授予它權限。設置該標誌後,兩個更細粒度的設置根據系統屬性和應用程序的本地配置控制遠程屬性的位置:Spring.Cloud.config.overrideNone=true:spring.cloud.config.overrideSystemProperties=false:只覆蓋系統屬性、命令行參數和環境變量(而不是本地配置文件)。

1.1.五、Customizing the Bootstrap Configuration(自定義引導配置)

  能夠經過在org.springframework.cloud.bootstrap.BootstrapConfiguration鍵下添加條目/META-INF/spring.factories來訓練引導上下文來執行任何您喜歡的操做。這是用於建立上下文的Spring @Configuration類的逗號分隔列表。您能夠在此處建立要用於自動裝配的主應用程序上下文的任何bean,而且還有ApplicationContextInitializer類型的@Beans的特殊合同。若是要控制啓動順序(默認順序爲「最後」),可使用@Order標記類。

警告
  添加自定義BootstrapConfiguration時,請注意,添加的類不在@ComponentScanned掃描您的「主」應用程序上下文中或@SpringBootApplication註釋配置類還沒有涵蓋的啓動配置類,請使用單獨的包名稱。
  @SpringBootApplication(scanBasePackages = {"com.o2b","com.o2c"})

  引導過程經過將初始化器注入主SpringApplication實例(即正常的Spring Boot啓動順序,不管是做爲獨立應用程序運行仍是部署在應用程序服務器中)結束。首先,從spring.factories中找到的類建立引導上下文,而後在ApplicationContextInitializer類型的全部@Beans添加到主SpringApplication開始以前

1.1.六、Customizing the Bootstrap Property Sources(自定義引導屬性源)

  引導過程添加的外部配置的默認屬性源是Config Server,但您能夠經過將PropertySourceLocator類型的bean添加到引導上下文(經過spring.factories)添加其餘源。您可使用此方法從其餘服務器或數據庫中插入其餘屬性。
  做爲一個例子,請考慮如下自定義定位器:

@Configuration public class CustomPropertySourceLocator implements PropertySourceLocator { @Override public PropertySource<?> locate(Environment environment) { return new MapPropertySource("customProperty", Collections.<String, Object>singletonMap("property.from.sample.custom.source", "worked as intended")); } }

  傳入的Environment是要建立的ApplicationContext的Environment,即爲咱們提供額外的屬性來源的。它將已經具備正常的Spring Boot提供的資源來源,所以您可使用它們來定位特定於此Environment的屬性源(例如經過將其綁定在spring.application.name上,如在默認狀況下所作的那樣Config Server屬性源定位器)。

  若是你在這個類中建立一個jar,而後添加一個META-INF/spring.factories包含:

  org.springframework.cloud.bootstrap.BootstrapConfiguration=sample.custom.CustomPropertySourceLocator 那麼「customProperty」PropertySource將顯示在其類路徑中包含該jar的任何應用程序中。

1.1.七、Logging Configuration【日誌配置】

  若是您打算使用SpringBoot來配置日誌設置,則應該將此配置放在‘bootstrap.[yml\properties]中,若是您但願將其應用於全部事件。

  [注意]若是SpringCloud要正確初始化日誌配置,就不能使用自定義前綴。例如,當初始化日誌系統時,使用custom.loggin.logpath將不會被SpringCloud識別。

1.1.八、環境變化

  應用程序將監聽EnvironmentChangeEvent,並以幾種標準方式進行更改(用戶能夠正常方式以@bean的形式添加附加的ApplicationListener)。當觀察到EnvironmentChangeEvent時,它將有一個已更改的鍵值列表,應用程序將使用如下內容:
    從新綁定上下文中的任何@ConfigurationProperties bean
    爲logging.level.*中的任何屬性設置記錄器級別

  請注意,配置客戶端不會經過默認輪詢查找Environment中的更改,一般咱們不建議檢測更改的方法(儘管可使用@Scheduled註釋進行設置)。若是您有一個擴展的客戶端應用程序,那麼最好將EnvironmentChangeEvent廣播到全部實例,而不是讓它們輪詢更改(例如使用Spring Cloud總線)。

  EnvironmentChangeEvent涵蓋了大量的刷新用例,只要您真的能夠更改Environment併發布事件(這些API是公開的,部份內核爲Spring)。您能夠經過訪問/configprops端點(普通Spring Boot執行器功能)來驗證更改是否綁定到@ConfigurationProperties bean。例如,DataSource能夠在運行時更改其maxPoolSize(由Spring Boot建立的默認DataSource是一個@ConfigurationProperties bean),而且動態增長容量。從新綁定@ConfigurationProperties不會覆蓋另外一大類用例,您須要更多的控制刷新,而且您須要更改在整個ApplicationContext上是原子的。爲了解決這些擔心,咱們有@RefreshScope。

1.1.九、刷新做用域

  當發生配置更改時,標記爲@RefreshScope的Spring@Bean將獲得特殊待遇。這個特性解決了有狀態bean的問題,只有在初始化它們時纔會注入它們的配置。例如,當經過環境更改數據庫URL時,若是DataSource具備打開的鏈接,您可能但願這些鏈接的持有者可以完成他們正在作的事情。而後,當某物下一次從池中借用一個鏈接時,它會獲得一個帶有新URL的鏈接。

  有時,在某些只能初始化一次的bean上應用@RefreshScope註釋甚至是強制性的。若是一個bean是「不可變的」,那麼您必須用@RefreshScope對bean進行註釋,或者在屬性鍵Spring.Cloud.刷新.額外刷新項下指定類名。

  刷新做用域bean是在使用時(即調用方法時)初始化的惰性代理,該做用域充當初始化值的緩存。若要強制bean在下一個方法調用中從新初始化,您必須使其緩存條目失效。

  RefreshScope是上下文中的bean,並具備一個經過清除目標緩存來刷新做用域中全部bean的公共REFERHAll()方法。/REFRESH端點公開此功能(經過HTTP或JMX)。要按名稱刷新單個bean,還須要一個REFRESH(String)方法。

要展開 /refresh 節點須要增長配置

management: endpoints: web: exposure: include: refresh

  注意:@RefreshScope(技術上)適用於@Configuration類,但它可能會致使使人驚訝的行爲。例如,這並不意味着該類中定義的全部@bean都在@RefreshScope中。具體來講,任何依賴於這些bean的東西都不能依賴它們在啓動刷新時被更新,除非它自己在@RefreshScope中。在這種狀況下,它是在刷新時重建的,而且它的依賴項被從新注入。此時,它們將從刷新的@配置中從新初始化)。

1.1.十、加密與解密

Spring Cloud有一個用於本地解密屬性值的環境預處理器。它遵循與配置服務器相同的規則,經過encrypt.*具備相同的外部配置。所以,您能夠以{cipher}*的形式使用加密的值,只要有一個有效的密鑰,它們就會在主應用程序上下文得到環境設置以前被解密。要在應用程序中使用加密特性,您須要在類路徑中包含Spring Security RSA (Maven座標:「org.springframework.security: Spring - Security - RSA」),而且您還須要在JVM中包含完整的JCE擴展。  

1.1.十一、管理點

對於Spring引導執行器應用程序,可使用一些額外的管理端點。您可使用:

  • POST to /actuator/env to update the Environment and rebind @ConfigurationProperties and log levels.
  • /actuator/refresh to re-load the boot strap context and refresh the @RefreshScope beans.
  • /actuator/restart to close the ApplicationContext and restart it (disabled by default).
  • /actuator/pause and /actuator/resume for calling the Lifecycle methods (stop() and start() on the ApplicationContext).

If you disable the /actuator/restart endpoint then the /actuator/pause and /actuator/resume endpoints will also be disabled since they are just a special case of /actuator/restart.

1.二、Spring Cloud Commons: Common Abstractions

  服務發現、負載平衡和斷路器等模式將本身提供給一個公共的抽象層,該抽象層能夠由全部Spring cloud clients使用,而不依賴於實現(例如,使用Eureka或Consul 服務發現)。

1.2.一、@EnableDiscoveryClient

  Spring Cloud Commons提供了@EnableDiscoveryClient註解。這是使用META-INF/spring.factories查找DiscoveryClient接口的實現。添加一個實現org.springframework.cloud.client.discovery.EnableDiscoveryClien的配置類t到spring.factories下。DiscoveryClient實現的例子包括Spring Cloud Netflix Eureka、Spring Cloud Consul Discovery和Spring Cloud Zookeeper Discovery。

  默認狀況下,DiscoveryClient的實現會使用遠程發現服務器自動註冊本地Spring引導服務器。經過在@EnableDiscoveryClient中設置autoRegister=false,能夠禁用此行爲。

  再也不須要@EnableDiscoveryClient。您能夠將DiscoveryClient實現放到classpath中,以使Spring引導應用程序註冊到服務發現服務器。

1.2.二、服務註冊

示例

@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); } }

註冊接口:

  • ZookeeperRegistration used with ZookeeperServiceRegistry
  • EurekaRegistration used with EurekaServiceRegistry
  • ConsulRegistration used with ConsulServiceRegistry

若是您正在使用ServiceRegistry接口,則須要爲您正在使用的ServiceRegistry實現傳遞正確的註冊表實現。  

1.2.2.一、服務自動註冊

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

1.2.2.二、服務註冊執行點

  Spring Cloud Commons提供了一個/service-registry執行器端點。這個端點依賴於Spring應用程序上下文中的註冊bean。帶有GET的調用/service registry返回註冊狀態。使用POST到與JSON主體相同的端點會將當前註冊的狀態更改成新值。JSON主體必須包含具備首選值的狀態字段。請參閱在更新狀態和爲狀態返回值時爲容許值使用的ServiceRegistry實現的文檔。例如,Eureka支持的狀態是UP、DOWN、OUT_OF_SERVICE和UNKNOWN。

1.2.三、Spring RestTemplate as a Load Balancer Client

  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客戶端用於建立完整的物理地址。

1.2.四、Spring WebClient as a Load Balancer Client

  能夠自動配置WebClient來使用loadbalancercerclient。要建立負載均衡的WebClient,請建立WebClient。構建器@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客戶端用於建立完整的物理地址。

1.2.4.一、重試失敗請求

  能夠配置負載平衡的RestTemplate重試失敗的請求。默認狀況下,該邏輯是禁用的。您能夠經過將Spring Retry添加到應用程序的類路徑來啓用它。負載平衡的RestTemplate尊重一些與從新嘗試失敗請求相關的Ribbon配置值。您可使用client.ribbon.MaxAutoRetriesclient.ribbon.MaxAutoRetriesNextServer, 和client.ribbon.OkToRetryOnAllOperations屬性。若是您想在類路徑上禁用Spring重試的重試邏輯,您能夠設置spring.cloud.loadbalancer.retry.enabled=false。有關這些屬性的做用,請參閱Ribbon文檔。

  若是您想在重試中實現備份策略,您須要建立一個LoadBalancedBackOffPolicyFactory類型的bean,並返回您想爲給定服務使用的備份策略,以下例所示:

@Configuration public class MyConfiguration { @Bean LoadBalancedBackOffPolicyFactory backOffPolciyFactory() { return new LoadBalancedBackOffPolicyFactory() { @Override public BackOffPolicy createBackOffPolicy(String service) { return new ExponentialBackOffPolicy(); } }; } }

  客戶端應該被替換爲您的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...
 } }}; } }; } }
View Code

1.2.五、多RestTemplate 對象

  若是您想要一個沒有負載平衡的RestTemplate,那麼建立一個RestTemplate bean並注入它。要訪問負載平衡的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("http://example.com", String.class); } }

注意,在前面的示例中,在普通RestTemplate聲明中使用@Primary註釋來消除不合格的@Autowired注入的歧義。

出現以下錯誤 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.

相關文章
相關標籤/搜索