Spring Cloud Zuul
Spring Cloud Zuul
构建网关
- 创建Spring Boot 项目, 命名api-getaway,pom文件中加入spring-cloud-starter-zuul 、
- 应用主类添加@EnableZuulProxy (使用注解开启API网关服务功能)
- 配置Zuul的基础信息 (应用名 端口号等)
请求路由
- 传统路由方式
# 传统路由配置 单实例配置 - 没有服务治理框架的时候
zuul.routes.user-service.path=/user-service/**
zuul.routes.user-service.url=http://localhost:8080/
# 传统路由配置 多实例配置 - 没有服务治理框架
zuul.routes.user-service.path=/user-service/**
zuul.routes.user-service.service-id=user-service
#默认根据服务发现机制 这里为false 不采用服务发现机制
ribbon.eureka.enabled=false
#user-service对于的是service-id的值 用来维护服务与实例
#user-service.ribbon.listOfServers=http://localhost:8080/,http://localhost:8081/
- 面向服务的路由
#整合spring-cloud-starter-eureka
eureka.client.service-url.defaultZone=http://localhost:1111/eureka/
#配置服务路由
zuul.routes.api-a.path=/api-a/**
zuul.routes.api-a.service-id=hello-service
zuul.routes.api-b.path=/api-b/**
zuul.routes.api-b.service-id=feign-consumer
#综合
#zuul.routes.user-server=/api-b/**
请求过滤
- 继承ZuulFilter抽象类并实现它定义的四个方法
/**
* 自定义过滤器
*/
public class AccessFilter extends ZuulFilter {
/**
*过滤器类型
* @return
* pre 请求路由前被调用
* routing 路由请求时被调用
* post 在routing和error 过滤器之后被调用
* error 处理请求时发生错误调用
*/
@Override
public String filterType() {
return "pre"; //请求被路由之前举行
}
//过滤器的执行顺序
@Override
public int filterOrder() {
return 0;
}
//判断过滤器是否需要被执行
@Override
public boolean shouldFilter() {
return true;
}
//过滤器的具体逻辑
@Override
public Object run() throws ZuulException {
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
logger.info("发送{} request to {}",request.getMethod(),request.getRequestURL().toString());
String accessToken = request.getParameter("token");
if(accessToken == null){
logger.info("token为 null");
ctx.setSendZuulResponse(false);
ctx.setResponseStatusCode(401);
ctx.setResponseBody("对返回的body进行内容编辑");
return null;
}
logger.info("token is OK");
return null;
}
}
- 应用主类注入Bean
@Bean
public AccessFilter accessFilter(){
return new AccessFilter();
}
- 作为系统的入口,屏蔽了系统内部各个微服务的细节;与服务治理框架结合,实现自动化的服务实例维护以及负载均衡的路由转发;实现接口权限校验与微服务业务的解耦
路由匹配
- ? 匹配单个字符
- (*) 匹配任意数量的字符
- (**) 匹配 任意多个字符,支持多级目录
- (不希望被API网关路由)忽略表达式:zuul.ignored-pattens = //hello/
路由前缀
#关闭前缀
zuul.strip-prefix=false
#路由前缀
zuul.prefix=/api
本地跳转
- 支持forward形式的服务跳转
- zuul.routes.api-b.path=/api-b/**
- zuul.routes…api-b.url==forward:/local
- 当请求/api-b/hello ,该请求会被API网关转发到网关的/local/hello请求,进行本地处理;
- 网关本地需要有该接口,不然会找不到请求而返回 404;
cookie 与头信息
- 默认敏感信息头不会传递 (包括Cookie、set-Cookie、Authorization)
- 覆盖默认值 zuul.sensitive-headers=
- 指定路由开启敏感头:zuul.routes.< router>.custom-sensitive-headers=true;
- 设置指定路由敏感头:zuul.routes.< router>.sensitive-headers
Hystrix和Ribbon的支持
- zuul天生拥有线程隔离和断路器的功能,以及对服务调用的客户端负载均衡功能,但使用path和url,对路由转发的请求不会采用HystrixCommand包装,所以尽量使用Path和ServiceId
- zuul.retryable 开启全局重试机制
- zuu.routes.< route>.retryable 指定路由重试
- 可通过Hysterix 和Ribbon 参数配置
异常处理
各个阶段的逻辑处理
- 自定义过滤器异常的两种基本解决办法:一种是通过在各个阶段的过滤器中增加try-catch块,实现过滤器内部的异常处理;一种是利用errorl类型的过滤器的声明周期特性,集中处理pre,route,post阶段抛出的异常信息。
//异常处理 run方法
// RequestContext ctx = RequestContext.getCurrentContext();
// Throwable throwable = ctx.getThrowable();
// //500
// ctx.set("error.status_code", HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
// ctx.set("error.exception",throwable.getMessage());
// return null;
- 可自定义ErrorFilter,继承SendErrorFilter的过滤器,复用它的run方法,然后重写它的类型、顺序以及执行条件,实现对原有逻辑的复用;
- 自定义异常信息,继承DefaultErrorAttributes实现getErrorAttributes, 移除remove(“exception”),此后注入此Bean
禁用过滤器
zuul.< SimpleClassName>.< filterType>.disable=true
动态加载
动态路由
- 创建SpringBoot,命名api-gateway-dynamic-route,加入zuul、eurake、config的依赖;
- /respurce 创建bootstrap.properties,指定(应用配置文件)spring.cloud.config.uri、(服务注册与发现)eureka.client.service-url.defaultZone;
- 应用主类开启@EnableZuulProxy,注入Bean
@Bean
@RefreshScope
@ConfigurationProperties("zuul")
@Primary
public ZuulProperties zuulProperties(){
return new ZuulProperties();
}
动态过滤器
Spring Cloud Config
前言
- 为分布式的基础设施和微服务应用提供集中化的外部配置支持
- 服务端:分布式配置中心,是一个独立的微服务应用;
- 客户端:通过指定的配置中心来管理应用资源与业务相关的配置内容,并在启动的时候从配置中心获取和加载配置信息;
构建分布式配置中心(config-server)
- 创建SpringBoot项目,命名config-server,添加spring-cloud-config-server;
- 主类添加@EnableConfigServer配置
- 应用名,端口号,及git仓库的相关配置信息等;
spring.application.name=config-server
server.port=
eureka.client.service-url.defaultZone=
spring.cloud.config.server.git.uri=https://github.com.....
spring.cloud.config.server.git.searchPaths=子目录存储
spring.cloud.config.label=master
spring.cloud.config.server.git.username=
spring.cloud.config.server.git.password=
构建客户端配置映射(config-client)
- 创建SpringBoot项目,命名config-client,添加spring-cloud-starter-config
- 创建bootstrap.properties (必须是这个文件名)获取指定的 【config-server】 配置文件
#对应配置文件的{application}
spring.application.name=didspace
#对应config0server地址
#spring.cloud.config.uri=http://localhost:7001/
#对应配置文件的{profile}
spring.cloud.config.profile=dev
#对应配置文件的的{Label}
spring.cloud.config.label=master
eureka.client.service-url.defaultZone=http://localhost:1111/eureka/
spring.cloud.config.discovery.enabled=true
spring.cloud.config.discovery.service-id=config-server
management.endpoints.web.exposure.include=*
- 可通过ResfulAPI 进行绑定配置服务中心获取属性
@RefreshScope
@RestController
public class TestController {
@Value("${from}") private String from;
@Autowired private Environment env;
@RequestMapping("/from")
public String from(){
//两种获取方式
String from = env.getProperty("from", "");
return this.from;
}
}
Git仓库配置 (服务端详解)
- 占位符配置URI,{application}、{profile}、{label} 不仅可以标识配置文件、还可以用来对git的仓库地址的配置;
- 可通过通配符 配置多个仓库
- 子目录存储 (支持使用占位符)
- 访问权限 HTTP/SSH
- 本地仓库:文件会在config-server 的本地系统中存储一份,可通过指定一个固定位置来存储,因此 断开网络会访问本地缓存
# config-server 中配置本地存储目录
spring.cloud.config.server.git.basedir=
- 若不使用GIT/SVN ,使用本地文件系统
#config0server 中配置本地文件系统
spring.profiles.active=native
spring.cloud.config.server.native.search-locations=
- 健康检测
- 属性覆盖,通过spring.config.server.overrides.{key}={value} 、属性设置键值对的参数,不会被springcloud的客户端修改
- 安全保护 :加入spring-boot-starter-security即可
- 加密解密:
- 高可用模式: 纳入Eureka 服务治理体系
- URI指定配置中心:只有当我们配置了spring.cloud.config.uri,客户端应用才会尝试链接Spring Cloud Config的服务来获取远程配置信息并初始化Spring环境变量(默认尝试连接 http://localhost:8888);
- 服务化配置中心
- 服务端配置
1. config-server 加入 spring-cloud-starter-eureka,以实现分布式配置中心加入Eureka的服务治理体系
2. 配置服务注册中心:eureka.client.service-url.defaultZone=http://localhost:1111/eureka/
3. 应用主类添加@EnableDiscoveryClient注解 - 客户端配置
- config-client加入 spring-cloud-starter-eureka,以实现客户端发现config-server服务
- bootstrap.properties中 配置 如下代码
- 应用主类增加@EnableDiscovertClient注解,用来发现config-server服务,利用其来加载应用配置
- 服务端配置
#对应配置文件的{application}
spring.application.name=didspace
#对应config0server地址
#spring.cloud.config.uri=http://localhost:7001/
#对应配置文件的{profile}
spring.cloud.config.profile=dev
#对应配置文件的的{Label}
spring.cloud.config.label=master
server.port=7002
eureka.client.service-url.defaultZone=http://localhost:1111/eureka/
spring.cloud.config.discovery.enabled=true
spring.cloud.config.discovery.service-id=config-server
-
失败快速响应与重试
- 客户端优先判断ConfigServer获取是否正常,并快速响应失败内容,只须在bootstrap.properties中配置参数spring.cloud.config.faillFast=true
- 重试 1:加入spring-boot-starter-aop/ spring-retry 2:默认值修改
-
获取远程配置
- 通过向ConfigSerer发送get请求
- 通过客户端配置方式 参考上述客户端配置代码
-
动态刷新配置
- config-client改造
- pom.xml 添加spring-boot-starter-actuator监控模块 ,通过/refresh端点的实现,实现客户端应用配置信息的重新获取与刷新
- config-client改造