Jersey ThreadPoolExecutorProvider 拒绝请求时如何发送服务器错误响应?
How can the server error response be sent when the Jersey ThreadPoolExecutorProvider rejects the request?
因此,在服务器端,我们扩展了 org.glassfish.jersey.spi.ThreadPoolExecutorProvider
以获得可运行任务的有界 BlockingQueue,覆盖了 corePoolSize 和 MaximumPoolSize。
当BlockingQueue的容量超过时(当有不能再排队的请求时),它开始拒绝任务(这和拒绝请求一样好)。
但我们观察到,当服务器端的任务在上述情况下被拒绝时,没有向客户端发送响应。最初我们甚至不知道请求是否被拒绝,但后来阅读了 java.util.concurrent.RejectedExecutionHandler
并且我们尝试实现一个 customHandler 并在创建一个 Executor 时传递它(请参考下面的代码片段)。
我现在可以看到任务被拒绝了,但不确定如何处理向客户端发送请求被拒绝的响应。如果我不这样做,那么客户端会一直等到超时。
我是否需要在泽西岛进行任何配置才能向客户端发送正确的响应。
@Override
protected ThreadPoolExecutor createExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler){
System.err.println("MANDAR_CREATED_EXECUTOR");
return super.createExecutor(corePoolSize, maximumPoolSize, keepAliveTime, workQueue, threadFactory, new CustomHandler());
}
class CustomHandler implements RejectedExecutionHandler {
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
System.err.println("MANDAR_REJECTED");
executor.remove(r);
executor.purge();
}
}
PS:我们用于实现 Jersey 层的样式是 this
解决方案有点像抛出 RejectedExecutionException。这是由 new ThreadPoolExecutor.AbortPolicy()
完成的。奇怪的是 AbortPolicy 是默认策略,在覆盖此 createExecutor 方法之前仍然没有触发。似乎 Jersey 对 Executor 的 RejectionExecutionHandler 的实现有点不同并且没有使用 AbortPolicy。
@Override
protected ThreadPoolExecutor createExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler){
return super.createExecutor(corePoolSize, maximumPoolSize, keepAliveTime, workQueue, threadFactory, new ThreadPoolExecutor.AbortPolicy());
}
编辑:
实际上更好的是覆盖 getRejectedExecutionHandler
方法,returns 基于 AbortyPolicy 的处理程序。
/**
* This method returns the handler that handles the rejected runnable tasks.
* We have initialized the handler to {@link AbortPolicy} that helps throwing a {@link RejectedExecutionException} which in turn returns 500 statusCode response
*/
@Override
protected RejectedExecutionHandler getRejectedExecutionHandler() {
return this.handler;
}
因此,在服务器端,我们扩展了 org.glassfish.jersey.spi.ThreadPoolExecutorProvider
以获得可运行任务的有界 BlockingQueue,覆盖了 corePoolSize 和 MaximumPoolSize。
当BlockingQueue的容量超过时(当有不能再排队的请求时),它开始拒绝任务(这和拒绝请求一样好)。
但我们观察到,当服务器端的任务在上述情况下被拒绝时,没有向客户端发送响应。最初我们甚至不知道请求是否被拒绝,但后来阅读了 java.util.concurrent.RejectedExecutionHandler
并且我们尝试实现一个 customHandler 并在创建一个 Executor 时传递它(请参考下面的代码片段)。
我现在可以看到任务被拒绝了,但不确定如何处理向客户端发送请求被拒绝的响应。如果我不这样做,那么客户端会一直等到超时。
我是否需要在泽西岛进行任何配置才能向客户端发送正确的响应。
@Override
protected ThreadPoolExecutor createExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler){
System.err.println("MANDAR_CREATED_EXECUTOR");
return super.createExecutor(corePoolSize, maximumPoolSize, keepAliveTime, workQueue, threadFactory, new CustomHandler());
}
class CustomHandler implements RejectedExecutionHandler {
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
System.err.println("MANDAR_REJECTED");
executor.remove(r);
executor.purge();
}
}
PS:我们用于实现 Jersey 层的样式是 this
解决方案有点像抛出 RejectedExecutionException。这是由 new ThreadPoolExecutor.AbortPolicy()
完成的。奇怪的是 AbortPolicy 是默认策略,在覆盖此 createExecutor 方法之前仍然没有触发。似乎 Jersey 对 Executor 的 RejectionExecutionHandler 的实现有点不同并且没有使用 AbortPolicy。
@Override
protected ThreadPoolExecutor createExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler){
return super.createExecutor(corePoolSize, maximumPoolSize, keepAliveTime, workQueue, threadFactory, new ThreadPoolExecutor.AbortPolicy());
}
编辑:
实际上更好的是覆盖 getRejectedExecutionHandler
方法,returns 基于 AbortyPolicy 的处理程序。
/**
* This method returns the handler that handles the rejected runnable tasks.
* We have initialized the handler to {@link AbortPolicy} that helps throwing a {@link RejectedExecutionException} which in turn returns 500 statusCode response
*/
@Override
protected RejectedExecutionHandler getRejectedExecutionHandler() {
return this.handler;
}