取得領先
VMware 提供培訓和認證,以加速您的進展。
了解更多Spring Cloud 最有趣的功能之一是它的可擴展性。您可以擴展它以支持其他雲端、增強已支持的雲端、支持新的服務、新的服務連接器 - 所有這些都無需修改 Spring Cloud 的程式碼本身。在本部落格中,我們將探討此功能。如果您尚未閱讀此系列中的第一篇和第二篇部落格文章,請先閱讀它們以獲得足夠的背景知識。
Spring Cloud 沿著三個正交方向提供可擴展性。您可以沿著其中一個方向擴展它,而正交性可確保您繼續受益於其他方向。
雲端平台:雖然 Spring Cloud 支援 Cloud Foundry、Heroku 和本機配置雲端(用於在本機以類似雲端的環境中進行測試),但您不受這些選擇的限制。您可以新增自己的雲端平台,並利用 Spring Cloud 的其他功能,例如 Spring Java Config。
雲端服務:雲端平台提供各種服務,從關聯式資料庫到訊息傳遞。每個雲端平台提供的服務差異很大,即使是相同平台的多個安裝也是如此。對於 PaaS 產品(例如 Cloud Foundry)尤其如此,因為 Cloud Foundry 的私有實例通常具有特定於每個安裝的服務。Spring Cloud 提供了一種簡單的方法來擴展到其核心產品之外的服務。就像雲端平台的可擴展性一樣,您不必更改 Spring Cloud 程式碼即可將其擴展到新的服務,並且您可以繼續利用其他部分。
框架:Spring Cloud 目前透過 spring-service-connector 模組支援 Spring 框架。但是,除了該模組之外,Spring Cloud 中的任何內容都不依賴 Spring。因此,您應該能夠使用來自任何基於 JVM 的框架的其他部分,或透過新增新的模組來擴展它以用於框架。
在先前的部落格文章中,我們研究了您將如何使用 CloudFactory
和 Cloud
以程式設計方式使用 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 Data 和 Spring 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
,它負責實作這些方法。
ServiceConnectorCreator
的 SC
泛型參數繫結到它將建立的連接器的類型,例如 DataSource
,而 SI
參數表示它可以使用的 ServiceInfo
的類型。
create()
方法會提供一個 ServiceInfo
物件和一個配置物件,該物件攜帶服務特定的資訊,例如池化參數。它需要使用這些參數來建立適當的連接器。
實作準備就緒後,只需將其放入名為 /META-INF/services/org.springframework.cloud.service.ServiceConnectorCreator
的檔案中即可。Spring Cloud 將使用先前描述的 Service Loader 機制。
如您所見,Spring Cloud 沿著雲端平台、服務和框架軸提供了相當大的可擴展性。下次您遇到這些新類型時,您應該能夠擴展 Spring Cloud 以與它們一起工作。如果您開放原始碼您的擴展,請告訴我們,以便我們可以展示它以供其他人受益。如果它是足夠常見的擴展,請考慮發出提取請求。