擴展 Spring Cloud

工程 | Ramnivas Laddad | 2014 年 8 月 5 日 | ...

Spring Cloud 最有趣的功能之一是它的可擴展性。您可以擴展它以支持其他雲端、增強已支持的雲端、支持新的服務、新的服務連接器 - 所有這些都無需修改 Spring Cloud 的程式碼本身。在本部落格中,我們將探討此功能。如果您尚未閱讀此系列中的第一篇第二篇部落格文章,請先閱讀它們以獲得足夠的背景知識。

可擴展性的三個面向

Spring Cloud 沿著三個正交方向提供可擴展性。您可以沿著其中一個方向擴展它,而正交性可確保您繼續受益於其他方向。

  1. 雲端平台:雖然 Spring Cloud 支援 Cloud Foundry、Heroku 和本機配置雲端(用於在本機以類似雲端的環境中進行測試),但您不受這些選擇的限制。您可以新增自己的雲端平台,並利用 Spring Cloud 的其他功能,例如 Spring Java Config。

  2. 雲端服務:雲端平台提供各種服務,從關聯式資料庫到訊息傳遞。每個雲端平台提供的服務差異很大,即使是相同平台的多個安裝也是如此。對於 PaaS 產品(例如 Cloud Foundry)尤其如此,因為 Cloud Foundry 的私有實例通常具有特定於每個安裝的服務。Spring Cloud 提供了一種簡單的方法來擴展到其核心產品之外的服務。就像雲端平台的可擴展性一樣,您不必更改 Spring Cloud 程式碼即可將其擴展到新的服務,並且您可以繼續利用其他部分。

  3. 框架:Spring Cloud 目前透過 spring-service-connector 模組支援 Spring 框架。但是,除了該模組之外,Spring Cloud 中的任何內容都不依賴 Spring。因此,您應該能夠使用來自任何基於 JVM 的框架的其他部分,或透過新增新的模組來擴展它以用於框架。

先前的部落格文章中,我們研究了您將如何使用 CloudFactoryCloud 以程式設計方式使用 Spring Cloud。在可擴展性方面,您將不會使用這兩者中的任何一個;而是您將在核心模組中實現其他類型。讓我們來看看它們。

雲端平台可擴展性

若要將 Spring Cloud 擴展到新的雲端平台,您需要熟悉的主要類型是 CloudConnector,這是一個簡單的三個方法介面

public interface CloudConnector {
	boolean isInMatchingCloud();
	ApplicationInstanceInfo getApplicationInstanceInfo();
	List<ServiceInfo> getServiceInfos();
}

isInMatchingCloud() 方法應檢查其環境以確定它是否在正確的環境中運行。例如,Cloud Foundry 連接器會檢查 VCAP_APPLICATION 環境變數是否存在,而 Heroku 連接器會尋找 DYNO 環境變數是否存在。getApplicationInstanceInfo() 方法會傳回有關目前應用程式實例(應用程式名稱、主機、連接埠和應用程式屬性)的資訊。最有趣的方法 getServiceInfos() 會傳回一個列表,每個元素都包含足夠的資訊,以便應用程式知道如何連接到每個服務。每個 ServiceInfo 物件中包含的確切資訊取決於每個實作(ServiceInfo 本身僅定義一個方法:getId())。

建立 CloudConnector 的實作後,您需要讓 Spring Cloud 知道它。對於所有擴展點,Spring Cloud 使用基於 ServiceLoader 的統一機制。應用於 Spring Cloud 以實現平台可擴展性時,它歸結為包含一個名為 /META-INF/services/org.springframework.cloud.CloudConnector 的檔案,其中包含具有實作類別完整名稱的條目。通常,您會將此檔案與您的實作和支援類別一起捆綁。然後,應用程式只需在類別路徑中包含此 jar 即可。

服務可擴展性

ServiceInfoCreator 介面提供了一個擴展點,用於使用新的服務。

public interface ServiceInfoCreator<SI extends ServiceInfo, SD> {
    public boolean accept(SD serviceData);
    public SI createServiceInfo(SD serviceData);
}

泛型參數 SI 定義了它將建立的 ServiceInfo 的種類,而 SD 參數定義了它可以使用的原始服務資料類型。原始服務資料類型取決於雲端平台。例如,在 Cloud Foundry 中,它將是一個基於 VCAP_SERVICES 環境變數的 Map,而在 Heroku 中,它將是一個包含服務特定的環境變數及其值的配對。由於原始資料類型取決於平台,因此 ServiceInfoCreator 的實作也是如此。accept() 方法會檢查服務資料,並確定它是否可以處理它。例如,它可以查看 URL 方案並確定它是否可以使用該服務資料。如果可以,createServiceInfo() 必須傳回 ServiceInfo 物件。如果它是一個全新的服務,您可能還必須為此實作 ServiceInfo,否則您可以使用其中一個現有的服務。

實作 ServiceInfoCreator 之後,您必須讓 Spring Cloud 知道它。這遵循與先前討論的雲端平台可擴展性相同的想法。在這種情況下,您使用的檔案名稱取決於 CloudConnector。對於 Cloud Foundry,它是 /META-INF/services/org.springframework.cloud.cloudfoundry.CloudFoundryServiceInfoCreator(理論上,CloudConnector 實作可能會決定使用另一種擴展機制,但 Spring Cloud 不建議這樣做)。

如先前的部落格文章中所述,雲端應用程式開發人員可能會決定直接使用 ServiceInfo 物件。因此,如果您只實作 ServiceInfoCreator,您就已經提供了一些好處。但是,對於許多專注於開發應用程式的開發人員來說,使用原始 ServiceInfo 物件可能不受歡迎,因此您也將實作下一個擴展。

框架可擴展性

最後一個擴展點是 ServiceConnectorCreator。它的工作是將 ServiceInfo 轉換為適用於應用程式正在使用的框架中使用的服務連接器。例如,它可以將 MysqlServiceInfo 轉換為 DataSource 物件。Spring Cloud 開箱即用地支援 DataSource 和一些 Spring DataSpring AMQP 類型的連接器。如果您希望將 Spring Cloud 擴展到其他框架,或者如果您想支援其他 Spring Data 類型(例如 Neo4J、Elasticsearch、Cassandra)或 Spring 相容的類型(例如 S3),但 Spring Cloud 尚未直接支援,那麼這就是您需要的擴展點。

public interface ServiceConnectorCreator<SC, SI extends ServiceInfo> {
    SC create(SI serviceInfo, ServiceConnectorConfig serviceConnectorConfig);
    ...
}

還有幾個方法;但是,您通常會擴展 AbstractServiceConnectorCreator,它負責實作這些方法。

ServiceConnectorCreatorSC 泛型參數繫結到它將建立的連接器的類型,例如 DataSource,而 SI 參數表示它可以使用的 ServiceInfo 的類型。

create() 方法會提供一個 ServiceInfo 物件和一個配置物件,該物件攜帶服務特定的資訊,例如池化參數。它需要使用這些參數來建立適當的連接器。

實作準備就緒後,只需將其放入名為 /META-INF/services/org.springframework.cloud.service.ServiceConnectorCreator 的檔案中即可。Spring Cloud 將使用先前描述的 Service Loader 機制。

總結

如您所見,Spring Cloud 沿著雲端平台、服務和框架軸提供了相當大的可擴展性。下次您遇到這些新類型時,您應該能夠擴展 Spring Cloud 以與它們一起工作。如果您開放原始碼您的擴展,請告訴我們,以便我們可以展示它以供其他人受益。如果它是足夠常見的擴展,請考慮發出提取請求。

取得 Spring 電子報

隨時關注 Spring 電子報

訂閱

取得領先

VMware 提供培訓和認證,以加速您的進展。

了解更多

取得支援

Tanzu Spring 在一個簡單的訂閱中提供 OpenJDK™、Spring 和 Apache Tomcat® 的支援和二進位檔案。

了解更多

即將舉行的活動

查看 Spring 社群中所有即將舉行的活動。

檢視全部