[菜鸟SpringCloud实战入门]第九章:服务网关Zuul体验
前言
欢迎来到菜鸟SpringCloud实战入门系列(SpringCloudForNoob),该系列通过层层递进的实战视角,来一步步学习和理解SpringCloud。
本系列适合有一定Java以及SpringBoot基础的同学阅读。
每篇文章末尾都附有本文对应的Github源代码,方便同学调试。
Github仓库地址:
github.com/qqxx6661/sp…
菜鸟SpringCloud实战入门系列
你可以通过以下两种途径查看菜鸟SpringCloud实战入门系列:
- 关注我的公众号:Rude3Knife 点击公众号下方:技术推文——SpringCloud
- 菜鸟SpringCloud实战入门专栏导航页(CSDN)
前文回顾:
- [菜鸟SpringCloud实战入门]第一章:构建多模块的Maven项目+创建注册中心Eureka子模块
- [菜鸟SpringCloud实战入门]第二章:创建服务提供者并在Eureka进行注册
- [菜鸟SpringCloud实战入门]第三章:将Eureka改造为高可用集群
- [菜鸟SpringCloud实战入门]第四章:远程调用服务实战
- [菜鸟SpringCloud实战入门]第五章:熔断器Hystrix的使用 + 可视化监控Hystrix Dashboard和Turbine
- [菜鸟SpringCloud实战入门]第六章:配置中心Spring Cloud Config初体验
- [菜鸟SpringCloud实战入门]第七章:配置中心客户端主动刷新机制 + 配置中心服务化和高可用改造
- [菜鸟SpringCloud实战入门]第八章:通过消息总线Spring Cloud Bus实现配置文件刷新(使用Kafka)
- ...更多文章请查看上方:菜鸟SpringCloud入门实战专栏导航页
实战版本
- SpringBoot:2.0.3.RELEASE
- SpringCloud:Finchley.RELEASE
-----正文开始-----
[菜鸟SpringCloud实战入门]第九章:服务网关Zuul体验
服务网关 Zuul
Zuul介绍
外部的应用如何来访问内部各种各样的微服务呢?在微服务架构中,后端服务往往不直接开放给调用端,而是通过一个API网关根据请求的url,路由到相应的服务。当添加API网关后,在第三方调用端和服务提供方之间就创建了一面墙,这面墙直接与调用方通信进行权限控制,后将请求均衡分发给后台服务端。
这个API网关便是Spring Cloud Zuul
Zuul提供动态路由,监控,弹性,安全等的边缘服务。Zuul是Netflix出品的一个基于JVM路由和服务端的负载均衡器。
Zuul与Ribbon以及Eureka配合:
Zuul、Ribbon以及Eureka结合可以实现智能路由和负载均衡的功能;网关将所有服务的API接口统一聚合,统一对外暴露。外界调用API接口时,不需要知道微服务系统中各服务相互调用的复杂性,保护了内部微服务单元的API接口;网关可以做用户身份认证和权限认证,防止非法请求操作API接口;网关可以实现监控功能,实时日志输出,对请求进行记录;网关可以实现流量监控,在高流量的情况下,对服务降级;API接口从内部服务分离出来,方便做测试。
Zuul通过Servlet来实现,通过自定义的ZuulServlet来对请求进行控制。核心是一系列过滤器,可以在Http请求的发起和响应返回期间执行一系列过滤器。Zuul采取了动态读取、编译和运行这些过滤器。过滤器之间不能直接通信,而是通过RequestContext对象来共享数据,每个请求都会创建一个RequestContext对象。
Zuul生命周期如下图。
Zuul大部分功能都是通过过滤器来实现的,这些过滤器类型对应于请求的典型生命周期。
- PRE: 这种过滤器在请求被路由之前调用。我们可利用这种过滤器实现身份验证、在集群中选择请求的微服务、记录调试信息等。
- ROUTING:这种过滤器将请求路由到微服务。这种过滤器用于构建发送给微服务的请求,并使用Apache HttpClient或Netfilx Ribbon请求微服务。
- POST:这种过滤器在路由到微服务以后执行。这种过滤器可用来为响应添加标准的HTTP Header、收集统计信息和指标、将响应从微服务发送给客户端等。
- ERROR:在其他阶段发生错误时执行该过滤器。 除了默认的过滤器类型,Zuul还允许我们创建自定义的过滤器类型。例如,我们可以定制一种STATIC类型的过滤器,直接在Zuul中生成响应,而不将请求转发到后端的微服务。
Zuul中默认实现的Filter:
图片来自:
www.ityouknow.com/springcloud…
在yml中可以禁用指定的Filter:
zuul:FormBodyWrapperFilter:pre:disable: true
复制代码
新建Zuul子模块
本章需要用到之前章节的的模块:
- eureka(eureka):第一章
- eureka-hi(服务提供者):第二章
我们新建子模块(新建模块如有疑惑请看教程第一章),名为zuul
修改pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><artifactId>zuul</artifactId><version>0.0.1-SNAPSHOT</version><name>zuul</name><packaging>jar</packaging><description>Demo project for Spring Boot</description><!--父工程的依赖--><parent><groupId>com.pricemonitor</groupId><artifactId>springcloud</artifactId><version>0.0.1-SNAPSHOT</version></parent><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-zuul</artifactId></dependency></dependencies></project>
复制代码
在主类中加上@EnableZuulProxy:
@SpringBootApplication
@EnableZuulProxy
public class ZuulApplication {public static void main(String[] args) {SpringApplication.run(ZuulApplication.class, args);}}
复制代码
修改yml文件:
- 设置端口为8773
- 在eureka注册
- 设置个producer路由,把/producer/映射到service-hi的服务
spring:application:name: gateway-service-zuul
server:port: 8773
eureka:client:serviceUrl:defaultZone: http://localhost:8761/eureka/
zuul:routes:hello:path: /producer/**serviceId: service-hi
复制代码
单机zuul运行
先后运行eureka,eureka-hi和zuul
使用官网来访问8763上eureka-hi提供的服务:
http://localhost:8773/producer/hi/rude3knife
得到:
说明网关正确转发了请求
zuul服务集群模拟
为了更好的模拟服务集群,我们再新开一个eureka-hi,端口号为8764,只需要修改yml的配置文件,然后重新运行即可。
你会看到来自8763和8764随机提供的服务:
zuul默认路由规则
Zuul其实已经代理所有注册到Eureka Server的微服务,并且Zuul的路由规则如下:http://ZUUL_HOST:ZUUL_PORT/
微服务在Eureka上的serviceId/**会被转发到serviceId对应的微服务。
我们试验一下, http://localhost:8773/service-hi/hi/rude3knife :
zuul自定义filter
最上面的简介中我们提到,Zuul中有默认实现的Filter,当然也可以实现自己的自定义Filter,用来完成一些鉴权、流量转发、请求统计等工作。我们来实现一个自定义filter。
我们假设有这样一个场景,因为服务网关应对的是外部的所有请求,为了避免产生安全隐患,我们需要对请求做一定的限制,比如请求中含有Token便让请求继续往下走,如果请求不带Token就直接返回并给出提示。
新建TokenFilter类:
package com.pricemonitor.zuul;import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import javax.servlet.http.HttpServletRequest;public class TokenFilter extends ZuulFilter {private final Logger logger = LoggerFactory.getLogger(TokenFilter.class);@Overridepublic String filterType() {// 可以在请求被路由之前调用return "pre";}@Overridepublic int filterOrder() {// filter执行顺序,通过数字指定 ,优先级为0,数字越大,优先级越低return 0;}@Overridepublic boolean shouldFilter() {// 是否执行该过滤器,此处为true,说明需要过滤return true;}@Overridepublic Object run() {RequestContext ctx = RequestContext.getCurrentContext();HttpServletRequest request = ctx.getRequest();logger.info("--->>> TokenFilter {},{}", request.getMethod(), request.getRequestURL().toString());String token = request.getParameter("token");if (StringUtils.isNotBlank(token)) {ctx.setSendZuulResponse(true); //对请求进行路由ctx.setResponseStatusCode(200);ctx.set("isSuccess", true);return null;} else {ctx.setSendZuulResponse(false); //不对其进行路由ctx.setResponseStatusCode(400);ctx.setResponseBody("token is empty");ctx.set("isSuccess", false);return null;}}
}
复制代码
随后,在启动类注入这个bean
@SpringBootApplication
@EnableZuulProxy
public class ZuulApplication {public static void main(String[] args) {SpringApplication.run(ZuulApplication.class, args);}@Beanpublic TokenFilter tokenFilter() {return new TokenFilter();}
}
复制代码
运行eureka注册中心,eureka-hi服务提供者,zuul网关三个子模块。
不带token访问:
http://localhost:8773/producer/hi/rude3knife
带着token访问:
http://localhost:8773/producer/hi/rude3knife?token=dsa
通过上面这例子我们可以看出,我们可以使用“PRE”类型的Filter做很多的验证工作,在实际使用中我们可以结合shiro、oauth2.0等技术去做鉴权、验证。
网关路由熔断
之前我们学过hystrix的熔断,主要针对的是内部服务互相调用的熔断,而zuul的熔断则主要服务于外部接口调用。
注意:Zuul 目前只支持服务级别的熔断,不支持具体到某个URL进行熔断。
实现:主要是通过继承FallbackProvider(之前继承的是ZuulFallbackProvider:默认有两个方法,一个用来指明熔断拦截哪个服务,一个定制返回内容。)
网关路由重试
可以配合Spring Retry,来对暂时不可用的服务进行重试。
注意: 开启重试在某些情况下是有问题的,比如当压力过大,一个实例停止响应时,路由将流量转到另一个实例,很有可能导致最终所有的实例全被压垮。说到底,断路器的其中一个作用就是防止故障或者压力扩散。用了retry,断路器就只有在该服务的所有实例都无法运作的情况下才能起作用。这种时候,断路器的形式更像是提供一种友好的错误信息,或者假装服务正常运行的假象给使用者。
不用retry,仅使用负载均衡和熔断,就必须考虑到是否能够接受单个服务实例关闭和eureka刷新服务列表之间带来的短时间的熔断。如果可以接受,就无需使用retry。
本章代码
github.com/qqxx6661/sp…
参考
www.ityouknow.com/springcloud…
www.ityouknow.com/springcloud…
www.cnblogs.com/cralor/p/92…
-----正文结束-----
菜鸟SpringCloud实战入门专栏全导航:通过以下两种途径查看
- 关注我的公众号:Rude3Knife 点击公众号下方:技术推文——SpringCloud
- 菜鸟SpringCloud实战专栏(CSDN)
关注我
我是蛮三刀把刀,后端开发。主要关注后端开发,数据安全,爬虫等方向。微信:yangzd1102
Github:@qqxx6661
个人博客:
- CSDN:@qqxx6661
- 知乎:@Zhendong
- 简书:@蛮三刀把刀
- 掘金:@蛮三刀把刀
原创博客主要内容
- Java知识点复习全手册
- Leetcode算法题解析
- 剑指offer算法题解析
- SpringCloud菜鸟入门实战系列
- SpringBoot菜鸟入门实战系列
- Python爬虫相关技术文章
- 后端开发相关技术文章
个人公众号:Rude3Knife
如果文章对你有帮助,不妨收藏起来并转发给您的朋友们~
[菜鸟SpringCloud实战入门]第九章:服务网关Zuul体验相关推荐
- [菜鸟SpringCloud实战入门]第七章:配置中心客户端主动刷新机制 + 配置中心服务化和高可用改造...
前言 欢迎来到菜鸟SpringCloud实战入门系列(SpringCloudForNoob),该系列通过层层递进的实战视角,来一步步学习和理解SpringCloud. 本系列适合有一定Java以及Sp ...
- [菜鸟SpringCloud实战入门]第五章:熔断器Hystrix的使用 + 可视化监控Hystrix Dashboard和Turbine
前言 欢迎来到菜鸟SpringCloud实战入门系列(SpringCloudForNoob),该系列通过层层递进的实战视角,来一步步学习和理解SpringCloud. 本系列适合有一定Java以及Sp ...
- Spring Cloud微服务网关Zuul过滤链和整合OAuth2+JWT入门实战
一.Spring Cloud Zuul 过滤链 1.1 工作原理 Zuul的核心逻辑是由一系列的Filter来实现的,他们能够在进行HTTP请求或者相应的时候执行相关操作.Zuul Filter的主要 ...
- SpringCloud 服务网关 Zuul 自定义路由和排除路由配置
前言 首先需要说明的是该文是 [带你入门SpringCloud 之 服务网关 Zuul ]的拓展篇,如果还未阅读 [带你入门SpringCloud 之 服务网关 Zuul ]请先阅读完毕后在阅读该文. ...
- SpringCloud实战(五)-路由网关(zuul)
本文是SpringCloud实战(五)-路由网关(zuul),若要关注前文,请点击传送门: SpringCloud实战(四)-断路器(Hystrix) 前文我们介绍了Hystrix断路器.在平常工作中 ...
- SpringCloud实战5-Feign声明式服务调用
SpringCloud实战5-Feign声明式服务调用 在前面的文章中可以发现当我们通过RestTemplate调用其它服务的API时,所需要的参数须在请求的URL中进行拼接,如果参数少的话或许我们还 ...
- 《深入理解 Spring Cloud 与微服务构建》第十一章 服务网关
<深入理解 Spring Cloud 与微服务构建>第十一章 服务网关 文章目录 <深入理解 Spring Cloud 与微服务构建>第十一章 服务网关 一.服务网关简介 二. ...
- R语言实战笔记--第九章 方差分析
R语言实战笔记–第九章 方差分析 标签(空格分隔): R语言 方差分析 术语 组间因子,组内因子,水平:组间因子和组同因子的区别是,组间因子对所有测试对象进行分组,而组内因子则把所有测试对象归为同一组 ...
- 史上最简单的SpringCloud教程 | 第五篇: 路由网关(zuul)
转:https://blog.csdn.net/forezp/article/details/69939114 最新版本: 史上最简单的SpringCloud教程 | 第五篇: 路由网关(zuul)( ...
最新文章
- 马斯克放话:6个月内公测卫星互联网!颠覆5G的将不是6G
- JAVA JDK+Eclipse IDE for Java Developers下载
- 博士申请 | 荷兰代尔夫特理工大学陶倩教授招收医学人工智能全奖博士生
- 使用C# lock同时访问共享数据
- 配对交易方法_COVID下的自适应配对交易,一种强化学习方法
- Flutter Exception降到万分之几的秘密 1
- And(CF-1013B)
- Rust 1.34.1 稳定版发布,Bug 修复
- 转!面向对象设计原则
- weblogic8.1在myeclipse中启动正常,在单独的weblogic中无法正常启动的解决方案.
- CentOS6.X安装10G需要额外安装的软件包
- Docker搭建酷q机器人
- TIT 计算机图形学 实验一 十二面体线框模型
- 0x01 前情提要随着疫情反复,今天我在家办公。我需要登一台服务器上配置,但是那个地址只能通过深信服vpn连接,在家办公一天就带了台kali系统的笔记本回来,没带windows的。 kali上
- deepin系统安装nginx
- Jquery判断动态表格中行数据是否重复
- 骞云数据库DBaaS解决方案深度解析
- 翻翻git之---不靠画全靠“演”,好看的自定义TextView translucent-android
- 微信小程序关注公众号模板显示隐藏问题
- 人脸识别之人脸验证(二)--DeepID
热门文章
- 自动驾驶公司 | 纵目科技完成D轮1.9亿美元融资
- 机器学习实战(五)支持向量机SVM(Support Vector Machine)
- webpack4升级指南
- TypeScript + Gulp + 混淆 + 打包
- 查看数据库表空间.md
- 【二十】Jmeter:插件二次开发—— JMeter 源码导入 eclipse
- windows smb更改端口_SMB协议(使用说明+过程详解+抓包分析)
- vue切换路由的时候,如何让右侧滚动条滚动到顶部呢?
- 常考程序 —— 笔试篇
- [设计模式-创建型]建造者(Builder)