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

webclient阻塞主线程netty,为什么?

欧阳骏俊
2023-03-14

我不明白为什么webclient会阻止我使用gradle的主要netty线程,以下是它的依赖项:

dependencyManagement {
    imports {
        mavenBom "org.springframework.cloud:spring-cloud-dependencies:Hoxton.SR11"
    }
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-webflux'
    ...
}

这个gradle脚本在两个应用程序中都使用。在第一个应用程序中,我执行

    @GetMapping
    open fun otherApp(): Mono<String> {
        return WebClient.create("http://localhost:8081")
                .get()
                .uri("/test")
                .retrieve()
                .bodyToMono(String::class.java)
//              I tried to use an additional scheduler but the main stream is blocked with it too
//              .publishOn(Schedulers.boundedElastic())
    }

第二个应用程序模拟长响应处理:

@GetMapping("/test")
    open fun test(): Mono<String> {
        Thread.sleep(15000L)
        return Mono.just("Hello");
    }

我希望呼叫服务不会阻塞主线程,而是会继续处理传入的连接,但直到我收到第一个呼叫的响应(睡眠将起作用),我的下一个连接将挂起等待。

结果:第一个应用程序像tomcat一样工作,只有一个线程

我的问题是:我做错了什么?

共有1个答案

欧阳乐生
2023-03-14

客户端应用程序不会阻塞,它能够处理新请求。您可以通过添加日志来确认:

@GetMapping("/test")
public Mono<String> test() {
    return Mono.just("incoming request")
        .doOnNext(e -> logger.info("Process: {}", e))
        .flatMap(e -> webclient.test());
}

服务器应用程序被阻止,因为线程。sleep(15000L)阻塞主线程(考虑改用.delayElement(持续时间秒(15)))

这是由于浏览器缓存。您应该禁用缓存或强制硬刷新(CTRL F5)。

我测试了硬刷新,它似乎工作得很好。

 类似资料:
  • 线程实例的join()方法可用于将一个线程的执行开始“连接”到另一个线程的执行结束,这样一个线程在另一个线程结束之前不会开始运行。如果对线程实例调用join(),则当前运行的线程将阻塞,直到线程实例完成执行 但是如果我有多个线程并且当我在循环内部调用join时。所有线程并行运行。但是根据连接的概念,首先连接的线程应该完成,然后只有主线程才允许连接其他线程。 } 在上面的代码中,如果第一个线程被连接

  • 问题内容: 当用户选择在另一个线程中启动阻止进程的菜单项时,我试图在JavaFX 8应用程序中提供反馈。在我的实际应用程序中,它是文件下载,但是通过示例,我使用最少的代码创建了一个测试用例: 它的工作方式如下:当选择“开始”菜单项时,主菜单文本应立即更改为“正在运行…”,然后应附加“完成!”。经过5秒钟的模拟我的文件下载的睡眠。 实际上发生的是,即使我正在使用,在阻止过程完成 后 , 两个 文本更

  • 这是一个扩展Thread并实现run()函数的类: 现在在主活动中的一个按钮中,我有这样的代码: 据我所知,这应该将runnable放在目标线程的消息队列中,并且线程(不是UI线程)将在可能的情况下运行它。但此代码会阻止 UI。为什么会发生这种情况?如您所见,我将目标线程的循环器发送到处理程序构造函数,并且处理程序应使用该循环器而不是主线程的循环程序。

  • 我正在尝试用Python编写一个程序。我想写的是一个脚本,它会立即向用户返回一条友好的消息,但会在后台生成一个长的子进程,它会处理几个不同的文件,并将它们写入一个祖父文件。我已经做了一些关于线程和处理的教程,但我遇到的是,无论我尝试什么,程序都会一直等待,直到子进程完成,然后才会向用户显示前面提到的友好消息。以下是我尝试过的: 线程示例: 我读过这些关于多线程的SO帖子如何在Python中使用线程

  • 我有下面的代码片段,它试图在多个子进程之间分割处理。 while循环中的主进程正在调用search函数,如果队列达到阈值计数,则处理池将映射到进程函数,其中作业来自队列。我的问题是,python多处理池是在执行期间阻塞主进程,还是立即继续执行?我不想遇到这样的情况,“has_jobs_to_process()”的计算结果为true,并且在处理作业的过程中,另一组作业的计算结果为true,并且再次调

  • 我不明白以下几点: 用户级线程需要非阻塞系统调用,即多线程内核。否则,整个进程将在内核中阻塞,即使进程中还有可运行的线程。 内核线程如何处理阻塞系统调用?在用户级线程中,当一个线程进行阻塞系统调用(例如读取)时,为什么其他线程不能继续工作?