我正在实现一种服务,该服务模拟网络上可用的另一种服务。 我正在尝试配置Spring Cloud网关,以在对我的实现的调用失败时将请求重新路由到公共服务。
我尝试通过以下方式使用Hystrix过滤器:
spring:
cloud:
gateway:
routes:
- id: foo
uri: http://my-internal-service/
filters:
- name: Hystrix
args:
name: fallbackcmd
fallbackUri: https://the.public.service/
不幸的是,就像documentation所说:
当前,仅支持转发:计划的URI。如果调用后备,则请求将被转发到与URI相匹配的控制器。
因此,我不能使用fallbackUri: https://...
。
是否有计划支持此功能? 否则,对于该特定用例,我有哪些选择?
答案 0 :(得分:0)
我最终得到了一种hacky解决方法,该解决方法似乎适用于我的特定用例(即GET请求):
最终结果如下:
application.yml
spring:
cloud:
gateway:
default-filters:
- name: AddResponseHeader
args:
name: X-Data-Origin
value: My internal service
routes:
- id: foo
uri: http://my-internal-service/
filters:
- name: Hystrix
args:
name: local-service-fallback
fallbackUri: forward:/fallback/foo
FallbackController.java
@RestController
@RequestMapping(path = "/fallback")
public class FallbackController {
private static final String fallbackUri = "https://the.public.service";
WebClient webClient;
public FallbackController() {
webClient = WebClient.create(fallbackUri);
}
@GetMapping("/foo")
Mono<MyResponse> foo(ServerWebExchange failedExchange) {
failedExchange.getResponse().getHeaders().remove("X-Data-Origin");
failedExchange.getResponse().getHeaders().add("X-Data-Origin", "The public service");
// Now call the public service using the same GET request
UriComponents uriComponents = UriComponentsBuilder.newInstance()
.uri(URI.create(fallbackUri))
.path("/path/to/service")
.queryParams(failedExchange.getRequest().getQueryParams())
.build();
return WebClient.create(uriComponents.toUriString())
.get()
.accept(MediaType.TEXT_XML)
.exchange()
.doOnSuccess(clientResponse -> {
// Copy the headers from the public service's response back to our exchange's response
failedExchange.getResponse().getHeaders()
.addAll(clientResponse.headers().asHttpHeaders());
})
.flatMap(clientResponse -> {
log.info("Data origin: {}",
failedExchange.getResponse().getHeaders().get("X-Data-Origin"));
return clientResponse.bodyToMono(MyResponse.class);
});
}
}
答案 1 :(得分:0)
我有类似的问题要解决。
我添加了新的备用路线,并且有效。
.route(p -> p .path("/fallback/foo").uri("https://example.com"))