转自:https://blog.csdn.net/pengjunlee/article/details/87084646

Zuul是什么?
  API Gateway 是随着微服务(Microservice)这个概念一起兴起的一种架构模式,它用于解决微服务过于分散,没有一个统一的出入口来进行流量管理的问题。

  API Gateway可以作为整个系统对外的唯一入口,它是一个介于客户端和服务器之间的中间层,用来处理一些与业务无关的边缘功能,例如:智能路由、登录鉴权、流量监控与限流、网络隔离,等等。

  API Gateway 的一种比较常规的选择就是使用Nginx代理,但是Netflix带来了它自己的解决方案----Zuul。Zuul 是Netflix公司开源的基于JVM的微服务网关,可以和Eureka、Ribbon和Hystrix等组件配合使用,提供动态路由,监控,弹性,安全等边缘服务。它相当于是设备和 Netflix 流应用的 Web 网站后端所有请求的前门,可以适当的对多个 Amazon Auto Scaling Groups 进行路由请求。

Netflix公司主要使用Zuul完成以下功能:

  鉴权

  流量监控

  压力测试

  金丝雀测试(灰度测试/AB测试)

  动态路由

  服务迁移

  限流

  安全防护

  静态响应处理

Zuul的工作原理

  和大部分基于Java的Web应用类似,Zuul也采用了servlet架构,因此Zuul处理每个请求的方式是:针对每个请求使用一个线程来处理。通常情况下,为了提高性能,所有请求会被放到处理队列中,从线程池中选取空闲线程来处理该请求。这样的设计方式,足以应付一般的高并发场景。

  如图所示,Zuul的核心是一系列的filters,并且它还提供了一个框架,可以对过滤器进行动态的加载,编译,运行。Zuul的过滤器之间并不会直接进行通信,而是通过一个RequestContext的静态类进行数据传递。RequestContext用ThreadLocal变量来记录每个Request所需要传递的数据。

  Zuul的过滤器是使用Groovy语言编写而成的,这些过滤器文件被放在Zuul Server上的特定目录下面,Zuul会定期轮询这些目录,修改过的过滤器会动态的加载到Zuul Server中以便于request使用。

  Zuul的标准过滤器有以下四种类型:

  

前置过滤器(pre filters):在请求到达Origin Server之前调用。我们可利用这种过滤器实现身份验证、在集群中选择请求的Origin Server、记录调试信息等。

路由过滤器(routing filters):将用户的请求转发给Origin Server。发送给Origin Server的用户请求在这类过滤器中build,并使用Apache HttpClient或者Netfilx Ribbon发送给Origin Server。

后置过滤器(post filters):在用户请求从Origin Server返回以后执行。这种过滤器可用来为响应添加标准的HTTP Header、收集统计信息和指标、将从Origin Server获取到的响应发送给客户端等。

错误过滤器(error filters):在其他阶段发生错误时执行该过滤器。

一个请求会先按顺序通过所有的前置过滤器,之后在路由过滤器中转发给后端应用,得到响应后又会通过所有的后置过滤器,最后再将响应发送给客户端。在整个流程中如果发生了异常则会跳转到错误过滤器中。

一般来说,如果需要在请求到达后端应用前就进行处理的话,会选择前置过滤器,例如鉴权、请求转发、增加请求参数等行为。在请求完成后需要处理的操作放在后置过滤器中完成,例如统计返回值和调用时间、记录日志、增加跨域头等行为。路由过滤器一般只需要选择 Zuul 中内置的即可,错误过滤器一般只需要一个,这样可以在 Gateway 遇到错误逻辑时直接抛出异常中断流程,并直接统一处理返回结果。

使用Zuul

  接下来我们将沿用上一章《客户端负载均衡(Ribbon)》中的项目,演示如何使用Zuul。

引入Zuul依赖

新建一个maven项目,起名为api-gateway,在其 pom.xml 文件中引入Zuul依赖:

	<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.6.RELEASE</version>
</parent> <properties>
<spring-cloud.version>Finchley.SR2</spring-cloud.version>
</properties> <dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Eureka-Client 依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency> <!-- Zuul 依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
</dependencies> <dependencyManagement>
<dependencies>
<!-- SpringCloud 版本控制依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

修改启动类

新建一个Springboot应用的启动类ApiGatewayApplication,并在上面添加@EnableZuulProxy注解,用来启用Zuul反向代理。

import org.springframework.boot.WebApplicationType;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy; @SpringBootApplication
@EnableDiscoveryClient
@EnableZuulProxy
public class ApiGatewayApplication {
public static void main(String[] args) {
new SpringApplicationBuilder(ApiGatewayApplication.class).web(WebApplicationType.SERVLET).run(args);
}
}

添加配置

application.yml 添加配置如下:

server:
port: 8791 # 服务的名称
spring:
application:
name: api-gateway # 注册中心地址
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/

启动测试

按照以下顺序启动应用进行测试:

==>启动Eureka注册中心,端口号 8761

==>分别通过8771和8772两个端口启动message-service

==>启动api-gateway,端口号 8791

启动完成之后,Eureka注册中心中注册的服务列表如下:

首先,我们在浏览器中输入以下地址: http://localhost:8771/api/v1/msg/get,将会显示以下界面:

同样的,访问地址:http://localhost:8772/api/v1/msg/get,将会显示以下界面:

证明两个message-service服务都能正常访问。

接下来我们通过Zuul网关请求服务,请求地址的格式如下:

<zuul-host>:<zuul-port>/service-name/[service-URI]

# zuul-host zuul网关的主机名称或IP地址,本例中为localhost

# zuul-port zuul网关的端口号,本例中为 8791

# service-name 要请求的服务名称,本例中为 message-service

# service-URI 要请求的服务的uri地址,本例中为 /api/v1/msg/get

本例中,完整的请求地址为:http://localhost:8791/message-service/api/v1/msg/get ,连续请求两次,返回结果如下:

可见,Zuul不仅成功地帮我们路由到了相应的微服务还对请求做了负载均衡。

Zuul集群架构

通常我们都会启动多个Zuul网关节点,并通过Nginx对多个网关进行负载均衡。为了防止Nginx出现单点故障,还需要在Nginx集群之前使用Lvs+KeepAlived进行健康检查以及故障迁移,典型的Zuul高可用集群架构如下图所示。

zuul和nginx的区别

相同点:Zuul和Nginx都可以实现负载均衡、反向代理、过滤器请求、实现网关效果

不同点:Nginx采用C语言编写

    Zuul采用java语言边学

    Zuul负载均衡实现:采用ribbon+eureka实现本地负载俊航。

    Nginx负载均衡实现:采用服务器端实现负载俊航。

    Nginx比Zuul功能会更加强大,因为Nginx整合一些脚本语言(Nginx+Lua)

    Nginx适用于服务器端负载均衡|也可以实现网关

    Zuul适合微服务中实现网关,而且使用的技术是java语言。

最好建议nginx+zuul实现网关

nginx作用实现反向代理

zuul对微服务实现网关拦截

参考文章
https://www.jianshu.com/p/e0434a421c03

https://cloud.spring.io/spring-cloud-netflix/single/spring-cloud-netflix.html#netflix-zuul-starter

【springcloud】API Gateway 的路由和过滤(Zuul--1)的更多相关文章

  1. 白话SpringCloud | 第十章:路由网关(Zuul)进阶:过滤器、异常处理

    前言 简单介绍了关于Zuul的一些简单使用以及一些路由规则的简单说明.而对于一个统一网关而言,需要处理各种各类的请求,对不同的url进行拦截,或者对调用服务的异常进行二次处理等等.今天,我们就来了解下 ...

  2. 微服务SpringCloud之GateWay路由

    在前面博客学习了网关zuul,今天学下spring官方自带的网关spring cloud gateway.Zuul(1.x) 基于 Servlet,使用阻塞 API,它不支持任何长连接,如 WebSo ...

  3. SpringCloud(5)路由网关Spring Cloud Zuul

    一个简单的微服务系统如下图: 1.为什么需要Zuul Zuul很容易实现 负载均衡.智能路由 和 熔断器,可以做身份认证和权限认证,可以实现监控,在高流量状态下,对服务进行降级. 2.路由网关 继续前 ...

  4. 白话SpringCloud | 第九章:路由网关(Zuul)的使用

    前言 介绍完分布式配置中心,结合前面的文章.我们已经有了一个微服务的框架了,可以对外提供api接口服务了.但现在试想一下,在微服务框架中,每个对外服务都是独立部署的,对外的api或者服务地址都不是不尽 ...

  5. SpringCloud学习笔记(八):Zuul路由网关

    概述 是什么? Zuul包含了对请求的路由和过滤两个最主要的功能: 其中路由功能负责将外部请求转发到具体的微服务实例上,是实现外部访问统一入口的基础而过滤器功能则负责对请求的处理过程进行干预,是实现请 ...

  6. SpringCloud实战 | 第四篇:SpringCloud整合Gateway实现API网关

    一. 前言 微服务实战系列是基于开源微服务项目 有来商城youlai-mall 版本升级为背景来开展的,本篇则是讲述API网关使用Gateway替代Zuul,有兴趣的朋友可以进去给个star,非常感谢 ...

  7. 聊聊 API Gateway 和 Netflix Zuul

    最近参与了公司 API Gateway 的搭建工作,技术选型是 Netflix Zuul,主要聊一聊其中的一些心得和体会. 本文主要是介绍使用 Zuul 且在不强制使用其他 Neflix OSS 组件 ...

  8. 再谈API GateWay服务网关

    前面在谈微服务架构的时候,我博客上转过Chris Richardson 微服务系列中对微服务网关的描述: 通常来说,使用 API 网关是更好的解决方式.API 网关是一个服务器,也可以说是进入系统的唯 ...

  9. springboot gateway 动态路由-01

    SpringCloud Gateway 是 Spring Cloud 的一个全新项目,该项目是基于 Spring 5.0,Spring Boot 2.0 和 Project Reactor 等技术开发 ...

随机推荐

  1. java集合(3)-Java8新增的Predicate操作集合

    Java8起为Collection集合新增了一个removeIf(Predicate filter)方法,该方法将批量删除符合filter条件的所有元素.该方法需要一个Predicate(谓词)对象作 ...

  2. Python+Requests+Xpath实现动态参数获取实战

    1.古诗文网直接登录时,用浏览器F12抓取登录接口的入参,我们可以看到框起来的key对应的value是动态参数生成的,需获取到: 2.登录接口入参的值一般是登录接口返回的原数据值,若刷新后接口与对应源 ...

  3. UI自动化学习笔记- PO模型介绍和使用

    一.PO模型 1.PO介绍:page(页面) object(对象) 在自动化中,Selenium 自动化测试中有一个名字经常被提及 PageObject (思想与面向对象的特征相同),通常PO 模型可 ...

  4. PhotoShop CC2015(64位)下载链接和破解教程

    photoshop如今有cc和cs两种版本,之前出了一个cs的破解教程和扣圆形图,有很多朋友说cc比cs好用的多,希望出个cc的下载链接和破解教程,故推出2015pscc版破解教程和下载链接. 百度云 ...

  5. jquery版本更新后无live函数的处理.TypeError: $(...).live is not a function

    jquery live函数语法 jquery版本更新, 发现一个问题: jq自带的live没有了.控制台下会有如下的提示:火狐: TypeError: $(...).live is not a fun ...

  6. 随处可编辑的编辑器之神VIM

    据说这世界上只有三种编辑器:Vim,Emacs 和 其他编辑器,其中 Vim 被称作编辑器之神,Emacs 被称作神的编辑器,当然,其他编辑器永远只能是其他编辑器. 拿一位 网友的话 来说,VIM 的 ...

  7. SpringBoot 默认json解析器详解和字段序列化自定义

    前言 在我们开发项目API接口的时候,一些没有数据的字段会默认返回NULL,数字类型也会是NULL,这个时候前端希望字符串能够统一返回空字符,数字默认返回0,那我们就需要自定义json序列化处理 Sp ...

  8. 在屏幕上搜索图片并返回图片所在位置的坐标的AutoHotkey脚本源代码(类似大漠插件)

    ;~  在屏幕上搜索图片并返回图片所在位置的坐标的AutoHotkey脚本源代码(类似大漠插件) ; https://www.autohotkey.com/boards/viewtopic.php?t ...

  9. Python - 函数实战

    前言 参考的是慕课网提供的实战,自己编码 http://www.imooc.com/wiki/pythonlesson1/function2.html 什么是模块化程序设计 在进行程序设计时将一个大程 ...

  10. Upload-labs 文件上传靶场通关攻略(下)

    Upload-Labs靶场攻略(下) Pass-11 GET型传参,上传目录可设置,考虑00截断,在/upload/后添加1.php%00,即可上传 Pass-12 POST型传参,上传目录可设置,P ...