java - RestEasy 异步 Controller 正确使用

标签 java multithreading rest asynchronous resteasy

我正在尝试使用 RestEasy 创建异步 REST 服务,但我找不到任何显示这样做的干净方法的文档。我发现的唯一例子在这里:

https://github.com/resteasy/Resteasy/blob/master/jaxrs/async-http-servlet-3.0/async-http-servlet-3.0-test/src/main/java/org/jboss/resteasy/test/async/JaxrsResource.java

   @GET
   @Produces("text/plain")
   public void get(@Suspended final AsyncResponse response) throws Exception
   {
      response.setTimeout(2000, TimeUnit.MILLISECONDS);
      Thread t = new Thread()
      {
         @Override
         public void run()
         {
            try
            {
               System.out.println("STARTED!!!!");
               Thread.sleep(100);
               Response jaxrs = Response.ok("hello").type(MediaType.TEXT_PLAIN).build();
               response.resume(jaxrs);
            }
            catch (Exception e)
            {
               e.printStackTrace();
            }
         }
      };
      t.start();
   }

在方法中创建新线程似乎不是在生产环境中执行操作的最佳方法。我觉得我应该从线程池或其他东西中获取线程。

任何建议或指向更好示例的链接都会非常有帮助。

最佳答案

您关于使用线程池的看法是正确的。让 Spring 为您处理它。

假设您使用 Spring 作为应用程序的选择,您可以执行类似的操作。

您可以为异步执行器定义配置类。

@EnableAsync
@Configuration
public class AsyncConfiguration implements AsyncConfigurer {

    @Inject
    private Environment env;

    @Bean
    @Override
    @Singleton
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
        taskExecutor.setCorePoolSize(env.getProperty("controller.threadPoolTaskExecutor.corePoolSize", Integer.class, 10));
        taskExecutor.setMaxPoolSize(env.getProperty("controller.threadPoolTaskExecutor.maxPoolSize", Integer.class, 100));
        taskExecutor.setKeepAliveSeconds(env.getProperty("controller.threadPoolTaskExecutor.keepAliveSeconds", Integer.class, 60*5));
        taskExecutor.setQueueCapacity(env.getProperty("controller.threadPoolTaskExecutor.queueCapacity", Integer.class, 10000));
        taskExecutor.setThreadNamePrefix("controller-async-task-executor");
        return taskExecutor;
    }

    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return new AsyncExceptionHandler();
    }

}

以下是定义异常处理程序的方法:

public class AsyncExceptionHandler implements AsyncUncaughtExceptionHandler {

    private static final Logger logger = LoggerFactory.getLogger(AsyncExceptionHandler.class);

    @Override
    public void handleUncaughtException(Throwable ex, Method method, Object... params) {
        logger.error("Error processing async request in method: " + method.getName(), ex);
    }   
}

您的 Controller 如下所示:

@Inject
private AsyncTaskExecutor asyncTaskExecutor; 

@GET
@Produces("text/plain")
public void get(@Suspended final AsyncResponse response) throws Exception
{
    response.setTimeout(2000, TimeUnit.MILLISECONDS);
    asyncTaskExecutor.submit(() -> {
        System.out.println("STARTED!!!!");
        Thread.sleep(100);
        Response jaxrs = Response.ok("hello").type(MediaType.TEXT_PLAIN).build();
        response.resume(jaxrs);
    });
}

关于java - RestEasy 异步 Controller 正确使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34912743/

相关文章:

java - 无法捕获 Kafka TopicExistsException

java - (Java) 静态泛型方法与泛型类静态方法

java - Spring REST,用户资源和密码

.net - rabbitmq 的 REST API

Java int 和 char 之间的隐式转换

java - 实现 IWorkbenchPreferencePage 在查看首选项页面时会出现 NPE

C++ pthread 条件信号

c++ - 为什么互斥锁不需要互斥锁(而那个互斥锁需要互斥锁...)

java - 同步关键字在内部如何工作

c# - ASP.Net Cookie 未保存到浏览器