可觀測性
Spring 透過 Micrometer 提供可觀測性支援,它定義了一個 觀測概念,該概念可以在應用程式中同時實現指標和跟蹤。
Spring Cloud Stream 在 Spring Cloud Function 層面集成了此類支援,透過提供ObservationFunctionAroundWrapper等抽象,該包裝器包裝函式以開箱即用地處理觀測。
所需依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-core-micrometer</artifactId>
</dependency>
以及其中一個可用的跟蹤器橋接器。例如 Zipkin Brave
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-tracing-bridge-brave</artifactId>
</dependency>
命令式函式
命令式函式被觀測包裝器 ObservationFunctionAroundWrapper 包裝,該包裝器提供了與觀測登錄檔互動所需的基礎設施。此類交互發生在函式的每次呼叫中,這實際上意味著觀測附加到函式的每次呼叫(即,每條訊息一個觀測)。換句話說,對於命令式函式,如果存在前面提到的所需依賴,可觀測性將直接生效。
響應式函式
響應式函式與命令式函式本質上不同,因此不使用 ObservationFunctionAroundWrapper 包裝。
命令式函式是一個訊息處理函式,每當有訊息時,框架都會呼叫它,類似於您典型的事件處理程式,對於 N 條訊息,將有 N 次此類函式的呼叫。這允許我們包裝此類函式,用附加功能(如錯誤處理、重試以及當然還有可觀測性)來裝飾它。
響應式函式是初始化函式。它的作用是將使用者提供的流處理程式碼 (Flux) 與繫結器提供的源流和目標流連線起來。它在應用程式啟動期間只被呼叫一次。一旦流程式碼與源/目標流連線,我們就無法看到或控制實際的流處理。它由響應式 API 控制。響應式函式還帶來了一個附加變數。鑑於該函式為您提供了整個流鏈的可見性(不僅僅是單個事件),那麼觀測的預設單位應該是什麼?流鏈中的單個專案?一個範圍的項?如果一段時間後沒有訊息怎麼辦?等等……我們想要強調的是,對於響應式函式,我們不能假設任何事情。(有關響應式函式和命令式函式之間差異的更多資訊,請參閱 響應式函式)。
因此,就像重試和錯誤處理一樣,您需要手動處理觀測。
幸運的是,您可以透過使用響應式 API 的 tap 操作並提供 ObservationRegistry 例項來輕鬆地對流的一部分進行觀測。此類部分定義了一個觀測單位,它可以是 flux 中的單個項、一個範圍或您可能希望在流中觀測的任何其他內容。
@SpringBootApplication
public class DemoStreamApplication {
Logger logger = LoggerFactory.getLogger(DemoStreamApplication.class);
public static void main(String[] args) {
Hooks.enableAutomaticContextPropagation();
SpringApplication.run(DemoStreamApplication.class, args);
}
@Bean
public Function<Flux<String>, Flux<String>> uppercase(ObservationRegistry registry) {
return flux -> flux.flatMap(item -> {
return Mono.just(item)
.map(value -> value.toUpperCase())
.doOnNext(v -> logger.info(v))
.tap(Micrometer.observation(registry));
});
}
}
上面的示例模擬了將 觀測 附加到單個訊息處理(即命令式函式),因為在這種情況下,觀測單位以 Mono.just(..) 開始,最後一個操作將 ObservationRegistry 附加到訂閱者。
如果訂閱者已附加觀測,則將使用該觀測為 tap 上游的鏈/段建立一個子觀測,但是如我們所述,預設情況下,框架不會將任何觀測附加到您返回的流鏈。