目录
2)新建AccessFilter类,继承ZuulFilter
3)Zuul的自动配置类,可以从spring容器自动发现过滤器实例,完成自动配置
2)配置 zuul 开启重试,并配置 ribbon 重试参数
1)创建降级类,实现 FallbackProvider 接口 添加@Component
1)在 06 项目中,Hystrix利用 actuator 来暴露自己的监控日志数据
1)新建spring模块:sp07-hystrix-dashboard
4)启动类注解:@EnableHystrixDashboard
5)访问 :http://localhost:4001/hystrix
一、zuul API 网关
zuul API 网关,为微服务应用提供统一的对外访问接口。
zuul 还提供过滤器,对所有微服务提供统一的请求校验
Zuul
-
统一的调用入口
-
统一的权限校验
-
集成 Ribbon
-
集成 Hystrix
1、统一的调用入口
1)新建 spring 模块 : sp06-zuul
2)添加依赖:(包括01-commons ,共三个)
3)配置application.yml:
spring:
application:
name: zuul
# 2001 3001 4001 5001 6001
server:
port: 3001
eureka:
client:
service-url:
defaultZone: http://eureka1:2001/eureka, http://eureka2:2002/eureka
zuul:
routes:
item-service: /item-service/**
user-service: /user-service/**
order-service: /order-service/**
4)添加启动类注解: @EnableZuulProxy
2、统一权限校验
1)通过Zuul的过滤器,判断用户权限
- 有权限,继续转发调用
- 没有权限,从网关直接返回结果
http://localhost:3001/item-service/u56y5g4 没登录,不允许访问
http://localhost:3001/item-service/u56y5g4?token=u6y54t 已登录,可以访问
2)新建AccessFilter类,继承ZuulFilter
添加@Component
@Component
public class AccessFilter extends ZuulFilter {
// pre, routing, post, error
@Override
public String filterType() {
//return "pre";
return FilterConstants.PRE_TYPE;
}
// 过滤器的顺序号
@Override
public int filterOrder() {
// 有5个默认的过滤器,自己的过滤器加到末尾
// 再第5个过滤器中, 向Context对象放入了 serviceId, 后面组件中, 才能访问这个数据
return 6;
}
// 针对当前请求,判断是否要执行过滤代码
// 如果调用 item-service,检查是否登录
// 否则,不检查登录,直接访问
@Override
public boolean shouldFilter() {
// 先获取当前请求的上下文对象
RequestContext ctx = RequestContext.getCurrentContext();
// 当前请求,调用的服务id
String serviceId = (String)
ctx.get(FilterConstants.SERVICE_ID_KEY);// "serviceId"
// 调用的是否是 item-service
return "item-service".equals(serviceId);
}
// 过滤代码
@Override
public Object run() throws ZuulException {
// 获得上下文对象
RequestContext ctx = RequestContext.getCurrentContext();
// 获得 request 对象
HttpServletRequest request = ctx.getRequest();
// http://localhost:3001/item-service/u56y5g4?token=u6y54t
// 接收 token 参数
String token = request.getParameter("token");
// 如果没有 token,阻止继续调用,直接返回响应
// ""、null、" "
if (StringUtils.isBlank(token)) {
// 阻止继续调用
ctx.setSendZuulResponse(false);
// 直接返回响应
// JsonResult --- {code:1,msg:xxx,data:null}
ctx.addZuulResponseHeader(
"Content-Type","application/json;charset=UTF-8");
ctx.setResponseBody(JsonResult
.err()
.code(400)
.msg("Not login! 未登录!")
.toString());
}
return null;// 当前 zuul 版本中,这个返回值没有使用
}
}
3)Zuul的自动配置类,可以从spring容器自动发现过滤器实例,完成自动配置
3、zuul集成 ribbon 负载均衡和重试
- zuul 默认启用负载均衡
- zuul 已经集成了 ribbon,默认已经实现了负载均衡
-
zuul默认不启用重试,zuul不推荐启用重试
一般不在网关执行重试,否则,会造成后台大面积服务器压力倍增
4、zuul启用 ribbon 重试
1)添加 spring-retry 依赖
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
</dependency>
2)配置 zuul 开启重试,并配置 ribbon 重试参数
需要开启重试,默认不开启 zuul.retryable=true
spring:
application:
name: zuul
# 2001 3001 4001 5001 6001
server:
port: 3001
eureka:
client:
service-url:
defaultZone: http://eureka1:2001/eureka, http://eureka2:2002/eureka
zuul:
routes:
item-service: /item-service/**
user-service: /user-service/**
order-service: /order-service/**
retryable: true
5、zuul 集成Hystrix 容错、限流
zuul默认已经启用了 Hystrix,可以直接写降级代码
1)创建降级类,实现 FallbackProvider 接口 添加@Component
@Component
public class OrderFB implements FallbackProvider {
/**
返回一个 service-id, 表示当前降级类是针对哪个后台服务的降级类
- order-service --- 只针对商品服务降级
- * --- 对所有服务都应用这个降级类
- null --- 等同于 *
*/
@Override
public String getRoute() {
return "order-service";
}
// 发回给客户端的降级响应
@Override
public ClientHttpResponse fallbackResponse(String route, Throwable cause) {
return new ClientHttpResponse() {
@Override
public HttpStatus getStatusCode() throws IOException {
return HttpStatus.INTERNAL_SERVER_ERROR;// 500
}
@Override
public int getRawStatusCode() throws IOException {
return HttpStatus.INTERNAL_SERVER_ERROR.value();
}
@Override
public String getStatusText() throws IOException {
return HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase();
}
@Override
public void close() {
}
@Override
public InputStream getBody() throws IOException {
// JsonResult --- {code:500,msg:xxx.data:null}
String json =JsonResult.err().code(500).msg("调用后台服务出错").toString();
return new ByteArrayInputStream(json.getBytes("UTF-8"));
}
@Override
public HttpHeaders getHeaders() {
HttpHeaders h = new HttpHeaders();
h.add("Content-Type", "application/json;charset=UTF-8");
return h;
}
};
}
}
item实现类:同order (将order-service 改成 item-service 即可)
2)zuul会自动配置类,对降级类进行自动配置
6、Hystrix 限流-- 熔断
当流量过大,后台服务出现故障,可以断开后台服务的链路,等待后台服务恢复
1)断路器的打开条件:
- 10秒20次请求(必须首先满足)
- 50%失败,执行的降级代码
2)半开状态:
- 断路器打开一段时间后,会进入半开状态
- 会尝试发送一次客户端调用
- 成功,关闭断路器,恢复正常
- 失败,继续保持打开状态
7、Hystrix 监控
对 Hystrix 降级和熔断的情况进行监控,可以快速定位错误,查找系统中的问题
1)在 06 项目中,Hystrix利用 actuator 来暴露自己的监控日志数据
- 1.添加 actuator 依赖(zuul 依赖中已经包含了 actuator依赖)
- 2.yml 配置暴露监控日志
management: endpoints: web: exposure: include: "*"
- 启动服务,查看暴露的监控端点
http://localhost:3001/actuator
http://localhost:3001/actuator/hystrix.stream
8、搭建Hystrix Dashboard 数据监控
1)新建spring模块:sp07-hystrix-dashboard
2)添加依赖:Hystrix Dashboard
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
3)application.yml
server:
port: 4001
hystrix:
dashboard:
#允许抓取的服务器列表
proxy-stream-allow-list: localhost
4)启动类注解:@EnableHystrixDashboard
5)访问 :http://localhost:4001/hystrix
(要先在item,user,order中请求数据,否则只有空的ping)