領先一步
VMware 提供培訓和認證,助您加速發展。
瞭解更多Spring Cloud Function 是一個新專案,其主要目標如下
正如 Spring 一直推廣基於普通舊 Java 物件(POJO)的程式設計模型一樣,Spring Cloud Function 推廣基於普通舊函式的程式設計模型。這意味著 java.util.function
包中定義的核心介面:Function
、Consumer
和 Supplier
。
這些型別的實現可以透過顯式或隱式方式註冊為 bean,透過 @FunctionScan
啟用的類路徑掃描。引數和/或返回型別可以選擇使用 Reactor 的 Flux
,它是一個 Reactive Streams Publisher
。這使得與其他的 Reactive Streams 元件(即使是基於其他實現的,如 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;
}
}
但是如果您需要實現將資料集作為處理單元的函式,透過視窗化或歸約操作,您可以使用 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 現在常用一樣。
您可能會問,既然您可以輕鬆建立 Function
、Consumer
和 Supplier
例項,為什麼 Spring 推廣這種模型是必要的。答案涉及控制反轉(Inversion of Control),這應該不足為奇。多年來,從基本的依賴注入到 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 本身提供了所有這些功能。這是將控制反轉提升到另一個層次的又一個案例。
在本部落格系列的第二部分,我們將提供關於如何在下一版 Spring Cloud Data Flow 中使用 Suppliers
、Functions
和 Consumers
的示例。基本思想是,無論何時您需要提供一些自定義邏輯,您都可以簡單地實現函式。這是一個有主見的模型的完美示例,您不僅不需要提供樣板程式碼,而且最好還是讓框架來處理這些。例如,您將能夠只註冊函式——可以是內聯的,也可以打包成 JAR(而不是 Spring Cloud Stream 應用),然後在 DSL 中引用它們,同時依靠 Spring Cloud Data Flow 為您包裝它們
mySupplier | myFunction | myConsumer
部署配置檔案甚至擴充套件到了無伺服器(又稱函式即服務,FaaS)提供商領域,例如 AWS Lambda 和 Apache OpenWhisk(以及一旦支援 Java 的 Azure Functions 和 Google Cloud Functions)。在本部落格系列的第三部分,我們將深入探討該主題的更多細節,但現在您可以查閱 AWS Lambda 介面卡 和 Apache OpenWhisk 介面卡 的文件。即將釋出的部落格也將涵蓋與基於 Kubernetes 的無伺服器框架(如 Fission)的整合。
除了將業務邏輯與基礎設施解耦的作用之外,各種部署配置檔案 JAR 和 FaaS 介面卡還提高了可移植性。開發人員可以完全獨立地實現一個函式,包括只關注輸入和輸出引數的單元測試。然後可以將該函式與允許其在目標環境中執行的依賴項一起打包,目標環境範圍從獨立的 REST 應用到 Spring Cloud Data Flow 或 FaaS 提供商。
這帶我們來到了這篇介紹性部落格的最後一點。“無伺服器”(Serverless)一詞引起了很多反對,並且幾乎總是伴隨著解釋:“當然仍然有伺服器,但您無需考慮它們。” 因此,雖然我們將避免引入“無框架”(Frameworkless)一詞,但相同的概念確實可以應用於框架。在上面的 Spring Cloud Data Flow 示例中,函式開發人員無需考慮框架,甚至不需要生成其依賴項中包含任何框架程式碼的 artifact。同樣的想法也適用於 FaaS 介面卡。我們基本上是將控制反轉推向極致,可以將好萊塢原則扭轉為:“不要依賴我們,我們將依賴您”。這在好萊塢可能行不通,但對於開發人員來說,這意味著您只需編寫一個函式,將其打包到 JAR 中,然後註冊它以便與各種端點或介面卡一起使用。Spring 一如既往地遵循 Alan Kay 巧妙闡述的原則:“簡單的事情應該簡單。複雜的事情應該成為可能。” 在即將釋出的部落格文章中,我們將深入探討由於 Spring Cloud Function 而可能實現的一些更復雜的事情,但我們永遠不會忘記保持簡單的事情簡單。
敬請關注!