天天看点

springcloud组件 ------ Zuul网关介绍搭建Zuul网关服务器路由过滤器Zuul原理弊端

文章目录

  • 介绍
  • 搭建Zuul网关服务器
  • 路由
  • 过滤器
    • 自定义zuulFilter
      • 身份认证示例
  • Zuul原理
  • 弊端

介绍

Zuul是Netflix开源的微服务网关,它可以和Eureka、Ribbon、Hystrix等组件配合使用,Zuul组件核心是一系列过滤器,这些过滤器可以完成:

  • 动态路由:动态将请求路由到不同后端集群
  • 压力测试:逐渐增加指向集群的流量,以了解性能
  • 负载分配:为每一种负载类型分配对应的容量,并弃用超出限定值的请求
  • 静态相应处理:边缘位置进行响应,避免转发到内部集群
  • 身份认证和安全:识别每个一资源的验证要求,并拒绝那些不符合的请求。Spring Cloud对Zuul进行了整合和增强

搭建Zuul网关服务器

  • 创建一个新的maven工程,引入依赖
<dependency>
    <groupId>org.springframework.cloud</groupId>
     <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
 </dependency>
           
  • 配置yml
server:
  port: 8888 #端口
spring:
  application:
    name: api-zuul-service #服务名称
           
  • 启动类
@SpringBootApplication
//开启Zuul网关功能
@EnableZuulProxy
public class ZuulServerApplication {

    public static void main(String[] args) {
        SpringApplication.run(ZuulServerApplication.class,args);
    }

}
           

路由

路由:根据请求的url将请求分配到对应的微服务中进行处理。

  • 基础路由配置
#路由配置
zuul:
  routes:
    #例子
    product-service: #路由id
      path: /product-service/**  #映射路径 #localhost:8888/product-service/xxxxx
      url: http://192.168.0.107:9001/ #映射路径对应的实际地址
           

访问:http://127.0.0.1:8888/product-service/product/getProduct/1

  • 面向服务的路由配置(整合Eureka)

    1.添加Eureka的依赖

<dependency>
   <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
           

2.开启Eureka的客户端服务发现

//在启动类上添加注解(比较新的版本可以不加)
@EnableDiscoveryClient
           

3.在Zuul网关服务中配置Eureka的注册中心相关信息

添加eureka配置

#eureka配置
eureka:
  client:
    service-url:
      defaultZone: http://localhost:9000/eureka/,http://localhost:8999/eureka/
  instance:
    prefer-ip-address: true #使用ip地址注册
    instance-id: ${spring.cloud.client.ip-address}:${server.port} #向注册中心中注册ip
           

4.修改路由中的映射配置

#路由配置
zuul:
  routes:
    #例子
    product-service: #路由id
      path: /product-service/**  #映射路径 #localhost:8888/product-service/xxxxx
      # url: http://192.168.0.107:9001/ #映射路径对应的实际地址
      serviceId: product-service #配置转发的微服务的服务名称
           
  • 简化路由配置
#路由配置
zuul:
  routes:
    #如果当前的微服务名称product-service,默认的请求映射路径 /product-service/**
    # 如果路由id和对应的微服务的serviceId一致的话
    product-service: /product-service/**
           

其实不配置也可以,比如,现在配置文件上没有配置comsumer-service,但是如果直接访问:http://127.0.0.1:8888/consumer-service/demo/get/1,也是完全没问题的。

过滤器

Zuul中的过滤器跟我们使用的javax.servlet.Filter不一样,javax.servlet.Filter只有一种类型,可以通过配置urlPatterns来拦截对应的请求。而Zuul中的过滤器一共就4种类型,而且每一种类型都有对应的使用场景:

  • PRE:这种过滤器在请求被路由之前调用。我们可以利用这种过滤器实现身份验证、在集权中选择请求的微服务、记录调试信息等。
  • ROUTING:这种过滤器将请求路由到微服务。这种过滤器用于构建发送给微服务的请求,并使用Apache HttpClient或者Netfilx Ribbon请求微服务。
  • POST:这种过滤器在路由到微服务以后执行。这种过滤器可用来为响应添加标准的HTTP Header、收集统计信息和指标、将响应从微服务发送给客户端等。
  • ERROR:在其他阶段发生错误时执行该过滤器。

    调用顺序示意图:

    springcloud组件 ------ Zuul网关介绍搭建Zuul网关服务器路由过滤器Zuul原理弊端

自定义zuulFilter

1.继承ZuulFilter ,实现四个方法

2.将LoginFilter 交给spring容器管理

/**
 * 自定义的zuul过滤器
 * 继承抽象父类
 * */
@Component
public class LoginFilter extends ZuulFilter {

    /**
     * 定义过滤器类型
     * pre
     * routing
     * post
     * error
     * */
    @Override
    public String filterType() {
        return "pre";
    }


    /**
     * 指定过滤器的执行顺序
     *      返回值越小,执行顺序越高
     * */
    @Override
    public int filterOrder() {
        return 1;
    }

    /**
     * 当前过滤气是否生效
     *  true:使用
     *  false:不适用
     * */
    @Override
    public boolean shouldFilter() {
        return true;
    }

    /**
     * 执行过滤器中的业务逻辑
     * */
    @Override
    public Object run() throws ZuulException {
        System.out.println("执行了过滤器");
        return null;
    }
}

           

身份认证示例

重写run方法

/**
 * 执行过滤器中的业务逻辑
 *  身份认证:
 *      1.所有的请求需要携带一个参数:access-token
 *      2.获取request请求
 *      3.通过request获取参数access-token
 *      4.判断token是否为空
 *      4.1 token == null:身份验证失败
 *      4.2 token != null:执行后续操作
 * */
@Override
public Object run() throws ZuulException {
    //1.获取zuul提供的上下文对象RequestContext
    RequestContext ctx = RequestContext.getCurrentContext();
    //2.从RequestContext中获取request
    HttpServletRequest request = ctx.getRequest();
    //3.获取请求参数access-token
    String token = request.getParameter("access-token");
    //4.判断
    if(token == null){
        ctx.setSendZuulResponse(false);//拦截请求
        ctx.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());
    }
    //继续执行
    return null;
}
           

Zuul原理

springcloud组件 ------ Zuul网关介绍搭建Zuul网关服务器路由过滤器Zuul原理弊端

弊端

1.请求线程池同步阻塞问题

2.不支持WebSoucket