Spring Cloud【Finchley】-14 微服务网关Zuul的搭建与使用 # Step8. 网关功能-Hystrix监控测试中我们测试了Zuul默认集成了Hystrix的监控,但是没有提及容错。
这里我们来学习下zuul的容错与回退功能如何实现。
官方指导:https://cloud.spring.io/spring-cloud-static/Finchley.SR2/single/spring-cloud.html#hystrix-fallbacks-for-routes
顺着 https://blog.csdn.net/yangshangwei/article/details/85850470#Step8_Hystrix_192 的操作步骤,如果我们将micorservice-provider-user 停掉,继续多次调用,查看Dashboard
上图可知:zuul的hystrix的监控粒度是微服务,而不是某个API,同样的,经过zuul的所有请求,都会被Hystrix保护起来。
zuul的配置规则如下:
zuul:
routes:
microservice-provider-user: /userprovider/**
所以可以这么访问: http://localhost:4534/userprovider/user/4
这样返回是不是很难看,下面我们来为zuul添加容错。
为了不影响别的微服务,我们新建个支持容错与回退功能的微服务 ,在maven父工程上右键 新增mave module
代码同 microservice-gateway-zuul的,为了区别,修改下application.yml中的端口,将port修改为4535
主要是两个方法
package com.artisan.microservice.fallback;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.stereotype.Component;
import com.netflix.hystrix.exception.HystrixTimeoutException;
// 添加注解#Component使其成为Spring管理的bean
@Component
public class MyFallbackProvider implements FallbackProvider {
@Override
public String getRoute() {
// 为哪个微服务提供提供回退服务,返回微服务的名字,必须和注册在Eureka Server上的名字一致
return "microservice-provider-user";
}
@Override
public ClientHttpResponse fallbackResponse(String route, final Throwable cause) {
// fallback时的状态码
if (cause instanceof HystrixTimeoutException) {
return response(HttpStatus.GATEWAY_TIMEOUT);
} else {
return response(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
private ClientHttpResponse response(final HttpStatus status) {
return new ClientHttpResponse() {
@Override
public HttpStatus getStatusCode() throws IOException {
return status;
}
@Override
public int getRawStatusCode() throws IOException {
return status.value();
}
@Override
public String getStatusText() throws IOException {
return status.getReasonPhrase();
}
@Override
public void close() {
}
@Override
public InputStream getBody() throws IOException {
// 响应体
return new ByteArrayInputStream(("【 " +getRoute() + " 】fallback").getBytes());
}
@Override
public HttpHeaders getHeaders() {
// headers设置
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
return headers;
}
};
}
}
此时,通过zuul去访问微服务micorservice-provider-user
http://localhost:4535/userprovider/user/4
停掉micorservice-provider-user,再次访问
http://localhost:4535/userprovider/user/4
可见回退功能生效了。
将 getRoute方法 返回 *
or null
@Override
public String getRoute() {
return "*";
}
简单起见,仅修改这一个地方,至于返回什么信息,我们这里也不做太复杂,保持和上面的示例一致即可。
zuul-fallback工程的zuul部分的配置信息:
接下来测试下,为了验证我们起两个微服务:
查看服务注册情况 http://localhost:8761/
查看zuul的路由信息 http://localhost:4535/actuator/routes
先通过zuul微服务去访问其他两个微服务
电影微服务: http://localhost:4535/userprovider/user/3
{"id":3,"username":"artisan3","name":"小工匠三","age":30,"balance":300.00}
用户微服务: http://localhost:4535/usermovie/movie/4
{"id":4,"username":"artisan4","name":"小工匠4","age":40,"balance":400.00}
停掉micorservice-consumer-movie-ribbon,再次通过zuul访问consumer-movie
http://localhost:4535/usermovie/movie/4
必须使用zuul代理的路径访问才能生效,使用http://localhost:4535/micorservice-consumer-movie-ribbon/movie/4 不行,因为停掉服务后zuul的路由信息中 http://localhost:4535/actuator/routes 已经没有该代理信息了。
同样的停掉 microservice-provider-user, 再次访问 http://localhost:4535/userprovider/user/3
https://github.com/yangshangwei/SpringCloudMaster/tree/master/microservice-gateway-zuul-fallback