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

Roh*_*hit 7 java-8 spring-boot microservices

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

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

Dmi*_*ykh 16

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

为了在仍然执行一些长时间运行的操作的同时从当前线程(在本例中为控制器)返回结果,您将需要另一个线程。

  • 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");
    }
}
Run Code Online (Sandbox Code Playgroud)

还有一项服务:

@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();
    }
}
Run Code Online (Sandbox Code Playgroud)

可以在此处找到更多详细信息https://docs.oracle.com/javase/tutorial/essential/concurrency/runthread.html

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

您可以简单地使用@Async、具有voidFuture返回类型来注释方法。

如果你仍然想提供你自己的执行器,你可以AsyncConfigurer在你的 spring 配置 bean 中实现接口。这种方法也需要@EnableAsync注释。

@Configuration
@EnableAsync
public class AsyncConfiguration implements AsyncConfigurer {

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

}
Run Code Online (Sandbox Code Playgroud)

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


Gio*_*nte 6

这是 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(){}
}
Run Code Online (Sandbox Code Playgroud)

您可以使用 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
Run Code Online (Sandbox Code Playgroud)

.

@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
    }

}
Run Code Online (Sandbox Code Playgroud)

这两种技术都非常好,但第一个带有 ExecutorService 的技术给了你更多的控制权。