Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Kotlin 高负载测试spring webflux Webclient时出现的问题_Kotlin_Spring Webflux_Spring Webclient - Fatal编程技术网

Kotlin 高负载测试spring webflux Webclient时出现的问题

Kotlin 高负载测试spring webflux Webclient时出现的问题,kotlin,spring-webflux,spring-webclient,Kotlin,Spring Webflux,Spring Webclient,我试图从C#和NetCore学习SpringWebFlux提交,我们有一个非常类似的问题,比如,第三方服务提供商有一些响应时间问题 但是使用SpringWebClient进行测试的响应时间增加了一倍,我不知道是否遗漏了什么 我尝试创建一个类似的示例: 运行3台服务器的计算机 演示服务器,仅模拟一些随机延迟时间(端口8080) C#中的测试服务器使用异步调用我的“等待”服务器(端口5000) 使用spring和webclient测试服务器以调用我的“等待”服务器(端口8081) 另一台运行

我试图从C#和NetCore学习SpringWebFlux提交,我们有一个非常类似的问题,比如,第三方服务提供商有一些响应时间问题

但是使用SpringWebClient进行测试的响应时间增加了一倍,我不知道是否遗漏了什么

我尝试创建一个类似的示例:

  • 运行3台服务器的计算机
    • 演示服务器,仅模拟一些随机延迟时间(端口8080)
    • C#中的测试服务器使用异步调用我的“等待”服务器(端口5000)
    • 使用spring和webclient测试服务器以调用我的“等待”服务器(端口8081)
  • 另一台运行JMeter的计算机,有1000个客户端,每个客户端有10个回合
一些代码 等待服务器 只是一条简单的路线

@Configuration
class TestRouter(private val middlemanDemo: MiddlemanDemo) {

    @Bean
    fun route() = router {
        GET("/testWait", middlemanDemo::middleTestAndGetWait)
    }
}
处理程序有一个带有种子的随机生成器,因此每个测试都可以生成相同的延迟序列

@Service
class TestWaiter {

    companion object RandomManager {

        private lateinit var random: Random

        init {
            resetTimer()
        }

        @Synchronized
        fun next(): Long {
            val random = random.nextLong(0, 10)
            return random * 2
        }

        fun resetTimer() {
            random = Random(12345)
        }
    }

    private val logger = LoggerFactory.getLogger(javaClass)

    fun testAndGetWait(request: ServerRequest): Mono<ServerResponse> {
        val wait = next()
        logger.debug("Wait is: {}", wait)
        return ServerResponse
                .ok()
                .json()
                .bodyValue(wait)
                .delayElement(Duration.ofSeconds(wait))
    }

    fun reset(request: ServerRequest): Mono<ServerResponse> {
        logger.info("Random reset")
        resetTimer()
        return ServerResponse
                .ok()
                .build()
    }
}
处理程序只是使用webclient调用服务

@Service
class MiddlemanDemo {

    private val client = WebClient.create("http://127.0.0.1:8080")

    fun middleTestAndGetWait(request: ServerRequest): Mono<ServerResponse> {
        return client
                .get()
                .uri("/testWait")
                .retrieve()
                .bodyToMono(Int::class.java)
                .flatMap(::processResponse)
    }

    fun processResponse(delay: Int): Mono<ServerResponse> {
        return ServerResponse
                .ok()
                .bodyValue(delay)
    }
}
@服务
中间人阶级{
private val client=WebClient.create(“http://127.0.0.1:8080")
有趣的middleTestAndGetWait(请求:ServerRequest):Mono{
返回客户端
.get()
.uri(“/testWait”)
.retrieve()
.bodyToMono(Int::class.java)
.flatMap(::processResponse)
}
有趣的processResponse(延迟:Int):单声道{
返回服务器响应
.ok()
.bodyValue(延迟)
}
}
但是,运行测试时,吞吐量仅达到50/秒

响应时间加倍,就像我再次等待,直到负载再次下降


我认为这可能是由于池获取时间造成的

我假设您的服务器获得超过1k TPS,每个请求看起来需要大约9秒。但是默认的HTTP客户端连接池是500。请参阅

请检查日志是否有
PoolAcquireTimeoutException
,或者您的服务器是否需要一些时间来等待池获取。

我正在标记答案,因为它为我指明了正确的方向,但我将添加完整的解决方案,供任何人查找:

关键是根据我的需要创建一个连接池。正如JK.Lee提到的,默认值是500

@Service
class MiddlemanDemo(webClientBuilder: WebClient.Builder) {

    private val client: WebClient

    init {
        val provider = ConnectionProvider.builder("fixed")
                .maxConnections(2000) // This is the important part
                .build()
        val httpClient = HttpClient
                .create(provider)
        client = webClientBuilder
                .clientConnector(ReactorClientHttpConnector(httpClient))
                .baseUrl("http://localhost:8080")
                .build()
    }

    fun middleTestAndGetWait(request: ServerRequest): Mono<ServerResponse> {

        return client
                .get()
                .uri("/testWait")
                .retrieve()
                .bodyToMono(Int::class.java)
                .flatMap(::processResponse)
    }

    fun processResponse(delay: Int): Mono<ServerResponse> {
        return ServerResponse
                .ok()
                .bodyValue(delay)
    }
}
@服务
类MiddlemanDemo(WebClient Builder:WebClient.Builder){
私有val客户端:网络客户端
初始化{
val provider=ConnectionProvider.builder(“固定”)
.maxConnections(2000)//这是重要的部分
.build()
val httpClient=httpClient
.创建(提供程序)
client=webClientBuilder
.clientConnector(ReactorClientHttpConnector(httpClient))
.baseUrl(“http://localhost:8080")
.build()
}
有趣的middleTestAndGetWait(请求:ServerRequest):Mono{
返回客户端
.get()
.uri(“/testWait”)
.retrieve()
.bodyToMono(Int::class.java)
.flatMap(::processResponse)
}
有趣的processResponse(延迟:Int):单声道{
返回服务器响应
.ok()
.bodyValue(延迟)
}
}
@Configuration
class TestRouter(private val middlemanDemo: MiddlemanDemo) {

    @Bean
    fun route() = router {
        GET("/testWait", middlemanDemo::middleTestAndGetWait)
    }
}
@Service
class MiddlemanDemo {

    private val client = WebClient.create("http://127.0.0.1:8080")

    fun middleTestAndGetWait(request: ServerRequest): Mono<ServerResponse> {
        return client
                .get()
                .uri("/testWait")
                .retrieve()
                .bodyToMono(Int::class.java)
                .flatMap(::processResponse)
    }

    fun processResponse(delay: Int): Mono<ServerResponse> {
        return ServerResponse
                .ok()
                .bodyValue(delay)
    }
}
@Service
class MiddlemanDemo(webClientBuilder: WebClient.Builder) {

    private val client: WebClient

    init {
        val provider = ConnectionProvider.builder("fixed")
                .maxConnections(2000) // This is the important part
                .build()
        val httpClient = HttpClient
                .create(provider)
        client = webClientBuilder
                .clientConnector(ReactorClientHttpConnector(httpClient))
                .baseUrl("http://localhost:8080")
                .build()
    }

    fun middleTestAndGetWait(request: ServerRequest): Mono<ServerResponse> {

        return client
                .get()
                .uri("/testWait")
                .retrieve()
                .bodyToMono(Int::class.java)
                .flatMap(::processResponse)
    }

    fun processResponse(delay: Int): Mono<ServerResponse> {
        return ServerResponse
                .ok()
                .bodyValue(delay)
    }
}