猿问

WLPs MicroProfile (FaultTolerance) 超时实现不中断线程?

我正在测试 websphere 自由的容错(微配置文件)实现。因此,我制作了一个简单的 REST-Service,其中的资源可以休眠 5 秒:


 @Path("client")

 public class Client {


      @GET

      @Path("timeout")

      public Response getClientTimeout() throws InterruptedException {

          Thread.sleep(5000);

          return Response.ok().entity("text").build();

      }

 }

我在另一个 REST 服务的同一个应用程序中调用这个客户端:


 @Path("mpfaulttolerance")

 @RequestScoped

 public class MpFaultToleranceController {


      @GET

      @Path("timeout")

      @Timeout(4)

      public Response getFailingRequest() {

          System.out.println("start");

          // calls the 5 seconds-ressource; should time out

          Response response = ClientBuilder.newClient().target("http://localhost:9080").path("/resilience/api/client/timeout").request().get();

          System.out.println("hello");

      }

 }

现在我希望 getFailingRequest() 方法会在 4 毫秒后超时并抛出异常。实际行为是应用程序打印“start”,等待 5 秒直到客户端返回,打印“hello”然后抛出“org.eclipse.microprofile.faulttolerance.exceptions.TimeoutException”。


我打开了进一步的调试信息:


<logging traceSpecification="com.ibm.ws.microprofile.*=all" />

在 server.xml 中。我得到了这些信息,即使在调用客户端之前也注册了超时!但是线程不会被中断。


(如果有人告诉我如何在这里获得漂亮的堆栈跟踪......我可以做到。)


因为这是一个非常基本的例子:我在这里做错了什么吗?我该怎么做才能使此示例正常运行。


谢谢


编辑:在 WebSphere Application Server 18.0.0.2/wlp-1.0.21.cl180220180619-0403) auf Java HotSpot(TM) 64 位服务器 VM,版本 1.8.0_172-b11 (de_DE) 上运行此示例,具有 webProfile-8.0 功能, mpFaultTolerance-1.0 和 localConnector-1.0。


编辑:解决方案,感谢 Andy McCright 和 Azquelt。由于调用不能被中断,我必须使其异步。所以你有 2 个线程:第一个线程通过调用调用第二个线程。第一个线程将被中断,第二个线程将一直保持到调用完成。但是现在您可以继续进行故障处理,打开电路等等,以防止进一步调用损坏的服务。


@Path("mpfaulttolerance")

@RequestScoped

public class MpFaultToleranceController {


    @Inject

    private TestBase test;


    @GET

    @Path("timeout")

    @Timeout(4)

    public Response getFailingRequest() throws InterruptedException, ExecutionException {

        Future<Response> resp = test.createFailingRequestToClientAsynch();

        return resp.get();

    }

}


慕尼黑的夜晚无繁华
浏览 163回答 2
2回答

小唯快跑啊

它确实使用 中断线程Thread.interrupt(),但不幸的是,并非所有 Java 操作都响应线程中断。许多事情抛出一个InterruptedException(如做响应中断Thread.sleep(),Object.wait(),Future.get()和子类的InterruptableChannel),但InputStreams和插座没有。我怀疑您(或您用来发出请求的库)正在使用不可中断的 Socket,因此您看不到您的方法提前返回。这尤其不直观,因为 Liberty 的 JAX-RS 客户端不会像 Andy McCright 提到的那样响应线程中断。我们知道这不是一个很好的情况,我们正在努力让它变得更好。

UYOU

我有同样的问题。对于我使用的某些 URL,容错超时不起作用。就我而言,我使用 RestClient。我使用 RestClientBuilder 的 readTimeout() 解决了我的问题:MyRestClientClass&nbsp;myRestClientClass&nbsp;=&nbsp;RestClientBuilder.newBuilder().baseUri(uri).readTimeout(3l,&nbsp;TimeUnit.SECONDS)&nbsp;.build(MyRestClientClient.class);使用此超时控件的一个优点是您可以将超时作为参数传递。
随时随地看视频慕课网APP

相关分类

Java
我要回答