java-cfenv 介紹:用於存取 Cloud Foundry 服務的新函式庫

版本發布 | Mark Pollack | 2019 年 2 月 15 日 | ...

簡介

Spring Cloud Connectors 函式庫自 2011 年 Cloud Foundry 啟動活動以來便已存在。連接器函式庫和 Cloud Foundry 的 Java 建置包的主要目標之一是「減少您開始使用 Cloud Foundry 時的初始投資」。 連接器函式庫會建立連接到後端服務 (如資料庫) 所需的 Spring bean 定義,並使用包含在 VCAP_SERVICES 環境變數中的資訊。然後,建置包會透過稱為「自動重新配置」的功能,將應用程式中原本的 bean 定義取代為連接器函式庫建立的 bean 定義。您可能在將應用程式推送至 Cloud Foundry 時的日誌中看過它...

-----> Downloading Spring Auto Reconfiguration 2.5.0_RELEASE from https://java-buildpack.cloudfoundry.org/auto-reconfiguration/auto-reconfiguration-2.5.0_RELEASE.jar

自動重新配置對於入門來說非常棒。 但是,當您想要更多控制權時,例如變更與 DataSource 相關聯的連線池大小時,它就不是那麼好了。 這需要編寫特定於連接器的程式碼,並且它不會像 Spring Boot 那樣公開那麼多的連線池選項。 相同的限制也適用於其他後端服務。

這引發了一個問題,為什麼我們有兩種競爭機制來建立服務基礎結構 bean? 我們不能讓 Spring Boot 為我們處理這一切嗎? 這就是我們創建新的 java-cfenv 函式庫的動機。

java-cfenv 介紹

java-cfenv 函式庫的靈感來自 node-cfenvpy-cfenv 函式庫,它們用於 Cloud Foundry 生態系統的其他地方。 這些函式庫提供了一個簡單的 API,用於從 VCAP_SERVICES 環境變數中包含的 JSON 字串中檢索憑證。 我們將從 Java API 的簡要介紹開始(我們不希望它經常被使用),然後展示它如何與 Spring 和 Spring Boot 的自動配置功能整合。

核心 API 由五個類別組成

  • CfEnv 負責解析 VCAP_SERVICESVCAP_APPLICATION 環境變數的內容。
  • CfApplication 提供對 VCAP_APPLICATION 環境變數內容的存取。
  • CfEnv 上的 Finder 方法會傳回 CfService 類別的執行個體。
  • CfService 提供對服務名稱、標籤、索引標籤和方案的存取,以及 CfCredentials 物件。
  • CfCredentials 提供存取器以取得使用者名稱、密碼、主機、連接埠和 URI。 URI 使用 UriInfo 類別表示。

例如,如果您在 Cloud Foundry 中將 MySql 服務繫結到您的應用程式,則 VCAP_SERVICES 環境變數將包含如下的條目

{
 "p-mysql": [
    {
      "credentials": {
        "hostname": "10.0.4.35",
        "port": 3306,
        "name": "cf_2e23d10a_8738_8c3c_66cf_13e44422698c",
        "username": "8McHri7aKbuTEGCR",
        "password": "J2BNJYkeXAH9idkG",
        "uri": "mysql://8McHri7aKbuTEGCR:[email protected]:3306/cf_2e23d10a_8738_8c3c_66cf_13e44422698c?reconnect=true",
        "jdbcUrl": "jdbc:mysql://10.0.4.35:3306/cf_2e23d10a_8738_8c3c_66cf_13e44422698c?user=8McHri7aKbuTEGCR&password=J2BNJYkeXAH9idkG"
      },
      "syslog_drain_url": null,
      "volume_mounts": [],
      "label": "p-mysql",
      "provider": null,
      "plan": "100mb",
      "name": "mysql",
      "tags": [
        "mysql",
        "relational"
      ]
    }
  ]
}

當使用 java-cfenv API 時,我們可以透過幾個簡單的方法呼叫來取得憑證資訊,然後以程式方式建立與資料庫的連線。

CfEnv cfEnv = new CfEnv();
CfService cfService = cfEnv.findServiceByName(“mysql”);
String plan = cfService.getPlan(); // 100mb
CfCredentials cfCredentials = cfService.getCredentials();
String password = cfCredentials.getPassword(); // J2BNJYkeXAH9idkG
UriInfo uriInfo = cfCredentials.getUriInfo();
String username = uriInfo.getUsername(); // 8McHri7aKbuTEGCR

findServiceByName 方法採用規則運算式,以幫助在可以稍微不同地命名服務的不同 Cloud Foundry 環境中提供一些可攜性。 還有其他 Finder 方法,可以幫助您從標籤等中進行選擇。

資料庫支援

在前面的範例中,您可能只想取得 JSON 欄位 jdbcUrl,以便可以將其傳遞到 DataSource。 您可以使用 API 來執行此操作

String jdbcUrl = cfCredentials.getString(“jdbcUrl”);

但是,並非 Cloud Foundry 上的所有資料庫服務都提供這個方便的欄位。 實際上,Cloud Foundry 上各種資料庫服務提供的欄位可能相當隨意。 現有的連接器函式庫已經開發出處理這種差異的啟發法,並且此功能已移植到新的 java-cfenv 函式庫。 它在 CfEnvJdbc 類別中可用

CfEnvJdbc cfEnvJdbc = new CfEnvJdbc();
CfJdbcService cfJdbcService = cfEnvJdbc.findJdbcService();
String jdbcUrl = cfJdbcService.getUrl();

如果有多個資料庫服務繫結到應用程式,則方法 findJdbcService 將會擲回例外。 在這種情況下,您可以使用方法 findJdbcServiceByName 在多個資料庫服務之間進行選擇。

String jdbcUrl1 = cfEnvJdbc.findJdbcServiceByName('mysqlA').getUrl();
String jdbcUrl2 = cfEnvJdbc.findJdbcServiceByName('mysqlB').getUrl();

與 Spring 一起使用

如果您使用的是 Spring 而不是 Spring Boot,您可以將 CfJdbcEnv 執行個體註冊為 bean,然後使用 Spring Expression Language 在其上調用方法來設定應用程式屬性。

@Bean
public CfJdbcEnv cfJdbcEnv() {
  return new CfJdbcEnv();
}

然後在屬性檔案中,存取 CfJdbcEnv 執行個體

myDatasourceUrl=#{ cfJdbcEnv.findJdbcService().getUrl() }

與 Spring Boot 一起使用

大多數 Spring Boot 使用者不必直接使用 java-cfenv API。 java-cfenv 函式庫包含 Spring Boot EnvironmentPostProcessor 實作,可自動設定眾所周知的 Spring Boot 屬性。 這允許 Spring Boot 的自動配置啟動,同時仍保留透過環境變數或其他更高優先級的環境屬性來源覆蓋值的可能性。

start.spring.io 產生您的專案後,您需要做的就是手動將 java-cfenv-boot 依賴項新增到您的專案中,並在將您的應用程式推送至 Cloud Foundry 時停用自動重新配置。 對於 maven,依賴項是

<dependency>
  <groupId>io.pivotal.cfenv</groupId>
  <artifactId>java-cfenv-boot</artifactId>
  <version>1.0.0.M1</version>
</dependency>

因為這目前是一個里程碑版本,所以您需要新增一個里程碑 <repository> 組態,例如

<repository>
   <id>spring-milestones</id>
   <name>Spring Milestones</name>
   <url>http://repo.spring.io/libs-milestone-local</url>
</repository>

要停用自動重新配置,請使用以下命令或其在資訊清單檔案中的等效命令。

cf set-env <APP> JBP_CONFIG_SPRING_AUTO_RECONFIGURATION '{enabled: false}'

由於自動重新配置也會設定 cloud 設定檔,許多應用程式都已開始依賴它,因此您可能還需要明確設定此設定檔。

cf set-env <APP> SPRING_PROFILES_ACTIVE cloud

如果您使用的是資訊清單,則條目將是

env:
 SPRING_PROFILES_ACTIVE: cloud
 JBP_CONFIG_SPRING_AUTO_RECONFIGURATION: '{enabled: false}'

值得注意的是,在生產環境中,無論如何您可能應該這樣做。

要設定連線池屬性,您現在可以簡單地使用標準 Spring Boot 屬性,例如 spring.datasource.maxActive=10 和其他更具體的連線池屬性。

下一步是什麼?

有關如何使用 java-cfenv 函式庫的更多資訊可在 GitHub 上找到。 目前的版本是 1.0.0.M1,並且將很快推出 GA 版本,因為它將於本月稍後併入 Data Flow 2.0 GA 版本中。 與往常一樣,我們歡迎您的回饋和貢獻,即使它們導致需要在 1.0 版本發布後不久併入 java-cfenv 2.0 版本中的 API 破壞性變更。

java-cfenv 的 1.0 GA 版本將支援 Spring Cloud Connectors 專案的所有服務,因為它們受到 Spring Boot 自動配置的良好支援。 屆時,現有的 Connectors 函式庫將進入維護模式。 當然,將會解決重大錯誤和安全性問題,但不會新增新功能。 將提供一個將應用程式從 Spring Cloud Connectors 遷移到 java-cfenv 的指南,並隨 java-cfenv 的 1.0 GA 版本一起提供。

項目頁面上列出了其他基於核心 Connectors 專案構建的函式庫。 這些擴充專案可以繼續使用 Connectors,但鼓勵維護人員遷移到以 Boot 為中心的方法。

取得 Spring 電子報

隨時關注 Spring 電子報

訂閱

搶先一步

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

了解更多

取得支援

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

了解更多

即將舉行的活動

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

查看全部