保持領先
VMware 提供培訓和認證,助你加速進步。
瞭解更多我們很高興宣佈,經過長時間的內部孵化,我們將釋出一個用於 JVM 非同步應用的基礎框架,我們稱之為 Reactor。它為 Java、Groovy 和其他 JVM 語言提供了抽象,使構建事件驅動和資料驅動的應用更加容易。它也非常快。在普通硬體上,使用最快的非阻塞 Dispatcher
可以每秒處理超過 15,000,000 個事件。還提供其他分發器(dispatcher),為開發者提供多種選擇,從執行緒池風格、長時間執行的任務執行到非阻塞、大容量任務分發。GitHub 倉庫在這裡 https://github.com/reactor/reactor。
正如其名稱所示,Reactor 深受 著名的 Reactor 設計模式 的影響。但它也受到其他事件驅動設計實踐以及多年來開發的幾種優秀的基於 JVM 的解決方案的影響。Reactor 的目標是將這些思想和模式濃縮成一個簡單且可重用的基礎,使事件驅動程式設計變得更加容易。
Reactor 的抽象為開發者提供了一套工具,不僅可以開發,還可以以更高效地利用系統資源的方式 組合 應用——這在雲環境中執行時尤為重要——並減少或消除目前困擾大多數非同步應用的巢狀回撥的“義大利麵條式”程式碼(恰如其分地稱為 “回撥地獄”)。
雖然由於其固有的靈活性,你可以讓 Reactor 做很多事情,但它真正的設計目標是作為一個基礎框架,用於那些在執行相對小的無狀態非同步處理塊時需要高吞吐量的應用。現代應用中非人工生成的資料的巨大數量很容易超過傳統的單執行緒阻塞設計模式。從生成位置資訊流的移動應用到傳送大量幾何資料的自動化製造機器,再到挖掘即時日誌以生成業務指標的大資料應用:現代資料驅動應用需要比傳統的命令式、阻塞式應用通常能提供的更好的資源利用率和更高的吞吐量。
這就是為什麼 Spring XD 專案(以及其他幾個 Spring 生態系統專案,如 Spring Integration 和 Spring Batch)打算利用 Reactor。將 Reactor 的非同步分發與 Spring Integration 基於 NIO 的 TCP 介面卡結合使用,以提供高吞吐量的 syslog 和 MQTT 攝取,這只是一個例子。
Reactor 的 reactor-core 模組中最基礎的三個元件是 Selector
、Consumer
和 Event
。可以使用 Selector
將 Consumer
分配給 Reactor
,Selector
是一種簡單的抽象,可在查詢要針對 Event
呼叫的 Consumer
時提供靈活性。提供了一系列預設的 Selector。從普通字串到正則表示式,再到 Spring MVC 風格的 URL 模板
這裡有一些示例程式碼,展示了使用 Reactor 建立事件驅動應用有多麼容易
// This helper method is like jQuery’s.
// It creates a Selector instance so you don’t have
// to construct one using 'new Selector("parse")'
import static reactor.Fn.$;
Reactor reactor = R.create();
// Register interest in events published to key "parse"
reactor.on($("parse"), new Consumer<Event<String>>() {
public void call(Event<String> ev) {
service.handleEvent(ev);
}
});
// Send an event to this Reactor and trigger all actions
// that match the given Selector
reactor.notify("parse", Fn.event("Hello World!"));
Reactor 分發版中包含一個名為 reactor-groovy
的模組。它包含 Groovy 繫結,提供了富有表現力的語法,使用 @CompileStatic
進行編譯時檢查,將 Closure
隱式轉換為 Consumer
,以及其他 Groovy 特有的節省時間的功能。
// Assign a Closure as a Consumer
reactor.on($('hello')) { Event<String> ev ->
if(ev.headers['specialHeader']) { // Events can have metadata
doSomethingWith(ev.data)
}
}
// Use Groovy helpers for notify
reactor.notify for: 'hello', data: 'Hello World!', specialHeader: 'specialValue'
最好的部分是:我們無需犧牲效能來實現這一目標。適用於 Java 程式碼的 JVM 最佳化同樣適用於 Groovy 程式碼。我們持續(有些人可能會說“執著地”)對分發程式碼進行微基準測試,使其儘可能快,併為 Java 和 Groovy 使用者提供最高的吞吐量。
Reactor 的設計也對 Java SE 8 的 Lambda 表示式 友好,Reactor 中的許多元件可以用 Lambda 替換,使你的 Java 程式碼更簡潔。我們還發現,使用 Java 8 的 Lambda(和方法引用)可以獲得稍高的吞吐量。當 Java 8 正式釋出時,你無需等待 Reactor 支援它。它會“just work”(開箱即用)。
// Use a POJO as an event handler
class Service {
public <T> void handleEvent(Event<T> ev) {
// handle the event data
}
}
@Inject
Service service;
// Use a method reference to create a Consumer<Event<T>>
reactor.on($("parse"), service::handleEvent);
// Notify consumers of the 'parse' topic that data is ready
// by passing a Supplier<Event<T>> in the form of a lambda
reactor.notify("parse", () -> {
slurpNextEvent()
});
Executor、Event Loop、Actor、分散式——在事件驅動程式設計中最重要的用例之一(任務分發)有很多實現形式。Reactor 支援多種風格的事件驅動程式設計。除了傳統的面向回撥的 Consumer
介面外,Reactor 還對 Promises/A+ 規範 進行了詮釋,使得處理延遲值(deferred values)和消費者(consumers)變得非常容易。
巢狀回撥雖然在像 Java 這樣的命令式語言中直觀易用,但當應用複雜度增加時,維護起來就會變得困難。Reactor 的 Composable
和 Promise
的核心是輕鬆組合操作。你可以將一個 Composable
連結成一系列操作,用於轉換值、將資料儲存到資料儲存、聚合值等等。而且由於它們可以鏈式呼叫,你可以在純 Java 中以型別安全的方式完成所有這些操作。這裡有一個快速示例,展示瞭如何使用 Composable
輕鬆連結一系列非同步執行的任務,這些任務在資料流透過 Composable
時對其進行轉換和過濾
Composable<Integer> c = new Composable<>()
.map(new Function<Integer, Integer>() {
public Integer apply(Integer i) {
return i % 2;
}
})
.filter(new Function<Integer, Boolean>() {
public Boolean apply(Integer i) {
return i == 0;
}
})
.consume(new Consumer<Integer>() {
public void accept(Integer eveni) {
// work with only even numbers here
}
});
Composable
的每個步驟都是一個潛在的非同步任務。對 map
、filter
和 consume
的呼叫會指定在前一步驟的值可用時執行的任務——無需陷入回撥地獄。
對於任何分發問題都沒有萬能的解決方案。Reactor 提供了不同風格的 Dispatcher
,因為每個非同步應用在不同部分有不同的分發需求。例如,在攝取海量資料時,Reactor
會希望使用基於 著名的 Disruptor RingBuffer 的高速非阻塞 Dispatcher
。但如果 Reactor
正在向資料庫伺服器發出阻塞呼叫或將大量資料儲存到 S3 中,它會希望利用吞吐量較低的工作執行緒池 Dispatcher
。Reactor 提供了多種選擇,以便你可以為特定任務選擇合適的工具。
如果內建的 Dispatcher
實現不符合你的需求,那麼 Reactor 提供了一個堅實的基礎,你可以在此基礎上構建自己的、針對特定問題領域定製的 Dispatcher
。
Grails 是一個用於 JVM 的全棧 Web 應用框架。儘管其程式碼庫成熟且擁有蓬勃發展的社群,但 Grails 仍然面臨 新的架構挑戰。事件透過 platform-core 外掛 引入 Grails。但事件功能如此強大,以至於它真正應該屬於核心;因此,從 2.3 版本開始,Grails 應用將內建一個極其強大但易於使用、基於約定的事件 API,其外觀和功能與當前 platform-core 外掛中的實現非常相似。此事件 API 將建立在 Reactor 的基礎之上。
將事件整合到 Grails 中的目標是針對新型開發——特別是“即時 Web”和大規模、非阻塞應用開發。結合非同步 GORM 特性,事件 API 將證明是一個強大的盟友。訪問大資料儲存的複雜查詢——因此需要很長時間處理——可以在結果準備好時透過直接將結果推送到瀏覽器來響應。
在接下來的幾個月裡,我們將努力為 SpringOne 做準備,屆時我們將重點展示我們的大資料、快速、可擴充套件的資料解決方案。如果你還沒有計劃參加,你絕對應該參加!我們將舉辦一個 關於 Reactor 的專題討論會,以及如何使用它建立大規模、高吞吐量的事件驅動應用。
但沒有你,我們無法做到!這項努力只有在你幫助我們為 JVM 上的大資料、快速、事件驅動應用開發建立一個充滿熱情和活力的社群才能成功。如果你感興趣,請檢視 GitHub 上的原始碼,檢視 reactor-quickstart 中的一些示例程式碼,報告你發現的任何問題,在 StackOverflow 上使用 #reactor 標籤 提問有關 Reactor 的問題,加入 reactor-framework Google Groups 郵件列表 的討論,或者 fork 倉庫 幫助新增功能、調整以獲得更高吞吐量以及貢獻新想法。
我們期待在那裡見到你!