Zuul是基于JVM的路由和服务端负载均衡器。
Zuul中的EnableZuulProxy和EnableZuulServer区别:
EnableZuulServer没有代理功能,只有pre,post,error过滤器,没有route过滤器。而EnableZuulProxy是有代理功能的,除了有EnableZuulServer提供的过滤器外,还有新增的过滤器,比如route过滤器。也就是说,EnableZuulProxy是包含EnableZuulServer的。
EnableZuulServer过滤器:
Pre filters:
ServletDetectionFilter,FormBodyWrapperFilter,DebugFilter,SendForwardFilter。
Post filters:SendResponseFilter,对响应进行处理。
Error filters:SendErrorFilter,在所有过滤器执行过程中,发生异常时,处理的过滤器。
EnableZuulProxy过滤器(包含以上过滤器):
Pre filters:PreDecorationFilter,如何路由。
Route filters::RibbonRoutingFilter,SimpleHostRoutingFilter,分别指对服务路由和host路由。
前提条件:
spring cloud版本:Finchley.RC2
application.yml:
eureka:
client:
serviceUrl:
defaultZone: http://node1:8771/eureka/,http://node2:8772/eureka/
server:
port: 8799
spring:
application:
name: service-zuul
zuul:
routes:
#只是一个id,不一定要是服务名
serviceProvider1:
path: /helloService/**
serviceId: serviceProvider
local1:
path: /local/**
url: forward:/
localForward1:
path: /**
url: forward:/localForward
nostripPrefix1:
path: /nostripPrefix/**
url: forward:/
stripPrefix: false
serviceprovider: #服务名
ribbon:
#按响应时间的权重分配请求,时间越短,权重越大,分配到请求的几率越大
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.WeightedResponseTimeRule
启动类:
@SpringBootApplication
@EnableZuulProxy
@EnableDiscoveryClient
@RestController
public class ZuulApplication {
public static void main(String[] args) {
SpringApplication.run(ZuulApplication.class, args);
}
@Bean
public IRule weightedResponseTimeRule() {
return new WeightedResponseTimeRule();//这里配置策略,和配置文件对应
}
@RequestMapping("/hello")
public String hello() {
return "local hello";
}
@RequestMapping("/localForward/hello")
public String localForward() {
return "localForward hello";
}
@RequestMapping("/nostripPrefix/hello")
public String nostripPrefix() {
return "nostripPrefix hello";
}
}
pre类型的过滤器:
@Component
public class MyFilter extends ZuulFilter {
@Override
public String filterType() {
return FilterConstants.PRE_TYPE;
}
@Override
public int filterOrder() {
return PRE_DECORATION_FILTER_ORDER - 1;
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public Object run() throws ZuulException {
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
String token = request.getParameter("token");
if (token == null) {
ctx.setSendZuulResponse(false);
ctx.setResponseStatusCode(HttpServletResponse.SC_BAD_REQUEST);
try {
ctx.getResponse().getWriter().write("no permission");
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
}
依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
启动一个erueka server,启动不同端口的2个服务提供者。如下
以下测试不同路由场景:
一.服务路由
1.localhost:8799/helloService/hello?name=lishi,token校验
2.localhost:8799/helloService/hello?name=lishi&token=1,这里是按serviceId来路由的,按响应时间负载均衡。
二.本地路由
1.localhost:8799/local/hello?name=lishi&token=1,重定向到本地/hello请求
2.localhost:8799/hello?name=lishi&token=1,重定向到本地/localForward/hello请求
3.localhost:8799/nostripPrefix/hello?name=lishi&token=1,重定向到本地/nostripPrefix/hello请求
总结:
Zuul一般用于对外提供统一接口,服务端进行负载均衡和反向代理
项目源码:https://github.com/bawcwchen/zuulDemo.git