项目源码下载:(访问密码:9987)
spring-cloud-apigateway_zuul.zip

学习使用Netflix Zuul及其与Spring Cloud 的牢固结合来创建负载均衡器。这里我们将主要关注API 网关模式及其用法。我们将构建一个netflix zuul 示例,我们将在其中创建一个微服务生态系统并测试其在整个生态系统中Zuul API 网关的有效性和适用性。

这是一种非常常见的微服务模式,而 Netflix,Zuul 的创建者大量且智能地利用了这一点,并且 Netflix 声称所有 Netflix 流量首先进入一个 Zuul 集群,该集群主要负责基于不同的动态路由、监控、弹性和安全性。基于 groovy 的自定义过滤器。
 

1. Zuul 在微服务生态系统中的位置?

在构建微服务时,一个常见的问题是为系统的客户端应用程序提供一个独特的网关。事实上,您的服务被拆分为用户不应该看到的小型微服务应用程序,否则可能会导致大量的开发/维护工作。还有一些场景,整个生态系统网络流量可能会通过一个点,这可能会影响集群的性能。
为了解决这个问题,Netflix(微服务的主要采用者)创建并开源了其Zuul 代理服务器,后来 Pivotal 旗下的 Spring 在其Spring Cloud 堆栈中对此进行了调整,使我们能够通过几个简单的步骤轻松有效地使用 zuul。

Zuul 是一种边缘服务,可将请求代理到多个支持服务。它为您的生态系统提供了一个统一的“前门”,允许任何浏览器、移动应用程序或其他用户界面使用来自多个主机的服务。您可以将 Zuul 与其他 Netflix 堆栈组件(如用于容错的 Hystrix 和用于服务发现的 Eureka)集成,或使用它来管理整个系统的路由规则、过滤器和负载平衡。最重要的是,所有这些组件都通过 spring 引导/云方法被 spring 框架很好地适应。
zuul地位
 

2. Zuul 组件

Zuul 主要有四种类型的过滤器,使我们能够拦截任何特定事务的请求处理的不同时间线中的流量。我们可以为特定的 url 模式添加任意数量的过滤器。
  • 前置过滤器——在请求被路由之前调用。
  • 后过滤器——在请求被路由后调用。
  • 路由过滤器——用于路由请求。
  • 错误过滤器——在处理请求时发生错误时调用。
zuul 组件

3.netflix zuul示例概述

现在让我们通过使用 Zuul 代理创建一个简单而有意义的生态系统来让我们的手变脏。我们将创建以下工件来演示整个过程:
  • Student Microservice – 一个基于 spring boot 的微服务,它只公开一个 url 来启用一些搜索功能。为简单起见,我们将只返回硬编码值,但在现实世界中,我们可以从该服务连接到任何地方以获取数据。
  • Zuul 网关服务代理——又是一个基于 spring boot 的,基本上会拦截学生服务的所有流量并应用一系列请求过滤器,然后路由到底层服务,再次在响应服务时,它会应用一些响应过滤。由于它是一个网关,我们可以有效地使用过滤器来采取许多有趣且有用的操作。网关服务的一些共同责任是——
    • 在网关层应用微服务认证和安全保护实际服务
    • 我们可以通过启用一些日志记录来获取边缘的有意义的数据和统计数据,以便为我们提供准确的生产视图,从而对进入生态系统的所有流量进行微服务洞察和监控
    • 动态路由可以根据需要将请求路由到不同的后端集群。
    • 我们可以通过逐渐增加到新集群的流量来进行运行时压力测试,以便在许多情况下衡量性能,例如集群具有新的硬件和网络设置或部署了新版本的生产代码。
    • 我们可以进行动态减载,即为每种类型的请求分配容量并丢弃超过限制的请求。
    • 我们可以应用静态响应处理,即直接在边缘构建一些响应,而不是将它们转发到内部集群进行处理。

技术栈和运行时

  • Java 1.8 和 Eclipse IDE 作为开发环境

  • Spring cloud Zuul 作为网关代理提供者

  • Spring Boot 作为应用程序框架

  • 用于将微服务公开为 REST 的 Spring Rest

  • Maven 作为构建工具

4. 创建学生微服务

按照以下步骤开发学生微服务,它将公开几个 REST 端点,稍后将通过 zuul 代理访问这些端点。稍后我们将研究 zuul 部分,现在让我们先创建学生服务。

4.1. 创建 Spring Boot 项目

从具有依赖项的spring 初始值设定项门户创建一个 Spring boot 项目,即WebRest Repositories。给出其他maven GAV坐标并下载项目。
服务创建
将项目解压缩并作为existing maven project. 在此步骤中,使用命令执行全新的 Maven 构建,mvn clean install以便正确下载所有 Maven 依赖项。

4.2. 添加几个 REST 端点

我们现在只需向此服务添加几个 REST 端点,以便稍后测试代理。为此,我们需要通过添加 annotation 来添加一个 REST 控制器@RestController。为简单起见,我们将添加一个模型类Student
所有更改后,类将如下所示。
import java.util.Date;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
 
@RestController
@SpringBootApplication
public class SpringBootStudentServiceApplication 
{
    @RequestMapping(value = "/echoStudentName/{name}")
    public String echoStudentName(@PathVariable(name = "name") String name) 
    {
        return "hello  <strong style=\"color: red;\">" + name + " </strong> Responsed on : " + new Date();
    }
 
    @RequestMapping(value = "/getStudentDetails/{name}")
    public Student getStudentDetails(@PathVariable(name = "name") String name) 
    {
        return new Student(name, "Pune", "MCA");
    }
 
    public static void main(String[] args) 
    {
        SpringApplication.run(SpringBootStudentServiceApplication.class, args);
    }
}
 
class Student 
{
    String name;
    String address;
    String cls;
 
    public Student(String name, String address, String cls) {
        super();
        this.name = name;
        this.address = address;
        this.cls = cls;
    }
 
    public String getName() {
        return name;
    }
 
    public String getAddress() {
        return address;
    }
 
    public String getCls() {
        return cls;
    }
}

4.3. 应用程序配置

现在打开application.properties文件并添加这些条目。
spring.application.name=student
server.port=8090
在这里,我们通过属性为该服务命名,spring.application.name=student并且我们通过server.port=8090. 我们需要覆盖默认端口,因为我们将有多个不同微服务的实例将在 localhost 中运行。

4.4. 验证学生服务

最后使用 command 进行 maven 构建,mvn clean install并通过运行 command 将该项目作为 spring boot 应用程序启动java -jar target\spring-boot-zuulgatwayproxy-student-service-0.0.1-SNAPSHOT.jar。现在一旦服务器启动,转到浏览器并测试端点是否正常工作。
http://localhost:8090/echoStudentName/Sajal
浏览器输出
http://localhost:8090/getStudentDetails/Sajal
不通参数输出

现在我们将使用 Zuul 创建实际的代理服务。
 

5.创建Zuul网关服务代理

这将再次是一个基于 Spring Boot 的微服务,但它有一个特殊的功能。它将使用 zuul 创建一个 API 网关代理,该代理将代理学生服务。之后我们可以添加任意数量的微服务,比如学生服务,并能够创建一个强大的微服务生态系统。

5.1. 创建 Spring Boot 项目

从具有依赖项的spring 初始值设定项门户创建一个 Spring boot 项目Zuul 。给出其他maven GAV坐标并下载项目。
zuul项目创建

解压缩该项目并将其作为现有的 maven 项目导入 Eclipse。在此步骤中,使用命令执行全新的 Maven 构建,mvn clean install以便正确下载所有 Maven 依赖项。

5.2. 启用 Zuul 服务代理

现在@EnableZuulProxysrc文件夹中存在的 Spring boot 应用程序类上添加注释。有了这个注解,这个工件将像一个 Zuul 服务代理,并将启用 API 网关层的所有功能,如前所述。然后我们将添加一些过滤器和路由配置。
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
import org.springframework.context.annotation.Bean;
import com.example.springbootzuulgatwayproxy.filters.ErrorFilter;
import com.example.springbootzuulgatwayproxy.filters.PostFilter;
import com.example.springbootzuulgatwayproxy.filters.PreFilter;
import com.example.springbootzuulgatwayproxy.filters.RouteFilter;
 
@SpringBootApplication
@EnableZuulProxy
public class SpringBootZuulgatwayproxyApplication {
 
    public static void main(String[] args) {
        SpringApplication.run(SpringBootZuulgatwayproxyApplication.class, args);
    }
 
    @Bean
    public PreFilter preFilter() {
        return new PreFilter();
    }
    @Bean
    public PostFilter postFilter() {
        return new PostFilter();
    }
    @Bean
    public ErrorFilter errorFilter() {
        return new ErrorFilter();
    }
    @Bean
    public RouteFilter routeFilter() {
        return new RouteFilter();
    }
}

5.3. Zuul 路由配置

打开 application.properties 并添加以下内容
#Zuul routes. Here for /student path, we are routing to localhost:8090 with extra path after that.
zuul.routes.student.url=http://localhost:8090
 
#Ribbon is auto integrated with Zuul and for this exercise we are not using that.
ribbon.eureka.enabled=false
 
#Will start the gateway server @8080
server.port=8080

这里zuul.routes.student.url会将所有流量路由/student到实际的学生服务服务器。这样我们也可以将路由添加到其他服务。
ribbon.eureka.enabled与 Zuul 自动集成。
server.port– 需要覆盖默认端口,因为我们将在本地主机中运行不同微服务的多个实例。

5.4. 添加 Zuul 过滤器

正如我们已经描述了现在,我们将添加一些过滤器,Zuul支持4种类型的过滤器,即prepostroute error。在这里,我们将创建每种类型的过滤器。
要编写过滤器,我们基本上需要执行以下步骤:
  • 需要延长 com.netflix.zuul.ZuulFilter
  • 需要重写filterTypefilterOrdershouldFilterrun方法。这里的filterType方法只能返回四个 String – 中的任何一个pre/post/route/error。根据这个值,过滤器将像一个特定的过滤器一样工作。
  • run 方法是我们的​​过滤器逻辑应该根据我们的要求放置的地方。
  • 此外,我们可以根据需要添加任意数量的任何特定过滤器,这种情况filterOrder将用于确定在执行该类型过滤器的阶段该过滤器的顺序。
预过滤器代码- 我们将添加以下预过滤器。目前过滤器除了println用于测试目的之外什么都不做。但实际上,这些功能足够强大,可以完成前面提到的许多重要方面。
import javax.servlet.http.HttpServletRequest;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
 
public class PreFilter extends ZuulFilter {
 
  @Override
  public String filterType() {
    return "pre";
  }
 
  @Override
  public int filterOrder() {
    return 1;
  }
 
  @Override
  public boolean shouldFilter() {
    return true;
  }
 
  @Override
  public Object run() {
    RequestContext ctx = RequestContext.getCurrentContext();
    HttpServletRequest request = ctx.getRequest();
 
    System.out.println("Request Method : " + request.getMethod() + " Request URL : " + request.getRequestURL().toString());
    return null;
  }
}
后过滤器
import com.netflix.zuul.ZuulFilter;
 
public class PostFilter extends ZuulFilter {
 
  @Override
  public String filterType() {
    return "post";
  }
 
  @Override
  public int filterOrder() {
    return 1;
  }
 
  @Override
  public boolean shouldFilter() {
    return true;
  }
 
  @Override
  public Object run() {
   System.out.println("Inside Response Filter");
 
    return null;
  }
}
路由过滤器
import com.netflix.zuul.ZuulFilter;
 
public class RouteFilter extends ZuulFilter {
 
  @Override
  public String filterType() {
    return "route";
  }
 
  @Override
  public int filterOrder() {
    return 1;
  }
 
  @Override
  public boolean shouldFilter() {
    return true;
  }
 
  @Override
  public Object run() {
   System.out.println("Inside Route Filter");
    return null;
  }
}
错误过滤器
import com.netflix.zuul.ZuulFilter;
 
public class ErrorFilter extends ZuulFilter {
 
  @Override
  public String filterType() {
    return "error";
  }
 
  @Override
  public int filterOrder() {
    return 1;
  }
 
  @Override
  public boolean shouldFilter() {
    return true;
  }
 
  @Override
  public Object run() {
   System.out.println("Inside Route Filter");
 
    return null;
  }
}

5.5. 注册zuul过滤器

创建要自动注册和启用的这些过滤器的 bean 定义。
@Bean
public PreFilter preFilter() {
    return new PreFilter();
}
@Bean
public PostFilter postFilter() {
    return new PostFilter();
}
@Bean
public ErrorFilter errorFilter() {
    return new ErrorFilter();
}
@Bean
public RouteFilter routeFilter() {
    return new RouteFilter();
}

6. Netflix zuul 示例演示

所以我们启用了 Zuul,添加了所需的配置并开发了过滤器。所以新的我们可以做基本的测试来了解整个事情。
使用命令进行 maven 构建,mvn clean install并通过运行命令将此项目作为 Spring Boot 应用程序启动java -jar target\spring-boot-zuulgatwayproxy-0.0.1-SNAPSHOT.jar。现在一旦服务器启动,转到浏览器并通过访问学生服务来测试端点是否正常工作,但它的名称是/student
http://localhost:8080/student/getStudentDetails/Sajal
代理服务输出
http://localhost:8080/student/echoStudentName/Sajal代理服务输出

7. 总结

这就是Netflix zuul 过滤器示例的全部内容。我会建议你自己做的时候,添加一些更多的底层服务并通过代理路由请求,应用不同类型的过滤器并在过滤器中添加真正的业务逻辑。

项目源码下载:(访问密码:9987)
spring-cloud-apigateway_zuul.zip

评论区域

评论功能已关闭. 提示:评论功能虽已关闭,关闭之前的评论仍然会展示。