SpringCloud系列教程 | 第九篇:服务网关Zuul初探

Springboot: 2.1.6.RELEASE

SpringCloud: Greenwich.SR1

如无特殊说明,本系列教程全采用以上版本

前面的文章我们介绍了,Eureka用于服务的注册于发现,Feign支持服务的调用以及均衡负载,Hystrix处理服务的熔断防止故障扩散,Spring Cloud Config服务集群配置中心,似乎一个微服务框架已经完成了。

我们还是少考虑了一个问题,外部的应用如何来访问内部各种各样的微服务呢?在微服务架构中,后端服务往往不直接开放给调用端,而是通过一个API网关根据请求的url,路由到相应的服务。当添加API网关后,在第三方调用端和服务提供方之间就创建了一面墙,这面墙直接与调用方通信进行权限控制,后将请求均衡分发给后台服务端。

一个简单的微服务架构已经跃然纸面:

在Spring Cloud微服务系统中,一种常见的负载均衡方式是,客户端的请求首先经过负载均衡(zuul、Ngnix、F5),再到达服务网关(zuul集群),然后再到具体的服务,服务统一注册到高可用的服务注册中心集群,服务的所有的配置文件由配置服务管理,配置服务的配置文件放在git仓库,方便开发人员随时改配置。

1. 为什么需要API Gateway?

1.1 简化客户端调用复杂度

在微服务架构模式下后端服务的实例数一般是动态的,对于客户端而言很难发现动态改变的服务实例的访问地址信息。因此在基于微服务的项目中为了简化前端的调用逻辑,通常会引入API Gateway作为轻量级网关,同时API Gateway中也会实现相关的认证逻辑从而简化内部服务之间相互调用的复杂度。

1.2 数据裁剪以及聚合

通常而言不同的客户端对于显示时对于数据的需求是不一致的,比如手机端或者Web端又或者在低延迟的网络环境或者高延迟的网络环境。

因此为了优化客户端的使用体验,API Gateway可以对通用性的响应数据进行裁剪以适应不同客户端的使用需求。同时还可以将多个API调用逻辑进行聚合,从而减少客户端的请求数,优化客户端用户体验

1.3 多渠道支持

当然我们还可以针对不同的渠道和客户端提供不同的API Gateway,对于该模式的使用由另外一个大家熟知的方式叫Backend for front-end, 在Backend for front-end模式当中,我们可以针对不同的客户端分别创建其BFF,进一步了解BFF可以参考这篇文章:Pattern: Backends For Frontends

1.4 遗留系统的微服务化改造

对于系统而言进行微服务改造通常是由于原有的系统存在或多或少的问题,比如技术债务,代码质量,可维护性,可扩展性等等。API Gateway的模式同样适用于这一类遗留系统的改造,通过微服务化的改造逐步实现对原有系统中的问题的修复,从而提升对于原有业务响应力的提升。通过引入抽象层,逐步使用新的实现替换旧的实现。

在Spring Cloud体系中, Spring Cloud Zuul就是提供负载均衡、反向代理、权限认证的一个API gateway。

在开始聊Zuul如何使用之前,先讲一个比较有意思的事情,就是在springcloud组件中,服务网关这个组件,springcloud提供了两种选择,一个是netflix公司开源的Zuul,还有一个是springcloud自己开源的Spring Cloud Gateway,具体这两个组件的恩怨情仇,在后面的Spring Cloud Gateway的文章中我们再细聊:)

2. Spring Cloud Zuul

2.1 简单使用

Spring Cloud Zuul路由是微服务架构的不可或缺的一部分,提供动态路由,监控,弹性,安全等的边缘服务。Zuul是Netflix出品的一个基于JVM路由和服务端的负载均衡器。

下面我们来看一下Zuul最简单的使用方式,创建zuul-simple工程

2.1 pom.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  4. <modelVersion>4.0.0</modelVersion>
  5. <parent>
  6. <groupId>org.springframework.boot</groupId>
  7. <artifactId>spring-boot-starter-parent</artifactId>
  8. <version>2.1.6.RELEASE</version>
  9. <relativePath/> <!-- lookup parent from repository -->
  10. </parent>
  11. <groupId>com.springcloud</groupId>
  12. <artifactId>zuul-simple</artifactId>
  13. <version>0.0.1-SNAPSHOT</version>
  14. <name>zuul-simple</name>
  15. <description>Demo project for Spring Boot</description>
  16. <properties>
  17. <java.version>1.8</java.version>
  18. <spring-cloud.version>Greenwich.SR1</spring-cloud.version>
  19. </properties>
  20. <dependencies>
  21. <dependency>
  22. <groupId>org.springframework.cloud</groupId>
  23. <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
  24. </dependency>
  25. <dependency>
  26. <groupId>org.springframework.boot</groupId>
  27. <artifactId>spring-boot-starter-test</artifactId>
  28. <scope>test</scope>
  29. </dependency>
  30. </dependencies>
  31. <dependencyManagement>
  32. <dependencies>
  33. <dependency>
  34. <groupId>org.springframework.cloud</groupId>
  35. <artifactId>spring-cloud-dependencies</artifactId>
  36. <version>${spring-cloud.version}</version>
  37. <type>pom</type>
  38. <scope>import</scope>
  39. </dependency>
  40. </dependencies>
  41. </dependencyManagement>
  42. <build>
  43. <plugins>
  44. <plugin>
  45. <groupId>org.springframework.boot</groupId>
  46. <artifactId>spring-boot-maven-plugin</artifactId>
  47. </plugin>
  48. </plugins>
  49. </build>
  50. </project>

引入spring-cloud-starter-netflix-zuul包

2.2 配置文件application.yml

  1. server:
  2. port: 8080
  3. spring:
  4. application:
  5. name: spring-cloud-zuul
  6. zuul:
  7. routes:
  8. baidu:
  9. path: /baidu/**
  10. url: https://www.baidu.com/

这里的配置表示,访问/baidu/** 直接重定向到https://www.baidu.com/**

如果直接访问http://localhost:8080/baidu,则会直接跳转到https://www.baidu.com/。

2.3 启动类

  1. package com.springcloud.zuulsimple;
  2. import org.springframework.boot.SpringApplication;
  3. import org.springframework.boot.autoconfigure.SpringBootApplication;
  4. import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
  5. @SpringBootApplication
  6. @EnableZuulProxy
  7. public class ZuulSimpleApplication {
  8. public static void main(String[] args) {
  9. SpringApplication.run(ZuulSimpleApplication.class, args);
  10. }
  11. }

启动类添加@EnableZuulProxy,支持网关路由。

史上最简单的zuul案例就配置完了

2.4 测试

启动项目,在浏览器访问http://localhost:8080/baidu/,我们可以看到页面已经跳转到百度首页。

再尝试访问http://localhost:8080/baidu/aa,我们可以看到页面跳转至:https://www.baidu.com/search/error.html, 因为https://www.baidu.com/aa 这个链接不存在, 所以百度帮我们跳转到的error页面。

至此,Zuul简单使用已经介绍完毕,下面我们来聊一下服务化的方式。

2.2 服务化

通过url映射的方式来实现Zuul的转发有局限性,比如每增加一个服务就需要配置一条内容,另外后端的服务如果是动态来提供,就不能采用这种方案来配置了。实际上在实现微服务架构时,服务名与服务实例地址的关系在eureka server中已经存在了,所以只需要将Zuul注册到eureka server上去发现其他服务,就可以实现对serviceId的映射。

我们结合示例来说明,在上面示例项目基础上来进行改造

2.2.1 添加依赖

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

增加spring-cloud-starter-netflix-eureka-client包,添加对eureka的支持。

2.2.2 配置文件application.yml

  1. server:
  2. port: 8080
  3. spring:
  4. application:
  5. name: spring-cloud-zuul
  6. zuul:
  7. routes:
  8. api-producer:
  9. path: /producer/**
  10. serviceId: spring-cloud-producer
  11. eureka:
  12. client:
  13. service-url:
  14. defaultZone: http://localhost:8761/eureka/

在这里我们增加了对服务的支持,这里的Zuul配置的含义为访问/producer/**,转向到eureka上面serviceId为spring-cloud-producer的服务。

2.2.3 测试

先从上一篇的项目中copy Eureka到本篇的文件夹中,再从第五篇的项目中copy一个producer到本篇的文件夹中。

依次启动eureka,producer和Zuul.

我们打开浏览器访问:http://localhost:8080/producer/hello?name=spring, 可以看到页面正常显示producer的响应:hello spring,producer is ready。说明通过zuul成功调用了producer服务。

这里producer可以启动两个服务,多次刷新http://localhost:8080/producer/hello?name=spring, 可以看到Zuul对服务的调用是负载均衡的。

2.3 网关的默认路由

但是如果后端服务多达十几个的时候,每一个都这样配置也挺麻烦的,spring cloud zuul已经帮我们做了默认配置。默认情况下,Zuul会代理所有注册到Eureka Server的微服务,并且Zuul的路由规则如下:http://ZUUL_HOST:ZUUL_PORT/微服务在Eureka上的serviceId/**会被转发到serviceId对应的微服务。

我们注销掉zuul-simple配置文件中有关路由的配置。

  1. #zuul:
  2. # routes:
  3. # api-producer:
  4. # path: /producer/**
  5. # serviceId: spring-cloud-producer

再次启动Zuul。

我们在浏览器中访问http://localhost:8080/spring-cloud-producer/hello?name=spring,可以看到和上面一样的返回结果,说明Spring cloud zuul默认已经提供了转发功能。

到此zuul的基本使用我们就聊完了。关于zuul高级使用,我们下篇再来介绍。

示例代码-Github

参考:

http://www.ityouknow.com/springcloud/2017/06/01/gateway-service-zuul.html

https://www.fangzhipeng.com/springcloud/2018/08/05/sc-f5-zuul.html

跟我学SpringCloud | 第九篇:服务网关Zuul初的更多相关文章

  1. springcloud(十一):服务网关Zuul高级篇

    时间过的很快,写springcloud(十):服务网关zuul初级篇还在半年前,现在已经是2018年了,我们继续探讨Zuul更高级的使用方式. 上篇文章主要介绍了Zuul网关使用模式,以及自动转发机制 ...

  2. springcloud(十):服务网关zuul初级篇

    前面的文章我们介绍了,Eureka用于服务的注册于发现,Feign支持服务的调用以及均衡负载,Hystrix处理服务的熔断防止故障扩散,Spring Cloud Config服务集群配置中心,似乎一个 ...

  3. springcloud(十):服务网关zuul

    前面的文章我们介绍了,Eureka用于服务的注册于发现,Feign支持服务的调用以及均衡负载,Hystrix处理服务的熔断防止故障扩散,Spring Cloud Config服务集群配置中心,似乎一个 ...

  4. springcloud(十):服务网关zuul(转)

    前面的文章我们介绍了,Eureka用于服务的注册于发现,Feign支持服务的调用以及均衡负载,Hystrix处理服务的熔断防止故障扩散,Spring Cloud Config服务集群配置中心,似乎一个 ...

  5. 「 从0到1学习微服务SpringCloud 」10 服务网关Zuul

    系列文章(更新ing): 「 从0到1学习微服务SpringCloud 」06 统一配置中心Spring Cloud Config 「 从0到1学习微服务SpringCloud 」07 RabbitM ...

  6. 跟我学SpringCloud | 第二篇:注册中心Eureka

    Eureka是Netflix开源的一款提供服务注册和发现的产品,它提供了完整的Service Registry和Service Discovery实现.也是springcloud体系中最重要最核心的组 ...

  7. 跟我学SpringCloud | 终篇:文章汇总(持续更新)

    SpringCloud系列教程 | 终篇:文章汇总(持续更新) 我为什么这些文章?一是巩固自己的知识,二是希望有更加开放和与人分享的心态,三是接受各位大神的批评指教,有任何问题可以联系我: inwsy ...

  8. Spring Cloud(十):服务网关 Zuul(路由)【Finchley 版】

    Spring Cloud(十):服务网关 Zuul(路由)[Finchley 版]  发表于 2018-04-23 |  更新于 2018-05-09 |  通过之前几篇 Spring Cloud 中 ...

  9. Spring Cloud(十一):服务网关 Zuul(过滤器)【Finchley 版】

    Spring Cloud(十一):服务网关 Zuul(过滤器)[Finchley 版]  发表于 2018-04-23 |  更新于 2018-05-07 |  在上篇文章中我们了解了 Spring ...

随机推荐

  1. Android 位置服务——BaiduLocation的使用

    原文:Android 位置服务--BaiduLocation的使用 版权声明:本文为博主原创文章,欢迎转载,转载请在文章显眼处说明文章出处并给出连接. https://blog.csdn.net/To ...

  2. Qt 创建圆角、无边框、有阴影、可拖动的窗口 good

    程序窗口的边框,标题栏等是系统管理的,Qt 不能对其进行定制,为了实现定制的边框.标题栏.关闭按钮等,需要把系统默认的边框.标题栏去掉,然后使用 Widget 来模拟它们.这里介绍使用 QSS + Q ...

  3. WPF编游戏系列 之三 物品清单

    原文:WPF编游戏系列 之三 物品清单        本篇将介绍如何通过C#自动生成游戏界面,主要演示点击"My Shop"后如何显示所有物品清单.其中数据源来自于Access 2 ...

  4. WPF x:Array的使用

    <Window x:Class="XamlTest.Window1"        xmlns="http://schemas.microsoft.com/winf ...

  5. JS 输入框为空的使用

    <!DOCTYPE html><html><head><meta http-equiv="Content-Type" content=&q ...

  6. 读BeautifulSoup官方文档之html树的搜索(2)

    除了find()和find_all(), 这里还提供了许多类似的方法我就细讲了, 参数和用法都差不多, 最后四个是next, previous是以.next/previous_element()来说的 ...

  7. 【C#】wpf添加gif动图支持

    原文:[C#]wpf添加gif动图支持 1.nuget里下载XamlAnimatedGif包,然后安装. 2.添加XamlAnimatedGif包的命名空间:xmlns:gif="https ...

  8. Delphi Android 将Google ZXing 整合(调用Jar文件)

    前篇文章介绍了在delphi App(以下简称App)中可使用intent来调用Google ZXing 条码扫描器(以下简称zx),其各有优缺点,优点是我们不需关注zx本身的细节,只需调用其接口即可 ...

  9. Qt官方对OpenSSL的编译方法的描述,单独下载的Qt library则一般不带SSL(包括QT FAQ)

    https://wiki.qt.io/MSYS2http://wiki.qt.io/Compiling_OpenSSL_with_MinGWhttps://wiki.qt.io/MinGW-64-bi ...

  10. Win10《芒果TV》商店版更新v3.2.6:修复后台任务故障,优化推送频次

    2017湖南卫视大型音乐竞技节目<歌手>,2017年1月21日晚首播第一期,7位歌手惊艳亮嗓,<芒果TV>UWP版迅速更新v3.2.6版,主要是修复后台任务故障,优化推送频次, ...