首页 > 解决方案 > Vertx/RxJava/Retrofit 阻塞

问题描述

我正在使用 Kotlin/Vertx/RxJava/Retrofit 服务器,但是当调用需要太长时间的外部 API 时,一些调用会阻塞 Vertx。

原始处理程序进行调用:

val response = weatherService.getWeatherSummaryByCity(countryCode = queryParams[0], adminCode = queryParams[1], cityName = queryParams[2])

这反过来执行外部调用:

fun getWeatherSummaryByCity(countryCode: String, adminCode: String, cityName: String): WeatherSummary? {
    val citiesList = externalAPI.getLocationByCityName(countryCode = countryCode, adminCode = adminCode, cityName = cityName)
    var weatherSummary : WeatherSummary? = null

    citiesList
        .doOnError { error -> print(error) }
        .filter { cityList -> !cityList.isEmpty() }
        .map { cityList -> cityList[0] }
        .filter { city -> city.Key != null && !city.Key.isEmpty() }
        .subscribe( { city: City -> weatherSummary = createWeatherSummary(city) } )

    return weatherSummary
}

这是Retrofit使用的界面

interface ExternalAPI {

@GET("/locations/{version}/cities/{countryCode}/{adminCode}/search.json")
fun getLocationByCityName(
        @Path("version") version: String = "v1",
        @Path("countryCode") countryCode: String,
        @Path("adminCode") adminCode: String,
        @Query("q") cityName: String,
        @Query("apikey") apiKey: String = key, 
        @Query("details") details: String = "true",
        @Query("language") language: String = "en-US"): Observable<List<City>>
}

代码按原样工作,但如果 externalAPI 花费的时间太长,它会阻止 Vertx。当我尝试这个时也会发生同样的情况:

Json.encodePrettily(response)

而且反应太大了。有什么想法可以避免阻塞吗?

标签: kotlinserverretrofitvert.x

解决方案


我看到两种方法来处理你的问题:

  1. 使用异步 http 客户端来获取getLocationByCityName。我没有使用改造,而是看这个:https ://futurestud.io/tutorials/retrofit-synchronous-and-asynchronous-requests它有开箱即用的支持。
  2. 阻塞代码总是可以通过调用vertx.executeblocking在专用工作线程上执行。这可以在这里阅读:https ://vertx.io/docs/vertx-core/java/#blocking_code

我会建议选项 1,因为它更干净。


推荐阅读