Zuul网关配置 过滤器 路由 异常处理 负载均衡

Zuul 是什么,有什么作用:

核心作用3个: 过滤、路由、异常处理
另外、Zuul 集成了负载均衡,在下面案例会有展示
下面分别讲Zuul的基础使用,以及这三个作用的案例演示:

1、基本配置如下:

1.1、添加Zuul 以及Eureka 依赖;
<!-- 网关依赖-->
<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
    </dependency>
    <!-- eureka  -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
</dependencies>
1.2、yml 文件、Zuul 路由规则配置:

由于存在Eureka 客户端,所以直接指定服务端的名字即可;
后面还有更简化的配置;

server:
  port: 10010  #端口
spring:
  application:
    name: api-gateway  # 网关名字
zuul:
  routes:
    user-service:     # 路由的 id
      path: /user-service/**  #映射路径
   #  url: http://127.0.0.1:8081   #映射路径对应的实际的url地址
    #  访问路径规则 添加 映射路径的规则
      serviceId: user-service  # 指定服务端的名称

简化配置: 直接指定服务端的 ID 指向 映射路径 path

zuul.routes..path=/xxx/**: 来指定映射路径。是自定义的路由名
zuul.routes..serviceId=/user-service:来指定服务名。
简化配置:
zuul.routes.= 即简化成如下配置:

zuul:
  routes:
    user-service: /user-service/** # 这里是映射路径

默认配置: Zuul 默认配置规则就是服务path 对应就是服务ID ,意思就是不配置Zuul 也是OK的。
忽略配置:
想要禁用某一个路由规则 采用如下配置:

zuul:
  ignored-services:
    - user-service
    - consumer
1.3、配置好Zuul ,

访问代理 http://localhost:10010/user-service/user/2
出现500报错,报错如下:

com.netflix.zuul.exception.ZuulException: Forwarding error
、、省略
Caused by: com.netflix.client.ClientException: Load balancer does not have available server for client: path

异常原因如下图:
在这里插入图片描述

明显路径映射不对,仔细查看发现yml 文件中path 、url 和user-service 在同一级路径了,都是坑;
修改如下图,恢复正常访问;
在这里插入图片描述
1、添加前缀: /api
使用 zuul.prefix : /api 的语法,yml具体配置如下:
访问:http://localhost:10010/api/user-service/user/2

zuul:
  prefix: /api   # 添加路由前缀
  routes:
    user-service:     # 路由的 id
      path: /user-service/**  #映射路径
   #  url: http://127.0.0.1:8081   #映射路径对应的实际的url地址
    #  访问路径规则 添加 映射路径的规则
      serviceId: user-service  # 指定服务端的名称

在这里插入图片描述

访问结果如下:
在这里插入图片描述

1、异常处理:

zuul 为我们提供了一个名叫 ZuulFallbackProvider 的接口、在服务挂掉时候调用该接口返回信息,我们通过实现该接口,重写接口中fallbackResponse 方法,返回错误的处理规则、给出信息提示:

@Component
public class ApiFallbackProvider implements ZuulFallbackProvider{
    @Override
    public String getRoute() {
        return "eurekaclient";
    }
    @Override
    public ClientHttpResponse fallbackResponse() {
        return new ClientHttpResponse() {
            @Override
            public HttpStatus getStatusCode() throws IOException {
                return HttpStatus.OK;
            }
    
            @Override
            public int getRawStatusCode() throws IOException {
                return 200;
            }
    
            @Override
            public String getStatusText() throws IOException {
                return "{code:0,message:\"服务器异常!\"}";
            }
    
            @Override
            public void close() {
    
            }
    
            @Override
            public InputStream getBody() throws IOException {
                return new ByteArrayInputStream(getStatusText().getBytes());
            }
    
            @Override
            public HttpHeaders getHeaders() {
                HttpHeaders headers = new HttpHeaders();
                headers.setContentType(MediaType.APPLICATION_JSON);
                return headers;
            }
        };
    }

2、动态路由:

Zuul 实现动态路由,是因为Zuul 集成的有负载均衡、有负载均衡的效果。

  • 首先更改服务提供者 EurekaClient 端口、启动多个服务提供者,然后访问服务 http://localhost:8761/ 如下图,有2个服务提供者:
  • 启动网关、 不断访问地址:http://localhost:8080/api/index 会看到如下,端口交替出现、意味着服务提供者交替提供服务; 就是默认的轮询 的方式;
    在这里插入图片描述

3、过滤、服务拦截:

1、服务网关还有个作用就是接口的安全性校验,这个时候我们就需要通过 zuul 进行统一拦截,zuul 通过继承过滤器 ZuulFilter进行处理:
2、重写ZuulFilter 类中的 方法、

package com.syntactic.filter;
/**
 * @auther SyntacticSugar
 * @data 2018/12/5 0005下午 5:00
 */
@Component
public class ApiFilter extends ZuulFilter {
    @Override
    public String filterType() {
        return "pre";
    }

    @Override
    public int filterOrder() {
        return 0;
    }

    @Override
    public boolean shouldFilter() {
        return true;
    }

    @Override
    public Object run() {
        // 逻辑代码
    }
}

filterType 为过滤类型,可选值有:pre(路由之前)、routing(路由之时)、post(路由之后)、error(发生错误时调用)。
filterOrdery为过滤的顺序,如果有多个过滤器,则数字越小越先执行
shouldFilter 表示是否过滤,这里可以做逻辑判断,true 为过滤,false不过滤
run 为过滤器执行的具体逻辑;

以下逻辑做一个权限校验:

 @Override
public Object run() {
    // 逻辑代码
    RequestContext currentContext = RequestContext.getCurrentContext();
    HttpServletRequest request = currentContext.getRequest();
    //  获取传递的参数、验证权限
    String token = request.getParameter("token");
    //
    if (!"123456".equals(token)) {
        currentContext.setSendZuulResponse(false);
        currentContext.setResponseStatusCode(400);
        //  把提示信息显示到 页面
        try {
            currentContext.getResponse().getWriter().write("token is invalid");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    return null;
}

访问:http://localhost:8080/api/index 非法
在这里插入图片描述

访问 http://localhost:8080/api/index?token=12345 有效
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值