spring boot 2 执行器端点不支持服务器发送事件 (SSE)
springboot2 actuator endpoint not supporting Server Sent Event(SSE)
我正在尝试使用 SSE 将一些指标公开为流。我能够使用来自 restController 的 SSE 事件,但是当我添加自定义执行器端点时,它只是以正确的方式关闭连接。
@Component
@Endpoint(id = "test")
public class StreamMetrics {
@ReadOperation
public Flux<ServerSentEvent<String>> streamEvents() {
return Flux.interval(Duration.ofSeconds(1))
.map(sequence -> ServerSentEvent.<String> builder()
.id(String.valueOf(sequence))
.event("pingpong")
.data("ping")
.build());
}
}
结果
curl -n -v http://localhost:9080/actuator/test
* Trying ::1:9080...
* TCP_NODELAY set
* Connected to localhost (::1) port 9080 (#0)
> GET /actuator/test HTTP/1.1
> Host: localhost:9080
> User-Agent: curl/7.68.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< transfer-encoding: chunked
< Content-Type: text/event-stream;charset=UTF-8
<
id:0
event:pingpong
data:ping
* Connection #0 to host localhost left intact
这在第一个事件后立即终止
其中
@RestController
@RequestMapping(value = "/test")
public class SSETest {
@GetMapping("/stream-sse")
public Flux<ServerSentEvent<String>> streamEvents() {
return Flux.interval(Duration.ofSeconds(1))
.map(sequence -> ServerSentEvent.<String> builder()
.id(String.valueOf(sequence))
.event("pingpong")
.data("ping")
.build());
}
}
结果
curl -v -n http://localhost:9080/test/stream-sse
* Trying ::1:9080...
* TCP_NODELAY set
* Connected to localhost (::1) port 9080 (#0)
> GET /test/stream-sse HTTP/1.1
> Host: localhost:9080
> User-Agent: curl/7.68.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< transfer-encoding: chunked
< Content-Type: text/event-stream;charset=UTF-8
<
id:0
event:pingpong
data:ping
id:1
event:pingpong
data:ping
id:2
event:pingpong
data:ping
这会继续下去而不会被终止。
终止事件(连续流)的端点注释有什么特别之处?
我在“2.2.4”和“2.3.0”中对此进行了测试
我找到了答案。 @ReadOperation(produces = "text/event-stream") 将更改执行器端点中的默认内容类型 application/vnd.spring-boot.actuator.v3+json。没有文档所以我看了代码
@Component
@Endpoint(id = "test")
public class StreamMetrics {
@ReadOperation(produces = "text/event-stream")
public Flux<ServerSentEvent<String>> streamEvents() {
return Flux.interval(Duration.ofSeconds(1))
.map(sequence -> ServerSentEvent.<String> builder()
.id(String.valueOf(sequence))
.event("pingpong")
.data("ping")
.build());
}
}
我正在尝试使用 SSE 将一些指标公开为流。我能够使用来自 restController 的 SSE 事件,但是当我添加自定义执行器端点时,它只是以正确的方式关闭连接。
@Component
@Endpoint(id = "test")
public class StreamMetrics {
@ReadOperation
public Flux<ServerSentEvent<String>> streamEvents() {
return Flux.interval(Duration.ofSeconds(1))
.map(sequence -> ServerSentEvent.<String> builder()
.id(String.valueOf(sequence))
.event("pingpong")
.data("ping")
.build());
}
}
结果
curl -n -v http://localhost:9080/actuator/test
* Trying ::1:9080...
* TCP_NODELAY set
* Connected to localhost (::1) port 9080 (#0)
> GET /actuator/test HTTP/1.1
> Host: localhost:9080
> User-Agent: curl/7.68.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< transfer-encoding: chunked
< Content-Type: text/event-stream;charset=UTF-8
<
id:0
event:pingpong
data:ping
* Connection #0 to host localhost left intact
这在第一个事件后立即终止
其中
@RestController
@RequestMapping(value = "/test")
public class SSETest {
@GetMapping("/stream-sse")
public Flux<ServerSentEvent<String>> streamEvents() {
return Flux.interval(Duration.ofSeconds(1))
.map(sequence -> ServerSentEvent.<String> builder()
.id(String.valueOf(sequence))
.event("pingpong")
.data("ping")
.build());
}
}
结果
curl -v -n http://localhost:9080/test/stream-sse
* Trying ::1:9080...
* TCP_NODELAY set
* Connected to localhost (::1) port 9080 (#0)
> GET /test/stream-sse HTTP/1.1
> Host: localhost:9080
> User-Agent: curl/7.68.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< transfer-encoding: chunked
< Content-Type: text/event-stream;charset=UTF-8
<
id:0
event:pingpong
data:ping
id:1
event:pingpong
data:ping
id:2
event:pingpong
data:ping
这会继续下去而不会被终止。
终止事件(连续流)的端点注释有什么特别之处?
我在“2.2.4”和“2.3.0”中对此进行了测试
我找到了答案。 @ReadOperation(produces = "text/event-stream") 将更改执行器端点中的默认内容类型 application/vnd.spring-boot.actuator.v3+json。没有文档所以我看了代码
@Component
@Endpoint(id = "test")
public class StreamMetrics {
@ReadOperation(produces = "text/event-stream")
public Flux<ServerSentEvent<String>> streamEvents() {
return Flux.interval(Duration.ofSeconds(1))
.map(sequence -> ServerSentEvent.<String> builder()
.id(String.valueOf(sequence))
.event("pingpong")
.data("ping")
.build());
}
}