六、微服务网关-Zuul

上一章:声明式服务调用-Feign

Zuul是什么?

Zuul是Netflix开源的微服务网关,可以和Eureka、Ribbon、Hystrix等组件配合使用,而Spring Cloud对Zuul进行了整合和增强,Zuul默认使用的HTTP客户端是Apache HTTPClient,Zuul的主要功能是路由转发和过滤器。路由功能是微服务的一部分,Zuul默认和Ribbon结合实现了负载均衡的功能。

Zuul使用很多不同类型的过滤器,那么这些过滤器的功能有哪些呢?

  • 身份验证和安全性:确定每个资源的身份验证要求并拒绝不满足这些要求的请求

  • 洞察和监控:跟踪有意义的数据和统计数据,以便我们提供准确的生产视图

  • 动态路由:根据需要动态的将请求路由到不同的后端集群

  • 压力测试:逐渐增加集群的流量以衡量性能

  • Load Shedding:为每种类型的请求分配容量并删除超过限制的请求

  • 静态响应处理:直接在边缘构建一些响应,而不是将它们转发到内部集群

以上是官方的,开源的jar实际上并没有这么多功能,可能他们内部用的有这些功能

Zuul的组件

  • zuul-core-zuul核心库:包含编译和执行过滤器的核心功能。
  • zuul-simple-webapp-zuul Web应用程序实例:展示了如何使用zuuk-core构建应用程序。
  • zuul-netflix-lib包:将其他NetflixOSS组件添加到Zuul中,例如使用功能区进去路由请求处理。
  • zuul-netflix-webapp-webapp:它将zuul-core和zuul-netflix封装成一个简易的webapp工程包。

搭建Zuul服务

单独创建一个新的服务,server-zuul
配置server-zuul的pom.xml

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
    <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>
</dependencies>

在启动类加入@EnableZuulProxy,开启zuul

/**
 * zuul路由网关服务
 *
 * @author: Aaron
 * @date: 2020/1/15 09:51
 * @param:
 * @description:
 * @return:
 */
@EnableZuulProxy
@EnableDiscoveryClient
@SpringBootApplication
public class ZuulApplication {

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

}

在application.yml配置服务的基本信息和路由规则
#配置端口

server:
  port: 8085
#配置服务名称
spring:
  application:
    name: server-zuul

eureka:
  client:
    service-url:
      #配置注册中心地址
      defaultZone: http://peer1:8081/eureka

#配置路由规则
zuul:
  #写法1:自定义服务路径
  routes:
    server-user: /test1/**
    server-org: /test2/**
    
  #忽略指定服务,多个服务用逗号隔开,ps:若想忽略所有服务,改成【'*'】即可
#  ignored-services: server-user,server-org

依次启动注册中心、user服务、org服务、zuul服务
访问地址:http://localhost:8085/test2/org/test?name=Aaronhttp:localhost:8085/test1/user/self?name=Aaron
在这里插入图片描述
如果能够正常显示 my name is Aaron,说明zuul起到了路由的作用。

服务过滤

zuul除了路由,过滤也是一个很重要的功能,它可以帮助我们在进入服务之前或者之后做一个自定义校验,配置自己的过滤规则
创建AccessTokenFliter.java类,配置token的校验规则

package com.yun.zuul.filter;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;

/**
 * AccessToken验证
 *
 * @author Aaron
 * @date 2020/1/16 10:18
 */
@Component
@Log4j2
public class AccessTokenFilter extends ZuulFilter {
    /**
     * 过滤的类型
     * 1、pre:路由之前
     * 2、routing:路由之时
     * 3、post:路由之后
     * 4、error:发送错误调用
     *
     * @return
     */
    @Override
    public String filterType() {
        return "pre";
    }

    /**
     * 过滤的顺序,默认就好
     *
     * @return
     */
    @Override
    public int filterOrder() {
        return 0;
    }

    /**
     * 是否过滤
     *
     * @return
     */
    @Override
    public boolean shouldFilter() {
        return true;
    }

    @Override
    public Object run() throws ZuulException {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        log.info(String.format("%s >>> %s", request.getMethod(), request.getRequestURL().toString()));
        //获取请求地址中的token参数,参数的位置可以根据需求来
        Object accessToken = request.getParameter("token");
        if (accessToken == null) {
            log.warn("token is empty");
            ctx.setSendZuulResponse(false);
            ctx.setResponseStatusCode(502);
            try {
                ctx.getResponse().getWriter().write("token is empty");
            } catch (Exception e) {
                log.error(e);
            }
            return null;
        }
        //
        // 校验token的有效性,这里就不写了,根据自己的校验规则写
        //
        log.info("ok");
        return null;
    }
}

重启服务之后再次调用http://localhost:8085/test1/user/self?name=Aaron,返回结果如下图,token is empty 说明我们的拦截起到了作用
在这里插入图片描述

现在我们再加上token参数试一下,http://localhost:8085/test1/user/self?name=Aaron&token=1111,就可以正常返回了
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值