領先一步
VMware 提供培訓和認證,助您加速進步。
瞭解更多Spring Cloud Function 是一個新專案,具有以下高階目標
正如Spring一直推崇基於普通Java物件(POJO)的程式設計模型一樣,Spring Cloud Function推崇一種基於普通舊函式的程式設計模型。我們指的是java.util.function包中定義的核心介面:Function、Consumer和Supplier。
這些型別的實現可以作為bean註冊,可以透過顯式註冊,也可以透過@FunctionScan啟用的類路徑掃描隱式註冊。引數和/或返回型別可以選擇使用Reactor的Flux,它是一個Reactive Streams Publisher。這使得與Fux Reactive Streams的其他元件(甚至那些基於RxJava 2等其他實現的元件)的互操作性成為可能,並且它為這種處理模型帶來了非阻塞I/O和背壓等響應式特性(有關更多資訊,請參閱Project Reactor)。無論引數和/或返回型別是否為Flux,Spring Cloud Function都會將它們包裝起來,以便函式可以透過Flux進行互操作。對於簡單的逐項處理用例,您可以保持簡單。
public class Greeter implements Function<String, String> {
public String apply(String name) {
return "Hello " + name;
}
}
但是,如果您需要實現透過視窗或歸約操作將資料集作為處理單元的函式,則可以使用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表示式語言一樣。
您可能會問,既然您可以輕鬆建立Function、Consumer和Supplier例項,為什麼Spring還需要推廣這種模型。答案涉及控制反轉,這並不奇怪。多年來,從基本的依賴注入到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抽象以消除定義通道介面卡的需要一樣,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可能實現的更復雜的事情,但我們永遠不會忘記保持簡單事情的簡單。
敬請期待!