Spring Cloud Zuul网关服务

作者: 山东大葱哥 | 来源:发表于2019-05-20 21:05 被阅读38次

内容简介

Zuul网关的功能和工作机制、结合代码介绍如何使用Zuul构建一个简单的网关、介绍Zuul的路由配置方式、了解Filter工作原理并实现一些扩展功能。

Zuul网关简介

Zuul是Spring Cloud全家桶中的微服务API网关。
所有从设备或网站来的请求都会经过Zuul到达后端的Netflix应用程序。作为一个边界性质的应用程序,Zuul提供了动态路由、监控、弹性负载和安全功能。Zuul底层利用各种filter实现如下功能:

  • 认证和安全 识别每个需要认证的资源,拒绝不符合要求的请求。
  • 性能监测 在服务边界追踪并统计数据,提供精确的生产视图。
  • 动态路由 根据需要将请求动态路由到后端集群。
  • 压力测试 逐渐增加对集群的流量以了解其性能。
  • 负载卸载 预先为每种类型的请求分配容量,当请求超过容量时自动丢弃。
  • 静态资源处理 直接在边界返回某些响应。

编写一个Zuul网关

1、新建一个zuul-demo模块,在依赖项处添加【Cloud Discovery->Eureka Discovery和Cloud Rouing->Zuul】。

2、修改入口类,增加EnableZuulProxy注解

@SpringBootApplication
@EnableZuulProxy
public class ZuulDemoApplication {
 
    public static void main(String[] args) {
        SpringApplication.run(ZuulDemoApplication .class, args);
    }
}
  1. 修改appliation.yml
server:
  port: 7000
spring:
  application:
    name: zuul-demo
eureka:
  client:
    service-url:
      defaultZone: http://localhost:7001/eureka/
  instance:
    prefer-ip-address: true  
    #将IP注册到Eureka Server上,而如果不配置就是机器的主机名。

4、启动Eureka Server、orderservice和 Zuul-Demo,在浏览器中输入http://localhost:7000/orderservice/order/pay 获取返回结果。

从上面的例子中的地址可以看出来默认Zuul的路由方式是:http://ZUULHOST:ZUULPORT/serviceId/**

如果启动多个orderservice可以发现Zuul里面还内置了Ribbon的负载均衡功能。

Filter工作原理

Zuul中的Filter

Zuul是围绕一系列Filter展开的,这些Filter在整个HTTP请求过程中执行一连串的操作。
Zuul Filter有以下几个特征:
Type:用以表示路由过程中的阶段(内置包含PRE、ROUTING、POST和ERROR)
Execution Order:表示相同Type的Filter的执行顺序
Criteria:执行条件
Action:执行体

Zuul请求生命周期

一图胜千言,下面通过官方的一张图来了解Zuul请求的生命周期。


image.png

自定义一个Filter实现token验证

  1. 添加一个AuthZuulFilter
public class AuthZuulFilter extends ZuulFilter {
    // 日志输出器
    private final static Logger LOGGER = LoggerFactory.getLogger(AuthZuulFilter.class);

    @Value("${server.port}")
    private String serverPort;

    //四种类型:pre,routing,error,post
    @Override
    public String filterType() {
        return FilterConstants.PRE_TYPE;
    }

    //自定义过滤器执行的顺序,数值越大越靠后执行,越小就越先执行
    @Override
    public int filterOrder() {
        return FilterConstants.PRE_DECORATION_FILTER_ORDER;
    }

    //控制过滤器生效不生效,可以在里面写一串逻辑来控制
    @Override
    public boolean shouldFilter() {        
        return true;
    }

    //执行过滤逻辑
    @Override
    public Object run() throws ZuulException {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        //从请求头中获取token信息
        String userToken = request.getHeader("userToken");
        LOGGER.debug("网关端口:" + serverPort);
        if (StringUtils.isEmpty(userToken)) {
            //设置为false就不会继续执行服务代码
            ctx.setSendZuulResponse(false);
            //设置状态码
            ctx.setResponseStatusCode(401);
            //设置相应信息
            ctx.setResponseBody("userToken is null");
            return null;
        }
        return null;
    }
}
  1. 修改启动程序,添加Filter注入:
    @Bean
    public AuthZuulFilter authZuulFilter() {
        AuthZuulFilter filter = new AuthZuulFilter();
        return filter;
    }

路由配置

Zuul提供了一套简单且强大路由配置策略,利用路由配置我们可以完成对微服务和URL更精确的控制

  1. 重写指定微服务的访问路径:
zuul:
  routes:
    rest-demo: /rest/**

这表示将rest-demo微服务的地址映射到/rest/**路径。

  1. 忽略指定微服务:
zuul:
  ignored-services: rest-demo,xxx-service

使用“*”可忽略所有微服务,多个指定微服务以半角逗号分隔。

3、忽略所有微服务,只路由指定微服务:

zuul:
  ignored-services: *
  routes:
    rest-demo: /rest/**

4、路由别名:

zuul:
  routes:
    route-name: #路由别名,无其他意义,与例1效果一致
      service-id: rest-demo
      path: /rest/**

5、指定path和URL

zuul:
  routes:
    route-name:
      url: http://localhost:8000/
      path: /rest/** 

此例将http://ZUULHOST:ZUULPORT/rest/映射到http://localhost:8000/,同时由于并非用service-id定位服务,所以也无法使用负载均衡功能。

注意点:

  1. cookie处理
zuul:
  sensitive-headers:   cookie,header之类额东西
  #sensitive-headers 表示要被过滤的头,黑名单,为空则可放行所有请求头。

相关文章

网友评论

    本文标题:Spring Cloud Zuul网关服务

    本文链接:https://www.haomeiwen.com/subject/djelzqtx.html