API网关Zuul(2)--Quick Start
编写一个简单的Zuul网关
1. 引入依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zuul</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
启动类:
@SpringBootApplication
@EnableZuulProxy
public class ZuulApplication {
public static void main(String[] args) {
SpringApplication.run(ZuulApplication.class, args);
}
}
配置文件:
server:
port: 8040
spring:
application:
name: microservice-gateway-zuul
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
instance:
prefer-ip-address: true
Zuul配置详解
路由配置
运行zuul后,访问http://localhost:8040/routes可以看到路径到微服务的映射信息。
1.1 自定义微服务访问路径
例如:
zuul:
routes:
microservice-provider-user: /user/**
这样设置后,微服务microservice-provider-user就会被映射到/user/,访问方法为:http://localhost:8040/user/
(备注:如果不配置自定义路径,zuul默认会将应用的服务名spring.application.name作为路径。)
1.2 忽略指定服务路径
zuul:
ignored-services: microservice-provider-user,microservice-consumer-movie
这样可以让Zuul忽略以上两个服务,只代理其他服务。
1.3 忽略所有微服务,只路由指定服务
zuul:
ignored-services: '*' # 使用'*'可忽略所有微服务
routes:
microservice-provider-user: /user/**
这样Zuul只会路由microservice-provider-user
1.4 同时指定微服务的serivceId和对应路径
zuul:
routes:
user-route: # 该配置方式中,user-route只是给路由一个名称,可以任意起名。
service-id: microservice-provider-user
path: /user/** # service-id对应的路径
此配置效果如1.1
1.5 同时指定path和url
zuul:
routes:
user-route: # 该配置方式中,user-route只是给路由一个名称,可以任意起名。
url: http://localhost:8000/ # 指定的url
path: /user/** # url对应的路径。
这样就将/user/**映射到http://localhost:8000/,但这种方式不能使用服务降级Hytrix功能和负载均衡Ribbon。
1.6 同时指定path和url,并且不破坏Zuul的Hystrix、Ribbon特性
zuul:
routes:
user-route:
path: /user/**
service-id: microservice-provider-user
ribbon:
eureka:
enabled: false # 禁用掉ribbon的eureka使用
microservice-provider-user:
ribbon:
listOfServers: localhost:8000,localhost:8001
这样就既可以path和url,又不破坏Hytrix和Ribbon的特性。
1.7 路由前缀
示例1:
zuul:
prefix: /api
strip-prefix: false
routes:
microservice-provider-user: /user/**
访问Zuul的/api/user/路径,请求将会被转发到microservice-provider-user的/api/
示例2:
zuul:
routes:
microservice-provider-user:
path: /user/**
strip-prefix: false
这样访问Zuul的/user/路径,请求将会被转发到microservice-provider-user的/user/
1.8 忽略某些路径
zuul:
ignoredPatterns: /**/admin/** # 忽略所有包括/admin/的路径
routes:
microservice-provider-user: /user/**
Zuul的header安全
2.1 敏感header设置
zuul:
routes:
microservice-provider-user:
path: /users/**
sensitive-headers: Cookie,Set-Cookie,Authorization
这样就为microservice-provider-user指定了敏感header。
也可以全局指定敏感header:
zuul:
sensitive-headers: Cookie,Set-Cookie,Authorization
需要注意的是,如果使用zuul.routes..sensitive-headers的配置方式,会覆盖掉全局的配置。*
2.2 忽略header
zuul:
ignored-headers: Header1,Header2
这样设置后,Header1和Header2将不会传播到其他的微服务中
默认情况下zuul.ignored-headers是空值,如果Spring Security在项目的classpath中,那么zuul.ignored-headers的默认值就是Pragma,Cache-Control,X-Frame-Options,X-Content-Type-Options,X-XSS-Protection,Expires,所以,当Spring Security在项目的classpath中,同时又需要使用下游微服务的Spring Security的Header时,可以将zuul.ignoreSecurity-Headers设置为false。
注意:经测试,sensitive-headers与ignored-header的效果是一样的。
Zuul的过滤器
过滤器是Zuul的核心组件,Zuul的大部分功能都是通过过滤器实现。
过滤器类型与请求生命周期
3.1 PRE
这种过滤器在请求被路由之前调用。我们可利用这种过滤器实现身份验证、在集群中选择请求的微服务、记录调试信息等。
3.2 ROUTING
这种过滤器将请求路由到微服务。这种过滤器用于构建发送给微服务的请求,并使用Apache HttpClient或Netfilx Ribbon请求微服务。
3.3 POST
这种过滤器在路由到微服务以后执行。这种过滤器可用来为响应添加标准的HTTP Header、收集统计信息和指标、将响应从微服务发送给客户端等。
3.4 ERROR
在其他阶段发生错误时执行该过滤器。
3.5. 内置的特殊过滤器
zuul还提供了一类特殊的过滤器,分别为:StaticResponseFilter和SurgicalDebugFilter
StaticResponseFilter:StaticResponseFilter允许从Zuul本身生成响应,而不是将请求转发到源。
SurgicalDebugFilter:SurgicalDebugFilter允许将特定请求路由到分隔的调试集群或主机。
自定义过滤器
示例:
public class PreRequestLogFilter extends ZuulFilter {
private static final Logger LOGGER = LoggerFactory.getLogger(PreRequestLogFilter.class);
@Override
public String filterType() {
return "pre";
}
@Override
public int filterOrder() {
return 1;
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public Object run() {
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
PreRequestLogFilter.LOGGER.info(String.format("send %s request to %s", request.getMethod(), request.getRequestURL().toString()));
return null;
}
}
由代码可知,自定义的Zuul Filter需实现以下几个方法:
- filterType:返回过滤器的类型。有pre、route、post、error等几种取值,分别对应上文的几种过滤器。
- filterOrder:返回一个int值来指定过滤器的执行顺序,不同的过滤器允许返回相同的数字,数字越小
- shouldFilter:返回一个boolean值来判断该过滤器是否要执行,true表示执行,false表示不执行。
- run:过滤器的具体逻辑。本例中,我们让它打印了请求的HTTP方法以及请求的地址。
修改启动类,为启动类添加以下内容:
@Bean
public PreRequestLogFilter preRequestLogFilter() {
return new PreRequestLogFilter();
}
3.6 禁用过滤器
Spring Cloud默认为Zuul编写并启用了一些过滤器,例如DebugFilter、FormBodyWrapperFilter、PreDecorationFilter等。这些过滤器都存放在spring-cloud-netflix-core这个Jar包的org.springframework.cloud.netflix.zuul.filters包中。
一些场景下,我们想要禁用掉部分过滤器,只需设置zuul.<SimpleClassName>.<filterType>.disable=true ,即可禁用SimpleClassName所对应的过滤器。
以过滤器org.springframework.cloud.netflix.zuul.filters.post.SendResponseFilter为例,只需设置zuul.SendResponseFilter.post.disable=true ,即可禁用该过滤器。
单独使用Zuul
引入jar包
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zuul</artifactId>
</dependency>
说明:引入该组件会自动引入Hystrix.ribbon.actuator
在应用主类中添加注解
@EnableZuulProxy
手工配置转发
zuul.routes.user-service.path=/user-service/**
zuul.routes..user-service.serviceId=user-service
user-service.ribbon.listOfServers=http://localhost:8080/,http://localhost:8081/
经过上述配置后,网关接受到的URL为/user-service/**时,将会通过ribbon负载均衡到这两个ip上:http://localhost:8080/,http://localhost:8081/