Is it possible to setup a proxy to a main server/servers/service but when this is not available, redirect requests to a secondary server/servers/service?
The secondary service is not an instance of the same type of the primary one. Their API is compatible but not the same. The secondary is a less-performant last resource when the primary is not available.
We are not using Eureka, only fixed IPs yet.
zuul:
routes:
whatever:
path: /whatever/**
sensitiveHeaders: Cookie,Set-Cookie
url: http://server1:8080/whatever
I had a look on ZuulFallbackProvider
, but this interface is to provided a fixed response on case of error. I want, when http://server1:8080/whatever is not responding, redirect to http://server2:8080/whateverApi2.
Thanks.
答案 0 :(得分:4)
您可以使用ZuulFallbackProvider
执行此操作,但您需要先配置以下内容。
首先,url-routing - 直接在zuul.routes.<service>.url
中指定url - 在Zuul中不在HystrixCommand中执行。为此,您需要更改您的配置,如下所示。
zuul:
routes:
whatever:
path: /whatever/**
sensitiveHeaders: Cookie,Set-Cookie
serviceId: whatever
stripPrefix: false
ribbon:
eureka:
enabled: false
whatever:
ribbon:
listOfServers: http://server1:8080/
以上配置使用Ribbon而不使用eureka。你可以找到详细信息here
现在,您的请求将通过Ribbon在HystrixCommand中执行。所以你可以提供自己的ZuulFallbackProvider。
在ZuulFallbackProvider中,您可以通过以下http://server2:8080/whateverApi2.
方法向fallbackResponse
发送回复请求。以下是一个非常天真的例子。 :-)您需要为自己的目的完成以下示例。
@Component
public class TestZuulFallbackProvider implements ZuulFallbackProvider{
@Override
public String getRoute() {
return "test";
}
@Override
public ClientHttpResponse fallbackResponse() {
ResponseEntity<String> response = new RestTemplate().exchange("http://server2:8080/whateverApi2", HttpMethod.GET, null, String.class);
return new ClientHttpResponse() {
@Override
public HttpStatus getStatusCode() throws IOException {
return response.getStatusCode();
}
@Override
public int getRawStatusCode() throws IOException {
return response.getStatusCodeValue();
}
@Override
public String getStatusText() throws IOException {
return response.getStatusCode().getReasonPhrase();
}
@Override
public void close() {
}
@Override
public InputStream getBody() throws IOException {
return new ByteArrayInputStream(response.getBody().getBytes("UTF-8"));
}
@Override
public HttpHeaders getHeaders() {
return response.getHeaders();
}
};
}
}
答案 1 :(得分:4)
如果有人试图做类似的事情,实际工作的不是使用任何Zuul组件,而是使用Hystrix。
在Gateway API中,我们创建一个façade控制器,响应我们想要设置回退解决方案的服务:
@HystrixCommand(fallbackMethod = "fallbackWhatever")
@PostMapping
ResponseEntity<Object> whatever(final RequestEntity<?> request) {
return defaultClient.searchSubmissions(request.getHeaders(), request.getBody());
}
ResponseEntity<Object> fallbackWhatever(final RequestEntity<?> request) {
return fallbackClient.searchSubmissions(request.getHeaders(), request.getBody());
}
defaultClient和fallbackClient是两个不同的FeignClient接口,每个接口都指向每个服务端点。
就是这样!如果您关闭主服务,Gateway API将开始调用回退服务,而不会返回单个服务不可用,并且更改只需几毫秒。
此外,如果你再打开它,它在准备好后几毫秒就会回复。
答案 2 :(得分:0)
需要添加可重试
zuul:
routes:
whatever:
path: /whatever/**
sensitiveHeaders: Cookie,Set-Cookie
url: http://server1:8080/whatever
retryable=true
类似的situation