領先一步
VMware 提供訓練和認證,以加速您的進展。
了解更多Spring Cloud Function 是一個新專案,具有以下高階目標
正如 Spring 一直以來推廣基於純舊 Java 物件 (POJO) 的程式設計模型一樣,Spring Cloud Function 推廣基於純舊函數的程式設計模型。我們指的是在 java.util.function
套件中定義的核心介面:Function
、Consumer
和 Supplier
。
這些類型的實作可以明確地或隱含地透過類別路徑掃描(由 @FunctionScan
啟用)註冊為 bean。參數和/或回傳類型可以選擇性地使用 Reactor 的 Flux
,這是一個反應式串流 Publisher
。這能夠與其他反應式串流元件互通操作,即使是那些基於其他實作的元件,例如 RxJava 2,並且它為此處理模型帶來了反應式功能,例如非阻塞 IO 和背壓(如需更多資訊,請參閱 Project Reactor)。每當參數和/或回傳類型不是 Flux
時,Spring Cloud Function 都會包裝它們,以便函數可以透過 Flux
互通操作。對於簡單的逐項處理用例,您可以保持簡單
public class Greeter implements Function<String, String> {
public String apply(String name) {
return "Hello " + name;
}
}
但是,如果您需要實作將資料集作為處理單位的函數,透過視窗化或 reduce 運算,您可以使用 Flux
類型
public static class WordCount
implements Function<Flux<String>, Flux<Map<String, Integer>>> {
public Flux<Map<String, Integer>> apply(Flux<String> phrases) {
return phrases.window(3)
.flatMap(f -> f.flatMap(phrase -> Flux.fromArray(phrase.split("\\W")))
.reduce(new HashMap<String, Integer>(),
(map, word) -> { map.merge(word, 1, Integer::sum); return map; }));
}
}
依賴函數類型也使得組合功能變得容易,例如
twistAndShout = twist.andThen(shout);
當然,函數也可以使用 Lambda 表達式定義,例如
Function<String, String> shout = s -> s.toUpperCase() + “!”;
事實上,Spring Cloud Function 支援將基於字串的 Lambda 表達式動態編譯為函數實例。當原型設計或新增一些簡單的轉換邏輯時,這可能特別有用,就像今天常用的 Spring Expression Language 一樣。
您可能會問,為什麼 Spring 有必要推廣此模型,因為您可以輕鬆地建立 Function
、Consumer
和 Supplier
實例。得知答案涉及控制反轉,應該不會太令人驚訝。多年來,從基本的依賴注入到 Spring 普遍使用的範本模式,所有的一切都以好萊塢原則來描述:「不要打電話給我們,我們會打電話給你」。上面提到的 Flux
適配實際上是控制反轉的一個例子,但更重要的是業務邏輯與部署配置文件的解耦。在這種情況下,業務邏輯指的是函數,而部署配置文件可以是 REST 應用程式、串流處理應用程式或有限任務。Spring Cloud Function 為每種類型提供一個 JAR,並且在每種情況下,都會使用自動配置的 FunctionCatalog 來定位 ApplicationContext
中的 Functions
、Consumers
和 Suppliers
。
例如,要將上面顯示的 Greeter
函數部署為 REST 端點,只需新增 "spring-cloud-function-web" 依賴項,如此 POM 中所示。這也包括 Spring Boot Maven 外掛程式,以便建置產生可執行 JAR
./mvnw clean install
java -jar greeter/target/greeter-0.0.1-SNAPSHOT.jar
然後可以使用 curl 呼叫它
$ curl -H "Content-Type: text/plain" :8080/greeter -d World
Hello World
同樣地,要將函數部署為串流處理器,只需新增 "spring-cloud-function-stream" 依賴項,該依賴項又建立在 Spring Cloud Stream 之上。正如 Spring Cloud Stream 提供了一個 Binder 抽象,消除了定義 Channel Adapters 的需要,Spring Cloud Function 消除了宣告元件(例如 Service Activators、Transformers,甚至 Spring Cloud Stream 委派給的 @StreamListener
註解方法)的需要。"spring-cloud-function-stream" JAR 本身提供了所有這些。這是將控制反轉提升到另一個層次的又一個案例。
在本部落格系列的第 2 部分中,我們將提供範例說明如何在下一版本的 Spring Cloud Data Flow 中使用 Suppliers
、Functions
和 Consumers
。基本概念是,每當您需要提供一些自訂邏輯時,您可以只實作簡單的函數。這是意見主導模型的完美範例,您不僅不需要提供樣板程式碼,而且框架最好還是處理它。例如,您將能夠僅註冊函數 - 以內聯或封裝為 JAR 的形式(而不是 Spring Cloud Stream 應用程式),然後在 DSL 中引用這些函數,同時依賴 Spring Cloud Data Flow 為您包裝它們
mySupplier | myFunction | myConsumer
部署配置文件甚至擴展到無伺服器(又名函數即服務)供應商的領域,例如 AWS Lambda 和 Apache OpenWhisk(以及 Azure Functions 和 Google Cloud Functions,一旦它們提供 Java 支援)。在本部落格系列的第 3 部分中,我們將更深入地探討該主題,但現在您可以仔細閱讀 AWS Lambda 適配器和 Apache OpenWhisk 適配器的文件。即將發表的部落格也將涵蓋與基於 Kubernetes 的無伺服器框架(例如 Fission)的整合。
除了將業務邏輯和基礎架構解耦的角色之外,各種部署配置文件 JAR 和 FaaS 適配器還提高了可移植性。開發人員可以完全隔離地實作函數,包括僅關注輸入和輸出參數的單元測試。然後,可以將該函數與允許它在目標環境中運行的依賴項一起封裝,範圍從獨立 REST 應用程式到 Spring Cloud Data Flow 或 FaaS 供應商。
這將我們帶到了本入門部落格的最後一點。「無伺服器」一詞引起了很多反彈,並且幾乎總是接著解釋:「當然仍然有伺服器,但您不必考慮它們。」因此,雖然我們會抵制引入「無框架」一詞,但相同的概念確實可以應用於框架。在上面的 Spring Cloud Data Flow 範例中,函數開發人員不需要考慮框架,甚至不需要產生在其依賴項中具有任何框架程式碼的工件。相同的想法也適用於 FaaS 適配器。我們基本上是將控制反轉推向極致,以至於我們可以將好萊塢原則扭曲為:「不要依賴我們,我們會依賴您」。這在好萊塢可能不受歡迎,但對於開發人員來說,這意味著您可以只編寫一個函數,將其封裝在 JAR 中,並註冊以用於各種端點或適配器。與往常一樣,Spring 遵循 Alan Kay 雄辯地陳述的原則:「簡單的事情應該簡單。複雜的事情應該是可能的。」在即將發表的部落格文章中,我們將深入探討由於 Spring Cloud Function 而成為可能的一些更複雜的事情,但我們永遠不會忘記保持簡單的事情簡單。
敬請關注!