Spring Cloud Function 2.0 與 Azure Functions

工程 | Dave Syer | 2018 年 9 月 25 日 | ...

Spring Cloud Function 自 1.0 版本以來就支援 Microsoft Azure Functions,但在最新的 2.0 版本(仍在里程碑階段)中,我們決定稍微更改程式設計模型。本文描述了這些變更對使用者的意義,並提供了轉變背後的一些背景資訊。Spring 團隊在開發過程中樂在其中,並與 Microsoft 的同仁合作,為我們的使用者打造了這兩項技術的最佳融合。

Azure Functions for Java

Microsoft 在 Azure Functions 中支援 Java 已經有一段時間了,它使開發人員能夠輕鬆地編寫和部署 Java 程式碼,以無伺服器的方式連接到 Azure 中的各種平台服務(事件、資料庫、儲存空間、HTTP 閘道等)。它帶有一個基於註解的程式設計模型,將函數實現放在 Java 方法中。因此,您編寫一個方法並使用 @FunctionName 進行註解,它就變成了一個 Azure Function。有一套基於 Maven 插件(目前)的豐富工具,可以驅動 Azure 命令列,並可用於建置函數、在本地執行和偵錯它,並將其部署到雲端。Azure 網站上有一個快速入門指南,它將幫助您安裝所有必要的先決條件並使其正常工作,並且在開發人員指南中提供了有關 Azure Functions 如何工作的更詳細的文件。

這些註解還將函數方法參數和傳回類型與部署時使用的服務聯繫起來。例如,如果您想在部署時綁定到 HTTP 閘道,您可以使用 @HttpTrigger

@FunctionName("uppercase")
public Bar execute(
    @HttpTrigger(name = "req", methods = { HttpMethod.GET, HttpMethod.POST },
        authLevel = AuthorizationLevel.ANONYMOUS) Foo foo,
    ExecutionContext context) {
  return new Bar(foo.getValue());
}

在這個例子中,我們接受一個傳入的 HTTP POST 請求,Azure 將其主體綁定到 Foo 類型的 POJO。我們將 Foo 轉換為 Bar,並透過 HTTP 回應傳回給呼叫者。

HTTP 觸發器是 Azure Functions 中最受歡迎的整合之一,但更受歡迎的是基於事件和儲存或基於資料庫的觸發器。完整的列表可以在觸發器和繫結文件中找到 - 有一個表格,您可以點擊特定的繫結或觸發器,它會將您帶到參考頁面,其中包含所有語言(包括 Java)的程式碼範例。

這是另一個使用 Azure Event Hub 作為輸入和 Cosmos DB 作為輸出的範例。這個例子在 github 中

@FunctionName("uppercase")
public Bar execute(
  @EventHubTrigger(name = "data", eventHubName = "events",
        connection = "TRANSACTIONS_EVENT_HUB_CONNECTION_STRING")
    Foo data,
    @CosmosDBOutput(name = "document", databaseName = "inventory",
        collectionName = "messages",
        connectionStringSetting = "PRODUCT_ITEMS_DOCUMENTDB_CONNECTION_STRING",
        createIfNotExists = true)
    OutputBinding<Bar> document,
    final ExecutionContext context) {
  return document.setValue(new Bar(foo.getValue()));
}

注意

如果傳入的 JSON 無法轉換為函數輸入類型(在本例中為 Foo),您會看到 Azure 失敗並出現令人困惑的 no such method 錯誤。如果您看到這種情況,您可以將 @FunctionName 方法更改為 String 輸入,並仔細檢查資料以確保它可以綁定到所需的輸入類型。

這些註解透過間接的方式將連接憑證資訊傳遞給在函數部署中配置的環境變數。所有這些的配置都發生在 build pom.xml 中,透過 Azure Functions Maven 插件。例如

<plugin>
  <groupId>com.microsoft.azure</groupId>
  <artifactId>azure-functions-maven-plugin</artifactId>
  <configuration>
    <resourceGroup>${functionResourceGroup}</resourceGroup>
    <appName>${functionAppName}</appName>
    <region>${functionAppRegion}</region>
    <appSettings>
            <property>
              <name>FUNCTIONS_EXTENSION_VERSION</name>
              <value>beta</value>
            </property>
            <property>
              <name>TRANSACTIONS_EVENT_HUB_CONNECTION_STRING</name>
            <value>${TRANSACTIONS_EVENT_HUB_CONNECTION_STRING}</value>
            </property>
            <property>
              <name>PRODUCT_ITEMS_DOCUMENTDB_CONNECTION_STRING</name>
              <value>${PRODUCT_ITEMS_DOCUMENTDB_CONNECTION_STRING}</value>
            </property>
            <property>
              <name>MSDEPLOY_RENAME_LOCKED_FILES</name>
              <value>1</value>
            </property>
    </appSettings>
  </configuration>
  <executions>
    <execution>
            <id>package-functions</id>
            <goals>
              <goal>package</goal>
            </goals>
    </execution>
  </executions>
</plugin>

在這種情況下,環境變數名稱將插件配置連結到函數繫結宣告。例如,@EventHubTrigger 有一個 connection 屬性,它將在運行時從 TRANSACTIONS_EVENT_HUB_CONNECTION_STRING 環境變數中填充。該插件使用具有相同名稱的本地環境變數(注意 ${} 佔位符)遠端配置它,開發人員或 CI 流程負責在運行時設定它。

您自己的個人連接字串是秘密,可以在 Azure 儀表板中找到 - 當您點擊相關資源時,通常會有一個 Connection Strings 連結(或類似的連結),您可以複製並貼到您的本地流程中(例如,在您在本地運行但不檢查到原始碼控制中的腳本中)。例如,您可以使用類似以下的 setup-env.sh 腳本

export PRODUCT_ITEMS_DOCUMENTDB_CONNECTION_STRING="AccountEndpoint=https://..."
export TRANSACTIONS_EVENT_HUB_CONNECTION_STRING="Endpoint=sb://..."

並在終端會話開始時來源它一次。

在範例的 pom.xml 中還有一些其他的插件宣告。它們都很重要,但基本上是樣板 - 您應該能夠複製它們並在所有 Azure Function 應用程式中重複使用相同的配置。

Spring Cloud Function

當應用程式開發人員宣告 java.util.Function 類型的 Spring bean 時,Spring Cloud Function 旨在支援類似的無伺服器用例。與 Vanilla Java 函數相比,在 Azure 上使用 Spring Cloud Function 的優點是,實際的業務邏輯程式碼(原則上)可以移植到其他平台,並且對於現有的 Spring 使用者來說,這是一個熟悉的程式設計模型。此外,Spring 的所有通常優點都適用:依賴注入以及與許多其他 Java 函式庫的全面整合。

上述兩個範例的等效項將是一個單一的 @Bean

@Bean
public Function<Foo, Bar> uppercase() {
  return foo -> new Bar(foo.getValue().toUpperCase());
}

在 Spring Cloud Function 的 1.0 版本中,使用者必須手動將 Microsoft 註解映射到 JSON 部署描述符,並手動將其包裝到具有適合該平台的正確佈局的封存中。這個過程很脆弱(但獨立於 Azure Java 程式設計模型)。

在 2.0 版本中,這仍然有效,但我們選擇更明確地支援 Azure 註解的使用。因此,現在我們有一個基礎類別,應用程式開發人員可以擴展並使用 Azure 註解進行裝飾。上面的例子將完全相同於 @Bean,並且上述其中一個 execute 方法將被插入到 Spring Cloud 處理程序的子類別中。例如

public class UppercaseHandler extends AzureSpringBootRequestHandler<Foo, Bar> {
  @FunctionName("uppercase")
    @HttpTrigger(name = "req", methods = { HttpMethod.GET,
        HttpMethod.POST }, authLevel = AuthorizationLevel.ANONYMOUS) Foo foo,
    ExecutionContext context) {
  return super.handle(foo, context);
}

請注意,基礎類別 AzureSpringBootRequestHandler 是通用的,具有輸入和輸出的類型參數。您必須將輸入類型與傳入的事件資料相匹配,事件資料將以 JSON 格式呈現,並在 Spring 執行任何操作之前由 Azure 使用 Jackson 轉換。基礎類別中有 2 個實用程式方法,一個 (handle) 傳回回應物件,另一個 (handleOutput) 接受 OutputBinding 並將其繫結到使用者 Function 的輸出。

注意

基礎類別是純樣板,僅作為您的 Spring 函數與無伺服器平台服務繫結的外部表示。如果您在不同的平台上運行,或者例如透過 Spring Cloud Function Web 适配器在本地運行,則 Azure 繫結將被忽略。將來有可能用介面宣告取代它 - Azure 平台目前不允許這樣做,但這是我們正在與 Microsoft 團隊研究的事情。

有各種配置選項可以驅動 Azure Function 的運行時行為。最重要(也是唯一強制性)的一個是 MAIN_CLASS,它是攜帶 Function(或 Functions)宣告的主要 @SpringBootApplication 類別。您可以將其指定為環境變數,或指定為應用程式 jar 資訊清單中的 Main-Class 條目。只要您的應用程式有一個具有精確一個函數的主要類別,就無需執行任何其他操作。在範例應用程式中,我們使用資訊清單來定義主要類別

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-jar-plugin</artifactId>
  <configuration>
    <archive>
      <manifest>
        <mainClass>example.FunctionApplication</mainClass>
      </manifest>
    </archive>
  </configuration>
</plugin>

如果您的應用程式有多個 Function bean,則可以透過 @FunctionName 註解將它們映射到 Azure 函數 - bean 名稱(或更精確地說,FunctionCatalog 中的名稱)與函數名稱相匹配。透過這種方式,您可以建立一個 Azure Function 應用程式,它是用於一組函數的單一部署構件。如果您願意,您也可以使用任意 @FunctionName,並透過環境變數 FUNCTION_NAMEapplication.properties 中的 function.name 配置 Spring Cloud Function 名稱。

項目儲存庫中還有一個關於如何將 Spring Cloud Function 設置為 Azure Function 的簡單範例 - 從 Azure 的角度來看,這是一個 HTTP 觸發器,但 Spring Cloud Function 部分非常相似。

注意

如果您本週在 Spring One Platform,請參加 Jeff Hollan (Microsoft) 和 Oleg Zhurakousky (Pivotal) 的 關於使用 Spring 和 Microsoft Azure 運行無伺服器應用程式的簡報

獲取 Spring 電子報

隨時關注 Spring 電子報

訂閱

搶先一步

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

了解更多

獲取支持

Tanzu Spring 在一個簡單的訂閱中提供 OpenJDK™、Spring 和 Apache Tomcat® 的支持和二進製文件。

了解更多

即將到來的活動

查看 Spring 社群中所有即將到來的活動。

查看全部