領先一步
VMware 提供培訓和認證,以加速您的進度。
了解更多Spring Cloud Function 在 2.0 版本(仍在里程碑階段)中有幾個新功能,其中可能最引人注目的是能夠「完全函數化」。這得益於 Spring Boot 2.1 以及 Spring Framework 5.1 中的變更,這意味著一種不同的 Spring 應用程式 bean 定義思考方式,同時也顯著提高了啟動效能。
從圖片開始總是好的,尤其是當它講述一個故事的時候。這是一個圖表,顯示了 Spring Cloud Function 2.0 相較於 1.0 的改進,比較了 AWS 中冷啟動的成本
x 軸是記憶體(MB),y 軸是冷啟動成本(GBsec)。最顯著的效果是對於低記憶體容器,2.0 的成本幾乎降低了 4 倍。「Custom」函數甚至更快(比 Spring Cloud Function 1.0 快 10 倍) - 它是一個使用 Spring Cloud Function 和 functional bean 的 自訂 AWS runtime。改進的原因在於啟動時間顯著縮短,而這又來自於在應用程式中使用 functional 形式的 bean 定義。如果你需要介紹,Josh 之前做了一個關於 functional bean 註冊的 影片(在 YouTube 上)。現在讓我們仔細看看它在 Spring Cloud Function 中是如何運作的。
這是一個來自 1.0 版本的 Spring Cloud Function 應用程式,具有熟悉的 @Configuration
和 @Bean
宣告風格
@SpringBootApplication
public class DemoApplication {
@Bean
public Function<String, String> uppercase() {
return value -> value.toUpperCase();
}
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
你可以將它與所有依賴項一起打包成 jar 檔案,並上傳到 Amazon,從而在 AWS Lambda 中運行它(例如)。該專案還支援 Azure Functions 和 Apache OpenWhisk。其他無伺服器供應商,例如 Oracle Fn 和 Riff,維護他們自己的綁定。
你也可以通過在 classpath 上包含 spring-cloud-function-starter-web
,在自己的 HTTP 伺服器中運行上面的應用程式。運行 main 方法會暴露一個 endpoint,你可以使用它來 ping uppercase
函數。
$ curl localhost:8080 -d foo
FOO
1.0 中的 web adapter 是使用 Spring MVC 實現的,因此你需要一個 Servlet 容器。在 Spring Cloud Function 2.0 中,你也可以使用 Webflux,預設伺服器是 netty(即使你仍然可以使用 Servlet 容器,如果你想的話)- 只需包含 spring-cloud-starter-function-webflux
依賴項即可。功能相同,並且使用者應用程式程式碼可以在兩者中使用。
但在 2.0 中,使用者應用程式程式碼可以改寫成「functional」形式,如下所示
@SpringBootConfiguration
public class DemoApplication
implements ApplicationContextInitializer<GenericApplicationContext> {
public static void main(String[] args) {
FunctionalSpringApplication.run(DemoApplication.class, args);
}
public Function<String, String> uppercase() {
return value -> value.toUpperCase();
}
@Override
public void initialize(GenericApplicationContext context) {
context.registerBean("demo", FunctionRegistration.class,
() -> new FunctionRegistration<>(uppercase())
.type(FunctionType.from(String.class).to(String.class)));
}
}
主要區別在於
主類別是一個 ApplicationContextInitializer
。
@Bean
方法已轉換為對 context.registerBean()
的呼叫。
@SpringBootApplication
已替換為 @SpringBootConfiguration
,以表示我們沒有啟用 Spring Boot 自動配置,但仍然將該類別標記為「進入點」。
來自 Spring Boot 的 SpringApplication
已替換為來自 Spring Cloud Function 的 FunctionalSpringApplication
(它是一個子類別)。
你在 Spring Cloud Function 應用程式中註冊的業務邏輯 bean 的類型為 FunctionRegistration
。這是一個 wrapper,其中包含函數以及有關輸入和輸出類型的資訊。在應用程式的 @Bean
形式中,該資訊可以通過反射推導出來,但在 functional bean 註冊中,除非我們使用 FunctionRegistration
,否則會遺失一部分資訊。
使用 ApplicationContextInitializer
和 FunctionRegistration
的替代方法是使應用程式本身實現 Function
(或 Consumer
或 Supplier
)。範例(等同於以上)
@SpringBootConfiguration
public class DemoApplication implements Function<String, String> {
public static void main(String[] args) {
FunctionalSpringApplication.run(DemoApplication.class, args);
}
@Override
public String apply(String value) {
return value.toUpperCase();
}
}
也可以新增一個單獨的、獨立的 Function
類別,並使用 run()
方法的替代形式將其註冊到 SpringApplication
。最重要的是,泛型類型資訊可以在執行時通過類別宣告獲得。
如果新增 spring-cloud-starter-function-webflux
,則應用程式會在自己的 HTTP 伺服器中運行(目前無法與 MVC starter 一起使用,因為嵌入式 Servlet 容器的 functional 形式尚未實現)。該應用程式也可以在 AWS Lambda 或 Azure Functions 中正常運行,並且啟動時間的改進非常顯著(如上圖所示)。這是另一個圖表中的啟動時間(y 軸上的啟動時間,單位為秒)
Spring Cloud Function 2.0 也有一些用於整合測試的實用程式,Spring Boot 使用者會非常熟悉。例如,這是用於包裝上述應用程式的 HTTP 伺服器的整合測試
@RunWith(SpringRunner.class)
@FunctionalSpringBootTest
@AutoConfigureWebTestClient
public class FunctionalTests {
@Autowired
private WebTestClient client;
@Test
public void words() throws Exception {
client.post().uri("/").body(Mono.just("foo"), String.class)
.exchange().expectStatus().isOk()
.expectBody(String.class).isEqualTo("FOO");
}
}
此測試與你為同一個應用程式的 @Bean
版本編寫的測試幾乎相同 - 唯一的區別是 @FunctionalSpringBootTest
註解,而不是常規的 @SpringBootTest
。所有其他部分,例如 @Autowired
WebTestClient
,都是標準 Spring Boot 功能。
Spring Boot 可以很好地與 functional bean 註冊一起使用 - Spring Cloud Function 建立並運行在 Spring Boot 上 - 但 Spring Boot 中一些最有用的功能,即自動配置,都是以非 functional 樣式編碼的。與整個 Spring Boot 相比,大多數 Spring Cloud Function 應用程式的範圍相對較小,因此我們能夠輕鬆地將其調整為這些 functional bean 定義。如果超出這個有限的範圍,你可以通過切換回 @Bean
樣式配置或使用混合方法來擴展你的 Spring Cloud Function 應用程式。將相同種類的功能擴展到 Spring Boot 生態系統的其餘部分需要更長的時間,但這是我們正在積極努力的事情。請試用 Spring Cloud Function 2.0 並在你有時間時向我們提供一些回饋 - GA 版本即將推出。