【发布时间】:2020-05-22 14:04:22
【问题描述】:
通过使用 Blockhound io.projectreactor.tools blockhound-junit-platform,我发现 UUID.randomUUID 是一个阻塞调用,这对我们来说是个问题,因为我们使用的是 Spring Boot Webflux 2.2 版。 2.发布
是否有任何其他方法可以以非阻塞方式获取随机 uuid,或者是否有任何其他 java 库推荐用于非阻塞生成随机字符串。
blockhound 的堆栈跟踪:
java.lang.Error: Blocking call! java.io.FileInputStream#readBytes
at reactor.blockhound.BlockHound$Builder.lambda$new$0(BlockHound.java:196) ~[blockhound-1.0.1.RELEASE.jar:na]
Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException:
Error has been observed at the following site(s):
|_ checkpoint ⇢ org.springframework.boot.actuate.metrics.web.reactive.server.MetricsWebFilter [DefaultWebFilterChain][ExceptionHandlingWebHandler]
Stack trace:
at reactor.blockhound.BlockHound$Builder.lambda$new$0(BlockHound.java:196) ~[blockhound-1.0.1.RELEASE.jar:na]
at reactor.blockhound.BlockHound$Builder.lambda$install$6(BlockHound.java:318) ~[blockhound-1.0.1.RELEASE.jar:na]
at reactor.blockhound.BlockHoundRuntime.checkBlocking(BlockHoundRuntime.java:46) ~[na:na]
at java.base/java.io.FileInputStream.readBytes(FileInputStream.java) ~[na:na]
at java.base/java.io.FileInputStream.read(FileInputStream.java:279) ~[na:na]
at java.base/java.io.FilterInputStream.read(FilterInputStream.java:133) ~[na:na]
at java.base/sun.security.provider.NativePRNG$RandomIO.readFully(NativePRNG.java:424) ~[na:na]
at java.base/sun.security.provider.NativePRNG$RandomIO.ensureBufferValid(NativePRNG.java:526) ~[na:na]
at java.base/sun.security.provider.NativePRNG$RandomIO.implNextBytes(NativePRNG.java:545) ~[na:na]
at java.base/sun.security.provider.NativePRNG.engineNextBytes(NativePRNG.java:220) ~[na:na]
at java.base/java.security.SecureRandom.nextBytes(SecureRandom.java:741) ~[na:na]
at java.base/java.util.UUID.randomUUID(UUID.java:150) ~[na:na]
【问题讨论】:
-
这真的有问题吗?从操作系统随机数源获取足够的随机字节曾经是旧 Linux 版本的问题,但现在应该很快了。也许这只会在您第一次生成 UUID 时发生?
-
查看此主题以讨论为什么默认熵源可能很慢以及如何选择不同的源:stackoverflow.com/questions/137212/…
-
如果你确实遇到了缓慢并且不想阻塞你的“反应”线程,你可以在一个专用的工作池上生成所有 UUID,就像你对其他阻塞的事情一样。但这似乎有点矫枉过正。
-
这没有问题(除非播种 SecureRandom 真的很慢)。类加载也是阻塞的。不要落入过早的“优化”陷阱,而是专注于可证明的性能问题。
-
您应该查看第一条评论,了解为什么通话需要这么多时间。但通常要包装同步阻塞调用 Mono.fromCallable(UUID::randomUUID).subscribeOn(Schedulers.boundedElastic())
标签: java reactive-programming uuid spring-webflux project-reactor