MicroProfile REST 客户端上的容错@Asynchronous 导致 windows 上的 open liberty 核心转储

Fault tolerance @Asynchronous on MicroProfile REST client cause open liberty core dump on windows

REST 客户端上的容错@Asynchronous-annotation 导致 Windows 上的核心转储和 MacOS 上的以下错误:

 *** java.lang.instrument ASSERTION FAILED ***: "!errorOutstanding" with message transform method call failed at ./src/java.instrument/share/native/libinstrument/JPLISAgent.c line: 873

受影响的版本:(Open Liberty 20.0.0.6/wlp-1.0.41.cl200620200528-0414) 在 OpenJDK 64 位服务器虚拟机上,版本 11.0.8+10-LTS

使用的功能:

[appSecurity-3.0, beanValidation-2.0, cdi-2.0, concurrent-1.0, distributedMap-1.0, ejbLite-3.2, el-3.0, jaxb-2.2, jaxrs-2.1, jaxrsClient-2.1, jdbc-4.2, jndi-1.0, jpa-2.2, jpaContainer-2.2, json-1.0, jsonb-1.0, jsonp-1.1, monitor-1.0, mpConfig-1.4, mpFaultTolerance-2.1, mpHealth-2.2, mpMetrics-2.3, mpOpenAPI-1.1, mpRestClient-1.4, requestTiming-1.0, servlet-4.0, ssl-1.0, transportSecurity-1.0].

重新制作:

@ApplicationScoped
@RegisterRestClient(baseUri = "https://postman-echo.com")
public interface TestingClient {

@GET
@Asynchronous
@Path("delay/4")
@Consumes(value = MediaType.APPLICATION_JSON)
CompletionStage<Response> doesItCrashWithDelay(String dummyData);

注入它:

@Inject
@RestClient
private TestingClient testingClient;

使用它:

@GET
@Path("doesitcrash")
public void doesItCrash() {
    final Response response = testingClient.doesItCrashWithDelay("dummydata").toCompletableFuture().join();
    logger.info(response.readEntity(String.class));
}

解决方法是让另一个 CDI bean 调用具有容错注释的其余客户端。但是根据这个博客 post REST 客户端接口应该能够有容错注释: https://openliberty.io/blog/2020/06/04/asynchronous-programming-microprofile-fault-tolerance.html

由于 CompletionStage 而已经异步的 REST 客户端是否允许 @Asynchronous?如前所述,@Timeout 和@Retry 等所有其他注释似乎都有效。

首先,您 100% 正确,您不需要在 MP Rest Client 接口方法上使用 @Asynchronous 注释 - 根据 MP Rest Client specification,一种 return 类型的 CompletionStage 使其异步。如果删除 @Asynchronous 注释,它应该可以工作。

在调查 JVM 错误消息时,我遇到了这条 helpful post,表明这条消息意味着 JVM 遇到了一个超大异常 - 可能是 WhosebugError。我的猜测是错误的发生是因为现在有两种不同的异步机制(MP Rest Client 和 MP Fault Tolerance)一起玩 - 并且可能玩得不好。如果没有看到异常堆栈跟踪,我们将无法确定。

我首先建议删除注释并验证它是否有效——这可能是比使用单独的 CDI bean 更好的解决方法。接下来,我建议在 https://github.com/OpenLiberty/open-liberty/issues 打开一个问题来研究更好的整体解决方案。