1. 簡介
在本教程中,我們將學習如何使用 Spring Cloud Function。
我們將本地構建並運行一個簡單的 Spring Cloud Function,然後將其部署到 AWS。
2. Spring Cloud Function 設置
為了開始,我們從頭開始實現並測試一個簡單的項目,該項目使用兩種不同的方法定義兩個函數:
- 一個字符串反轉器,使用簡單的方法
- 以及一個問候者,使用專門的類
2.1 Maven 依賴
首先,我們需要添加 spring-cloud-starter-function-web 依賴。這將作為本地適配器,並引入必要的依賴項以在本地運行我們的函數:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-function-web</artifactId>
<version>1.0.1.RELEASE</version>
</dependency>在部署到AWS時,請稍候,我們將對其進行一些修改。
2.2. 編寫 Spring Cloud Function
使用 Spring Cloud Function,我們可以將類型為 Function、Consumer 或 Supplier 的 @Bean 聲明為單獨的方法:
@SpringBootApplication
public class CloudFunctionApplication {
public static void main(String[] args) {
SpringApplication.run(CloudFunctionApplication.class, args);
}
@Bean
public Function<String, String> reverseString() {
return value -> new StringBuilder(value).reverse().toString();
}
}如上代碼所示,我們可以將反轉字符串功能作為 函數 暴露出來,以便我們的目標函數式平台調用它。
2.3. 本地測試反轉字符串函數
spring-cloud-starter-function-web 暴露了該函數作為 HTTP 端點。 在運行 CloudFunctionApplication 後,我們可以使用 curl 測試本地目標:
curl localhost:8080/reverseString -H "Content-Type: text/plain" -d "Baeldung User"請注意,端點是 Bean 的名稱。
正如預期的那樣,我們得到反轉後的字符串作為輸出:
resU gnudleaB2.4. 在包中掃描 Spring Cloud Function
除了將我們的方法暴露為 <em @Bean,我們還可以將軟件編寫為實現泛型接口 <em Function<T, R> 的類:
public class Greeter implements Function<String, String> {
@Override
public String apply(String s) {
return "Hello " + s + ", and welcome to Spring Cloud Function!!!";
}
}我們可以隨後指定掃描用於查找相關 Bean 的包,位於 application.properties 文件中:
spring.cloud.function.scan.packages=com.baeldung.spring.cloudfunction.functions2.5. 本地測試 Greeter 函數
再次,我們可以啓動應用程序並使用 curl 測試 Greeter 函數:
curl localhost:8080/greeter -H "Content-Type: text/plain" -d "World"請注意,端點是實現 Functional 接口的類名。
順理成章,我們得到了預期的問候語。
Hello World, and welcome to Spring Cloud function!!!3. 在AWS上使用Spring Cloud Function
Spring Cloud Function 的強大之處在於,我們可以構建 Spring 支持的函數,這些函數具有云無關性。函數本身不需要知道它是如何被調用的,或者它部署到哪個環境中。例如,我們可以輕鬆地將此 greeter 函數部署到 AWS、Azure 或 Google Cloud Platform,而無需更改任何業務邏輯。
由於 AWS Lambda 是流行的無服務器解決方案之一,讓我們重點關注如何將其部署到其中。
所以,讓我們不再猶豫,將我們的函數部署到雲端!
3.1. Maven 依賴
請記住 <em >spring-cloud-starter-function-web</em > 依賴項,這是我們最初添加的。現在是時候更改它了。
如你所見,根據我們運行 Spring Cloud Function 的位置,我們需要添加適當的依賴項。
對於 AWS,我們將使用 spring-cloud-function-adapter-aws。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-function-adapter-aws</artifactId>
</dependency>接下來,讓我們添加必要的 AWS 依賴項以處理 Lambda 事件:
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-lambda-java-events</artifactId>
<version>2.0.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-lambda-java-core</artifactId>
<version>1.1.0</version>
<scope>provided</scope>
</dependency>最後,由於我們將使用 Maven 構建生成的 Artifact 上傳到 AWS Lambda,因此我們需要構建一個被“瘦化”的 Artifact,即所有依賴項都以單獨的類文件形式展開,而不是 JAR 包。
使用 spring-boot-thin-layout 依賴項可以幫助我們通過排除不必要的依賴項來減小 Artifact 的大小:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot.experimental</groupId>
<artifactId>spring-boot-thin-layout</artifactId>
<version>1.0.10.RELEASE</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<shadedArtifactAttached>true</shadedArtifactAttached>
<shadedClassifierName>aws</shadedClassifierName>
</configuration>
</plugin>
</plugins>
</build>3.2. AWS 處理程序
如果我們要通過 HTTP 請求再次暴露我們的字符串反轉器,那麼 Spring Cloud Function AWS 附帶了 SpringBootRequestHandler。它實現了 AWS 的 RequestHandler,負責將 AWS 請求分發到我們的函數中。
public class MyStringHandlers extends SpringBootRequestHandler<String, String> {
}Spring Cloud Function AWS 附帶了 SpringBootStreamHandler 和 FunctionInvokingS3EventHandler 作為其他示例。
MyStringHandlers 只是一個空類,但它在作為 Lambda 函數的入口點以及定義其輸入和輸出類型方面起着重要作用。
如截圖所示,我們將在此 Handler 輸入字段中提供該類的完全限定名稱,位於 AWS Lambda 配置頁面上。
3.3. AWS 如何確定要調用的雲函數?
實際上,即使我們的應用程序中有多個 Spring Cloud Function,AWS 只能調用其中一個。
在下一部分中,我們將使用名為 FUNCTION_NAME 的環境變量在 AWS 控制枱中指定雲函數的名稱。
4. 上傳函數到 AWS 並進行測試
最後,我們使用 Maven 構建我們的 JAR 包,然後通過 AWS 控制枱 UI 上傳它。
<h3><strong>4.1. 在 AWS 控制枱中創建 Lambda 函數並進行配置</strong></h3
><p>在 AWS Lambda 控制枱頁面,在函數代碼部分,我們可以選擇 <strong>Java 8</strong> 運行時,只需簡單地點擊 <strong>上傳</strong>。</p>
<p>之後,我們需要在 <strong>Handler</strong> 字段中指定實現 <em>SpringBootRequestHandler</em> 類的全限定名,或 <em>com.baeldung.spring.cloudfunction.MyStringHandlers</em>,在本例中:</p>
<img src="/file/story/attachments/image/l/4379da87-a38e-4555-be44-984c93815b1e">
<p>然後,在環境變量中,我們通過 <em>FUNCTION_NAME</em> 環境變量指定要通過哪個 Spring Bean 觸發:</p>
<img src="/file/story/attachments/image/l/485f3b90-c53f-4740-8aa9-2b9ee7fad250">
<p>完成這些步驟後,我們就可以通過創建測試事件並提供一個示例字符串來測試 Lambda 函數:</p>
<img src="/file/story/attachments/image/l/f35bdba5-c3d1-4ddf-8bb3-90ae86eedd51">
<p><strong>4.2. 在 AWS 上測試函數</strong></p>
<p>現在,我們 <em>保存</em> 我們的測試,然後點擊 <em>測試</em> 按鈕。</p>
<p>正如預期的那樣,我們得到了與本地測試函數時相同的輸出:</p>
<img src="/file/story/attachments/image/l/36958022-5b78-4c41-95a1-7c1e2c5b51ec">
4.3. 測試另一個函數
請記住,我們的應用程序中還有另一個函數:greeter。 讓我們確保它也能正常工作。
我們將 FUNCTION_NAME 環境變量設置為 greeter:
點擊 保存 按鈕,然後再次點擊 測試 按鈕:
5. 結論
總而言之,儘管仍處於早期階段,Spring Cloud Function 是一種強大的工具,可以解耦業務邏輯與任何特定的運行時目標。藉助它,相同的代碼可以在 Web 端點、雲平台或流處理的一部分上運行。它消除了所有傳輸細節和基礎設施,使開發人員能夠繼續使用熟悉的工具和流程,並專注於業務邏輯。