Spring Cloud - Zuul
文章目录
请求路由,负载均衡,校验过滤
启用
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
@SpringBootApplication
@EnableEurekaClient
@EnableZuulProxy
public class ZuulApplication {
public static void main(String[] args) {
SpringApplication.run(ZuulApplication.class);
}
}
请求路由
无注册中心 (配置URL)
- 单例配置
zuul:
routes:
<route>:
path: /user/**
url: http://127.0.0.1:8080
#stripPrefix: false # 是否过滤 path
- 多例配置
zuul:
routes:
user:
path: /user/**
serviceId: spcd-user
#stripPrefix: false
ribbon:
eureka:
enabled: false # 不使用服务发现机制获取service
spcd-user:
ribbon:
NIWSServerListClassName: com.netflix.loadbalancer.ConfigurationBasedServerList
listOfServers: http://127.0.0.1:8741,http://127.0.0.1:8742 # 多实例
ConnectTimeout: 500
ReadTimeout: 10000
MaxTotalHttpConnections: 500
MaxConnectionsPerHost: 100
- 本地跳转
zuul:
routes:
<route>:
path: /user/*
url: forward:/local # zuul服务本身接口 /local/*
注册中心
使用 serviceId 为注册中心的 注册服务名即可
zuul:
ignoredServices: '*' # 禁止自动创建路由
routes:
user:
path: /user/**
serviceId: spcd-user
stripPrefix: false
默认情况下 ,Eureka上的所有服务,Zuul会自动创建路由, 规则如下
zuul.routes.<服务名>.path=/<服务名>/**
zuul.routes.<服务名>.serviceId=<服务名>
zuul.ignoredServices 可指定服务忽略自动创建路由规则 ,=* 则全部忽略,需为服务手动配置路由规则
Cookies and Sensitive Headers
Zuul默认过滤敏感头信息,不传递给下游服务,可配置如下修改
zuul:
routes:
users:
path: /myusers/**
sensitiveHeaders: Cookie,Set-Cookie,Authorization # 默认,头信息过滤,不传递给下游
#sensitiveHeaders: # 不过滤,全部传递给下游
url: https://downstream
超时 + 重试
zuul 中已集成 Hystrix 和 Ribbon ,即当 hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds > ribbon.ReadTimeout 即会发生重试,禁止重试命令如下
zuul.retryable=false
zuul.routes.<route>.retryable=false
超时设置
- 配置Eureka时,使用Ribbon超时
ribbon.ReadTimeout
ribbon.SocketTimeout
- 配置URL时,使用zuul配置超时
zuul.host.connect-timeout-millis
zuul.host.socket-timeout-millis
ZuulFilter
ZuulFilter
public int filterOrder() ; // 过滤器执行顺序, 小优先
public String filterType();
public boolean shouldFilter(); // 是否执行
public Object run(); // 执行逻辑
filterType 定义四种生命周期的过滤类型
-
pre: 在请求被路由前调用
-
ServletDetectionFilter 标记处理servlet类型 -3
-
Servlet30WrapperFilter 将HttpServletRequest 包装为 Servlet30RequestWrapper 对象
-
FromBodyWrapperFilter 包装 Content-Type: application/x-www-from-urlencoded ,multipart/form-data(ServletDetectionFilter) 的请求
还有 DebugFilter 和 PreDecorationFilter 为默认实现的 pre 的ZuulFilter
-
-
routing: 在请求在路由时调用
- RibbonRoutingFilter 对配置serviceId 的请求进行路由 (Ribbon)
- SimpleHostRoutingFilter 对配置url的请求进行路由
- SendForwardFilter 对forward.to 本地路由跳转
-
post: 在请求路由返回响应后,或发生error后 调用
- LocationRewriteFilter 重写位置头为zuul url
- SendResponseFilter 响应客户端 oreder 1000
- SendErrorFilter 错误信息 forward 到 zuul的/error接口产生错误响应
-
error: 处理请求时发生错误时被调用
Disable Zuul Filters
zuul.<SimpleClassName>.<filterType>.disable=true
zuul.SendResponseFilter.post.disable=true # org.springframework.cloud.netflix.zuul.filters.post.SendResponseFilter禁用
生命周期图
Fallback
class MyFallbackProvider implements FallbackProvider {
@Override
public String getRoute() {
return "*"; // 可指定 route
}
@Override
public ClientHttpResponse fallbackResponse(final Throwable cause) {
if (cause instanceof HystrixTimeoutException) {
return response(HttpStatus.GATEWAY_TIMEOUT);
} else {
return fallbackResponse();
}
}
@Override
public ClientHttpResponse fallbackResponse() {
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("fallback".getBytes());
}
@Override
public HttpHeaders getHeaders() {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
return headers;
}
};
}
}
动态路由
1、通过与 spring cloud config 配合使用,zuul作为 config client 端,需引入
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
2、使用bootstrap.yml 指定config server 中的配置文件 zuul-dev.yml
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:8761/eureka/
spring:
application:
name: zuul
cloud:
config:
discovery:
enabled: true
service-id: spcd-config
profile: dev
label: master
#uri: http://127.0.0.1:8711
username: user
password: 123456789
3、在zuul-dev.yml 开启 endpoints端点接口
# actuator
management:
endpoints:
web:
exposure:
include: "*"
exclude: env #必须去除 env
启动后 通过 http://127.0.0.1:8721/actuator/refresh 刷新配置