微服务首先返回响应,然后处理请求

时间:2017-10-10 13:46:12

标签: spring-boot java-8 microservices

我正在研究一个解决方案,我正在尝试创建一个微服务,它立即返回响应,然后处理请求。

我正在尝试使用Java 8和Spring。

2 个答案:

答案 0 :(得分:3)

以下是ExecutorService的示例:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import javax.annotation.PreDestroy;
import javax.servlet.http.HttpServletRequest;

@RestController
public class MyController {

    // Instantiate an executor service
    private ExecutorService executor = Executors.newSingleThreadExecutor();

    @PreDestroy
    public void shutdonw() {
        // needed to avoid resource leak
        executor.shutdown(); 
    }

    @GetMapping
    public Object gerUrl(HttpServletRequest request) {
        // execute the async action, you can use a Runnable or Callable instances
        executor.submit(() -> doStuff());    
        return "ok";
    }

    private void doStuff(){}
}

您可以使用Executors工厂类来构建ExecutorService。这些方法可能会对您有所帮助:

java.util.concurrent.Executors
Executors.newSingleThreadExecutor() // jobs are queued and executed by a single thread
Executors.newCachedThreadPool() // new threads are instantiated as needed and cached
Executors.newFixedThreadPool(int nThreads) // user defined number of threads

@EnableAsync
@SpringBootApplication
public class MyApplication extends SpringBootServletInitializer {

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(MyApplication.class);
    }

    public static void main(String[] args) throws Exception {
        SpringApplication.run(MyApplication.class, args);
    }

}


import javax.annotation.PreDestroy;

import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurerSupport;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

@Configuration
public class AsyncConfiguration extends AsyncConfigurerSupport {

    private ThreadPoolTaskExecutor executor;

    @Override
    public Executor getAsyncExecutor() {
        executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(20);
        executor.setMaxPoolSize(50);
        executor.setQueueCapacity(1000);
        executor.initialize();
        return executor;
    }

    @PreDestroy
    public void shutdownExecutors() {
        executor.shutdown();
    }

}


@Service
public class MyService {

    @Async
    public void doStuff(){
        // Async method
    }

}

这两种技术都相当不错,但是第一个使用ExecutorService的技术可以为您提供更多控制。

答案 1 :(得分:2)

这可以通过多种方式实现。

为了在仍然执行长时间运行的同时从当前线程(在这种情况下为控制器)返回结果,您将需要另一个线程。

  • 直接使用Executor

控制器:

@Controller
public class AsyncController {

    private AsyncService asyncService;

    @Autowired
    public void setAsyncService(AsyncService asyncService) {
        this.asyncService = asyncService;
    }

    private ResponseEntity asyncMethod(@RequestBody Object request) {
        asyncService.process(new MyLongRunningRunnable());

        // returns immediately
        return ResponseEntity.ok("ok");
    }
}

一项服务:

@Service
public class AsyncService {
    private ExecutorService executorService;

    @PostConstruct
    private void create() {
        executorService = Executors.newSingleThreadExecutor();
    }

    public void process(Runnable operation) {
        // no result operation
        executorService.submit(operation);
    }


    @PreDestroy
    private void destroy() {
        executorService.shutdown();
    }
}

更多细节可以在https://docs.oracle.com/javase/tutorial/essential/concurrency/runthread.html

找到
  • 另一种方法是使用Spring内置的异步功能

您只需使用@AsyncvoidFuture返回类型注释方法即可。

如果您仍想提供自己的执行程序,可以在spring配置bean中实现AsyncConfigurer接口。 此方法还需要@EnableAsync注释。

@Configuration
@EnableAsync
public class AsyncConfiguration implements AsyncConfigurer {

    @Override
    public Executor getAsyncExecutor() {
        return Executors.newSingleThreadExecutor();
    }

}

有关此主题的更多信息https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/scheduling/annotation/Async.html