当前位置: 首页 > 知识库问答 >
问题:

Spring Flux和异步注释

马弘和
2023-03-14

我有一个Spring-Flux应用程序,在某个时候我需要在后台执行一些繁重的任务,调用方(HTTP请求)不需要等到该任务完成。

如果没有反应器,我可能会使用Async注释,在不同的线程上执行该方法。对于反应器,我不确定我是否应该继续这种方法,或者是否已经有一个内置机制允许我完成这一点。

例如,给定一个接受资源对象的控制器:

@PostMapping("/create")
public Mono<Resource> create(@Valid @RequestBody Resource r) {
    processor.run(r); // the caller should not wait for the resource to be processed
    return repository.save(r);
}

和一个处理器类:

@Async
void run(Resource r) { 
    WebClient webClient = WebClient.create("http://localhost:8080");
    Mono<String> result = webClient.get()
                                   .retrieve()
                                   .bodyToMono(String.class);
    String response = result.block(); //block for now
}

/create的HTTP调用方不需要等到run方法完成。

共有2个答案

公良扬
2023-03-14

我做了一些测试,我认为即使使用认购()作为火和忘记也会等待请求完成,然后再向网络浏览器或REST-client返回答案(至少在我的简单测试中,看起来是这样的)。所以,你必须做类似@Async的事情,创建另一个线程:

@PostMapping("/create")
public Mono<Resource> create(@Valid @RequestBody Resource r) {
    return processor.run(r)
    .subscribeOn(Schedulers.elastic()) // put eveything above this line on another thread
    .doOnNext(string -> repository.save(r)); // persist "r", not changing it, though

}

和一个处理器类:

Mono<String> run(Resource r) { 
    WebClient webClient = WebClient.create("http://localhost:8080");
    return webClient.get()
           .retrieve()
           .bodyToMono(String.class);
}
养昊天
2023-03-14

如果您正在寻找fire and forget模式的实现,您可以订阅您的发布者

@PostMapping("/create")
public Mono<Resource> create(@Valid @RequestBody Resource r) {
    run(r).subscribe();
    return repository.save(r);
}

Mono<Void> run(Resource r) {
    WebClient webClient = WebClient.create("http://localhost:8080");
    return webClient.get()
            .retrieve()
            .bodyToMono(String.class)
            .then();
}

如果发布服务器执行阻塞操作,则应使用弹性或并行调度程序在其他线程上订阅。

 类似资料:
  • 异步操作在线程中执行,与主应用程序线程分开。当应用程序调用方法异步执行操作时,应用程序可以在异步方法执行其任务时继续执行。 示例 下面通过一个例子来理解这个概念。在示例程序中使用IO库接受用户输入。 是一种同步方法。它将阻止执行函数调用之后的所有指令,直到方法完成执行。 等待输入。它停止执行并且在收到用户输入之前不再执行任何操作。 以上示例将产生以下输出 - 在计算中,当某个事件在继续之前等待事件

  • 问题内容: 同步和异步AJAX调用有什么区别?何时使用同步以及何时异步? 问题答案: 在最基本的级别上,当您希望调用在后台发生时,您可以使用异步模式,而当您希望代码等待直到调用完成时,则可以使用同步模式。 异步模式是AJAX调用的常用方法,因为通常在事件上附加一个回调函数,以便您可以在服务器端数据就绪时进行响应,而不必等待数据到达。

  • 问题内容: 我正在尝试2种方法来阻止无限循环运行: supervisor_1 :任务编程取消 Supervisor_2 :使用Ctrl + C停止任务 虽然 supervisor_2 不会引发中断时,在任何错误,我不能让 supervisor_1 从得到。知道为什么吗? 这是代码: @update : 感谢@Gerasimov,这是一个可以解决此问题的版本,但仍会不时在KeyboardInterr

  • 本文向大家介绍举例说明同步和异步相关面试题,主要包含被问及举例说明同步和异步时的应答技巧和注意事项,需要的朋友参考一下 考察点:线程 如果系统中存在临界资源(资源数量少于竞争资源的线程数量的资源),例如正在写的数据以后可能被另一个线程读到,或者正在读的数据可能已经被另一个线程写过了,那么这些数据就必须进行同步存取(数据库操作中的排他锁就是最好的例子)。当应用程序在对象上调用了一个需要花费很长时间来

  • 在过去的几天里,我一直在探索Netty,因为我正在编写一个快速而紧凑的HTTP服务器,它应该能够接收大量请求,而Netty的HTTP服务器实现非常简单,可以完成这项工作。 我的下一步是作为请求处理的一部分,我需要启动一个到外部web服务器的HTTP请求。我的直觉是实现一个可以同时发送大量请求的异步客户机,但我有点困惑什么是正确的方法。我的理解是,Netty服务器对每个传入消息都使用一个工作线程,因

  • 异步迭代允许我们对按需通过异步请求而得到的数据进行迭代。例如,我们通过网络分段(chunk-by-chunk)下载数据时。异步生成器(generator)使这一步骤更加方便。 首先,让我们来看一个简单的示例以掌握语法,然后再看一个实际用例。 回顾可迭代对象 让我们回顾一下可迭代对象的相关内容。 假设我们有一个对象,例如下面的 range: let range = { from: 1, to