在 grpc Spring 引导中关闭自定义线程池执行器

Shutting down Custom Thread Pool executor in grpc Spring boot

我正在创建一个应用程序,我正在使用 Spring Boot 来构建 gRPC 客户端和服务器。 我有一个要求,我想在 9 小时后关闭我的服务。第二天又开始了。 对于grpc Server,提供了一个默认的线程池,但是我们可以通过调用提供自己的自定义线程池,serverBuilder.executor(our custom executor) 但是,当我们提供自定义执行程序时,我们有责任将其关闭。

现在,如果我们不使用 Spring 引导,我们可以在我们用来终止服务的自定义方法中调用 shutDown()/shutDownNow()。

但是当我们使用Spring启动时,我们提供了这样的自定义执行器

@Component
public class BootGrpcConfiguration extends GRpcServerBuilderConfigurer{

    @Override
    public void configure(ServerBuilder<?> serverBuilder) {
        ExecutorService threadPoolExecutor = Executors.newFixedThreadPool(1);
        serverBuilder.executor(threadPoolExecutor);

    }

}

现在关闭它有多种可能的方法:

  1. 在配置方法本身内部使用 awaitTermination(9, TimeUnit.HOURS)
  2. 使我的 cutom execuotr 成为一个 bean 并从代码中的任何地方关闭它
  3. 在方法外声明 ExecutorService threadPoolExecutor 实例并使用某种 getter 获取它,然后从代码中的任何地方调用它的 shutdDown 方法。

您认为哪种方式效率更高? 我特别想问一下,将自定义执行程序设为 bean 是否是个好主意?

你需要告诉spring当你的组件被销毁时要做什么,例如:

@Component
public class BootGrpcConfiguration extends GRpcServerBuilderConfigurer{

    private ExecutorService threadPoolExecutor = Executors.newFixedThreadPool(1);

    @Override
    public void configure(ServerBuilder<?> serverBuilder) {
        serverBuilder.executor(threadPoolExecutor);

    }

    @PreDestroy
    public void destroy() {
        threadPoolExecutor.shutdown();
    }

}

如果您将线程池创建为一个 bean,那么您可以在那里声明 destroy 方法:

@Configuration
public class AppConfiguration {

    @Bean(destroyMethod = "shutdown")
    public ExecutorService initializeExecutorService() {
        return Executors.newFixedThreadPool(1);
    }
}

您当然需要一个在一段时间内不接受新工作的自定义执行程序:

ExecutorService executorService = new ThreadPoolExecutor() {

    @Override   
    protected void beforeExecute(Thread t, Runnable r) {
        super.beforeExecute(t, r);
        // do some checks here
    }
 }