概述
Spring Cloud【Finchley】-14 微服务网关Zuul的搭建与使用 # Step8. 网关功能-Hystrix监控测试中我们测试了Zuul默认集成了Hystrix的监控,但是没有提及容错。
这里我们来学习下zuul的容错与回退功能如何实现。
没有添加fallback功能的示例
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添加容错。
使用zuul为单个微服务添加容错和回退功能
Step1. 新建微服务microservice-gateway-zuul-fallback
为了不影响别的微服务,我们新建个支持容错与回退功能的微服务 ,在maven父工程上右键 新增mave module
代码同 microservice-gateway-zuul的,为了区别,修改下application.yml中的端口,将port修改为4535
Step2. FallbackProvider实现类
主要是两个方法
- getRoutes 方法,返回为哪个微服务提供回退功能
- getBody 方法,微服务不可用时返回的信息
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; } }; } }
Step3. 测试
- 启动Eureka Server
- 启动microservice-gateway-zuul-fallback
- 启动micorservice-provider-user
此时,通过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工程application.yml修改
zuul-fallback工程的zuul部分的配置信息:
测试验证
接下来测试下,为了验证我们起两个微服务:
- 启动microservice-discovery-eureka
- 启动microservice-provider-user
- 启动micorservice-consumer-movie-ribbon
- 启动microservice-gateway-zuul-fallback
查看服务注册情况 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
最后顺便看下zuul的路由信息
代码
https://github.com/yangshangwei/SpringCloudMaster/tree/master/microservice-gateway-zuul-fallback