我正在使用具有功能端点的Spring WebFlux来创建API。为了提供我想要的结果,我需要使用外部RESTful API,并以异步方式执行此操作,我正在使用WebClient实现。效果很好,就像这样:
public WeatherWebClient() {
this.weatherWebClient = WebClient.create("http://api.openweathermap.org/data/2.5/weather");
}
public Mono<WeatherApiResponse> getWeatherByCityName(String cityName) {
return weatherWebClient
.get()
.uri(uriBuilder -> uriBuilder
.queryParam("q", cityName)
.queryParam("units", "metric")
.queryParam("appid", API_KEY)
.build())
.accept(APPLICATION_JSON)
.retrieve()
.bodyToMono(WeatherApiResponse.class);
}
由于这会执行网络访问,因此它是NetFlix OSS Hystrix的一个很好的用例。我已经尝试过使用spring-cloud-starter-netflix-hystrix,将@HystrixCommand添加到上面的方法中,但即使我设置了错误的URL(404)或错误的API_KEY(401),也无法使其跳转到电路中
我认为这可能是与WebFlux本身兼容的问题,但设置属性@HystrixProperty(name =“circuitBreaker.forceOpen”,value =“true”)确实会强制执行回退方法。
我错过了什么吗?这种方法是否与Spring WebClients不兼容?
谢谢!
答案 0 :(得分:9)
@HystrixCommand不会真正起作用,因为Hystrix不会威胁Mono / Flux与Java原语的任何不同。
Hystrix不监视Mono的内容,而仅监视调用public Mono<WeatherApiResponse> getWeatherByCityName(String cityName)
的结果。
此结果始终没问题,因为响应式调用链创建将始终成功。
您需要的是使Hystrix威胁Mono / Flux的方式有所不同。 在Spring Cloud中,有一个specification,可以用HystrixCommand包装Mono / Flux。
Mono<WeatherApiResponse> call = this.getWeatherByCityName(String cityName);
Mono<WeatherApiResponse> callWrappedWithHystrix = HystrixCommands
.from(call)
.fallback(Mono.just(WeatherApiResponse.EMPTY))
.commandName("getWeatherByCityName")
.toMono();