路由网关--spring cloud zuul
路由网关--spring boot Zuul
1.为什么需要Zuul?
- Zuul Ribbon 以及 Eureka 相结合,可以实现智能路由和负载均衡的功能, Zuul 能够将请求流量按某种策略分发到集群状态的多个服务实例。
- 网关将所有服务的 API 接口统 聚合,并统 对外暴露。外界系统调用 PI 接口时,都是由网关对外暴露的 PI 接口,外界系统不需要知道微服务系统中各服务相互调用的复杂性。微服务系统 保护了其内部微服务单元的 API 接口 防止其被外界直接调用,导致服务的敏感信息对外暴露。
- 网关服务可以做用户身份认证和权限认证,防止非法请求操作 PI 接口,对服务器起到保护作用。
- 网关可以实现监控功能,实时日志输出,对请求进行记录。
- 网关可以用来实现流量监控 在高流量的情况下,对服务进行降级。
- API 接口从内部服务分离出来 方便做测试。
Zuul工作原理
Zuul 是通过 Servlet 来实现的, Zuul 通过自定义的 Zuu!Servlet (类似于 Spring MVC DispatcServlet 〕来对请求进行控制。 Zuul 的核心 系列过滤器,可以在 Http 请求的发起和响应返回期间执行 系列的过滤器。
- PRE 过滤器:它是在请求路由到具体的服务之前执行的,这种类型的过滤器可 以做安全验证,例如身份验证、 参数验证等。
- ROUTING 过滤器 它用于将请求路由到具体的微服务 。在默认情况下,它使用Http Client 进行网络请求。
- POST 过滤器:它是在请求己被路由到微服务后执行的 般情况下,用作收集统计信息、指标,以及将响 传输到客户端。
- ERROR 过滤器:它是在其他过滤器发生错误时执行的
Zuul 采取了动态读取、编译和运行这些过滤器 过滤器 间不能直接 信,而是通RequestContext 对象来共享数据 每个请求都会创建 RequestContext 对象 Zuul 过滤
具有 以下关键特性。
Type (类型) Zuul 过滤器的类型,这个类型决定了过滤器在请求的哪个阶段起作用,例如 Pre Post 阶段等。
Execution Order (执行顺序) :规定了过滤器的执行顺序, Order 的值越小,越先执行
Criteria (标准) Filter 行所需的条
Action (行动〉 如果符合执行条件,则执行 ction (即逻辑代码)。
Zuul生命周期
当一个客户端 Request 请求进入 Zuul 服务时,网关先进入“pre filter 进行一 系列的验证、操作或者判断 然后交给“routing filter ”进行路由转发,转发到具体的服务实例进行逻辑处理、返回数据。当具体的服务处理完后,最后由“post filter ”进行处理, 该类型的处
理器处理完之后,将 Response 信息返回给客户端。
Demo
项目名称:eureka-zuul-client
再启动类EurekaZuulClientApplication加上EnableEurekaClient注解,开启EurekaClient功能,加上@EnableZuulProxy注解,开启Zuul注解
@EnableZuulProxy
@EnableEurekaClient
@SpringBootApplication
public class EurekaZuulClientApplication{
public static void main(String[] args){
SpringApplication.run(EurekaZuulClientApplication.class,args);
}
}
application.yml配置
enruka:
client:
serviceUrl:
defaultZone:http://localhost:8761/eureka/
server:
port:5000
spring:
application:
name:service-zuul
zuul:
routes:
hiapa:
path:/hiapi/**
serviceId:eureka-client
ribbonapi:
path:/ribbonapi/**
serviceId:eureka-ribbon-client
feignapi:
......
zuul.prefix:XXXX版本号 //给api配置版本号
在Zuul上实现,熔断器
Zuul实现熔断功能需要实现 ZuulFallbackProvider 接口。实现该接口有两个方法,getRoute()方法,用于指定熔断功能应用于哪些路由的服务 个方法 fallbackResponseO为进入熔断功能时执行的逻辑
zuul中使用过滤器
@Component
public class MyFilter extends ZuulFilter
{
private static Logger log=LoggerFactory.getLogger(MyFilter.class);
@Override
public String filterType(){
return Pre_TYPE;
}
@Override
public int filterOrder(){
return 0;
}
@Override
public boolean shouldFilter(){
return true;
}
public Object run(){
RequestContext ctx=RequestContext.getCurrentContext();
HttpServletRequest request=ctx.getRequest("");
Object accessToken=request.getParameter("token");
if(accessToken==null){
log.warn("token is empty");
ctx.setSendZuulResponse(false);
ctx.setResponseStatusCode(401);
try{
ctx.getResponse().write("token is empty");
}catch(Exception e){
return null;
}
}
log.info("ok");
return null;
}
}
Zuul的常见使用方式
Zuul是采用类似于Spring mvc的DispatchServlet来实现的,采用的是异步阻塞模型,性能比ngnix差,由于Zuul和其他Netflix组件可以相互配合,无缝集成,Zuul很容易就能实现负载均衡,智能路由,熔断器。由于 川的横向扩展能力非常好,所以当负载过高时,可以通过添加实例来解决性
能瓶颈。
一种常见的使用方式是对不同的渠道使用不同的 Zuul 来进行路由,例如移动端共用Zuul 关实例 Web 端用另 Zuul 网关实例,其他的客户端用另外 Zuul 实例进行路由另外已种常见的集群是通过 Ngnix Zuul 相互结合来做负载均衡。暴露在最外面的是Ngnix 从双热备进行 Keepalive, Ngnix 经过某种路由策略,将请求路由转发到 Zuul 集群上,Zuul 最终将请求分发到具体的服务上。