热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

【SpringCloudGateway微服务网关】【尚学堂】学习笔记

API网关介绍1什么是API网关API网关作用就是把各个服务对外提供的API汇聚起来,让外界看起来是一个统一的接口。同时也可以在网关中提供额外的功能总结ÿ
API 网关介绍

1 什么是API网关

API网关作用就是把各个服务对外提供的API汇聚起来,让外界看起来是一个统一的接口。同时也可以在网关中提供额外的功能
总结:网关就是所有项目的一个统一入口

请求响应流程:
nginx --> 前端项目集群 --> 网关 --> 后端项目集群

2 网关组成

网关 = 路由转发+过滤器(编写额外功能)

2.1 路由转发

接收外界请求,通过网关的路由转发,转发到后端的服务上
如果只有这个一个功能看起来和之前学习的Nginx方向代理服务器很像,外界访问nginx,由nginx做负载均衡,后把请求转发到对应服务器上

2.2 过滤器

网关非常重要的功能就是过滤器
过滤器中默认提供了25个内置功能,还支持额外的自定义功能
对于我们来说比较常用的功能包括网关的容错、限流以及请求及相应的额外处理

3 Spring Cloud中提供的网关解决方案


3.1 Spring Cloud Netflix Zuul

属于Spring Cloud Netflix下一个组件,具有灵活、简单的特点。在早期Spring Cloud中使用的比较多
其版本更新都依赖Netflix Zuul

3.2 Spring Cloud Gateway

由Spring自己推出的网关产品,完全依赖Spring自家产品。符合Spring战略意义,其更新版本等都由Spring自己把控

Spring Cloud Gateway介绍

1 简介

Spring Cloud Gateway是Spring Cloud的二级子项目,提供了微服务网关功能,包含:权限安全、监控、指标等功能

2 名词解释

在学习Gateway时里面有一些名词需要提前了解

2.1 Route

路由,一个Gateway项目可以包含多个路由
一个路由包含ID、URI、Predicate集合、Filter集合
在Route中ID是自定义的,URI就是一个地址,剩下的Predicate和Filter

2.2 Predicate

谓词,谓词是学习Gateway比较重要的一点,简单点理解谓词就是一些附加条件和内容,其实就是路由规则,和简单的校验逻辑

2.3 Filter

所有生效的Filter都是GatewayFilter的实例,在Gateway运行过程中Filter负责在代理服务之前或之后去做一些事情

Spring Cloud Gateway入门案例

新建微服务,首先引入依赖

<dependency><groupId>org.springframework.cloudgroupId><artifactId>spring-cloud-starter-gatewayartifactId>
dependency>

添加配置文件&#xff0c;gateway的配置都是在配置文件中实现的

server:port: 9999
spring:application:name: my-spring-cloud-gatewaycloud: #配置Spring Cloud相关属性gateway: #配置Spring Cloud Gateway相关属性discovery: #配置网关发现机制locator: #配置处理机制enable: true #开启网关自动映射处理逻辑&#xff0c;#只要请求地址符合规则&#xff1a;http://gatewayIP:gatewayPort/微服务名称/微服务请求地址#网关自动映射&#xff0c;把请求转发到http://微服务名称/微服务请求地址#如&#xff1a;有微服务&#xff0c;命名是ribbon-app-service#请求地址是&#xff1a;http://localhost:9999/ribbon-app-service/getArgs?name&#61;admin&age&#61;20#自动转发到&#xff1a;http://ribbon-app-service/getArgs?name&#61;admin&age&#61;20#商业开发中&#xff0c;enable一般不设置&#xff0c;使用默认值false。避免不必要的自动转发规则lower-case-service-id: true #开启服务名称小写转换。Eureka对服务名管理默认全是大写routes: #配置网关中的一个完整路由&#xff0c;包括命名&#xff0c;地址&#xff0c;谓词集合&#xff08;规则&#xff09;&#xff0c;过滤器集合- id: first #路由定义的命名&#xff0c;唯一即可。命名规则符合Java中的变量符合命名规则# lb - 代表loadbalanceuri: lb://ribbon-app-service #当前路由定义对应的微服务转发地址#谓词&#xff0c;命名是有规则的。是GatewayPredicate接口实现的命名前缀&#xff0c;XxxRoutePredicataFactorypredicates: #配置谓词集合- Path&#61;/api/** #定义一个谓词。格式&#xff1a;谓词名字&#61;参数 或者 name:名字 args:参数#过滤器命名&#xff0c;有规则。GatewayFilterFactory接口实现的命名前缀filters: #配置过滤器集合#过滤转发地址前缀&#xff0c;过滤一节#如&#xff1a;请求地址&#xff1a;http://localhost:9999/api/getArgs?name&#61;admin&age&#61;20#对应的谓词&#xff0c;规则是/api&#xff0c;符合#对应的uri是 lb:ribbon-app-service 转换成http://ribbon-app-service且包含负载均衡#转发地址是&#xff1a;http://ribbon-app-service/getArgs?name&#61;admin&age&#61;20#过滤器是 过滤转发地址前缀&#xff0c;过滤一节&#xff0c;即删除/api- StripPrefix&#61;1 #定义一个过滤器。格式&#xff1a;过滤器名字&#61;参数 或者 name:名字 args:参数- id:uri:predicates:- name: Pathargs:- patterns&#61;/api/**,/a/**filters:
eureka:client:service-url:defaultZone: http://localhost:8761/eureka/

谓词&#xff08;规则&#xff09;


# 检查请求头中是否有指定数据&#xff0c;key是my&#xff0c;值是bjsxt&#xff08;正则表达式&#xff09;
routes:- id: firsturi: lb://ribbon-api-servicepredicates:- Path&#61;/api/**,/a/**,/b/**name: Headerargs: #map类型&#xff0c;键值对header: myregexp: bjsxt.* #正则表达式filters:# 校验请求中的参数&#xff0c;key是name&#xff0c;值是一个正则表达式
routes:- id: firsturi: lb://ribbon-api-servicepredicates:- Query&#61;name,admin.* #谓词判断请求参数&#xff0c;值判断请求头传递的参数&#xff0c;请求体参数不判断filters:# 检查请求类型
routes:- id: firsturi: lb://ribbon-api-servicepredicates:- Method&#61;GET,POSTfilters:# 检查客户端ip地址是否符合要求
routes:- id: firsturi: lb://ribbon-api-servicepredicates:- sources&#61;192.168.0.1,192.168.0.2,192.168.0.*filters:# 检查请求中指定的COOKIE值
routes:- id: firsturi: lb://ribbon-api-servicepredicates:- name&#61;COOKIENameregexp&#61;aa*filters:# 检查请求在什么时间范围内
routes:- id: firsturi: lb://ribbon-api-servicepredicates:- Path&#61;/api/**- Between&#61;2020-01-31T18:00:00.000&#43;08:00[Asia/Shanghai],2020-01-31T20:00:00.000&#43;08:00[Asia/Shanghai]filters:# 检查请求头
routes:- id: firsturi: lb://ribbon-api-servicepredicates:- Path&#61;/api/**- pattern&#61;*filters:# 权重实现负载均衡&#xff08;通常不会使用&#xff0c;只有在多版本服务发布的时候偶尔使用&#xff0c;新版本权重2&#xff0c;接受少量的请求&#xff0c;如果没有问题&#xff0c;就可以替换旧版本&#xff09;
routes:- id: firsturi: lb://ribbon-api-service-1predicates:- Path&#61;/api/**- Weight&#61;group,2 #group表示分组名称&#xff0c;分组名称一样&#xff0c;表示同一组filters: SpripPrefix&#61;1- id: twouri: lb://ribbon-api-service-2predicates:- Path&#61;/api/**- Weight&#61;group,8 #按照权重比例分配请求filters: SpripPrefix&#61;1

Filter

Filter作用&#xff1a;在路由转发到代理服务器之前和代理服务器返回结果之后额外做的事情。
Filter执行了&#xff0c;那就说明谓词条件通过了

在Spring Cloud Gateway的路由中Filter分为&#xff1a;
内置Filter&#xff0c;都是GatewayFilter实现类
自定义GlobalFilter


# 添加一个请求头信息
routes:- id: firsturi: lb://ribbon-api-servicepredicates:- Path&#61;/api/**- pattern&#61;*filters:- AddRequestHeader&#61;a,b# 完整写法
routes:- id: firsturi: lb://ribbon-api-servicepredicates:filters:- name: AddRequestHeaderargs:name: newHeadervalue: newValue查看源码&#xff0c;XXXGatewayFilterFactory&#xff0c;这些都是过滤器&#xff0c;对应配置类就可以配置属性参数常用的&#xff1a;
AddRequestHeader
AddResponseHander
DedupeResponseHander
StripPrefix

使用Gateway实现限流

可以利用Gateway中RequestRateLimiter实现限流

1 常见的限流算法


1.1 计数器算法

以QPS每秒查询率为100举例子

从第一个请求开始计时&#xff0c;每个请求让计数器加一&#xff0c;到达到100以后&#xff0c;其他的请求都拒绝
如果1秒内前200毫秒请求数量已经到达了100&#xff0c;后面800毫秒中500次请求都被拒绝了&#xff0c;这种情况称为‘突刺现象’

1.2 漏桶算法

漏桶算法可以解决突刺现象
和生活中漏桶一样&#xff0c;有一个水桶&#xff0c;下面有一个漏眼往出漏水&#xff0c;不管桶里有多少水&#xff0c;漏水的速率都是一样的。但是既然是一个桶&#xff0c;桶里装的谁都是有上限的。当达到了上限新进来的水就装不了&#xff08;主要出现在突然倒进来大量水的情况&#xff09;

1.3 令牌桶算法

令牌桶算法可以说是对漏桶算法的一种改进
在桶中放令牌&#xff0c;请求获取令牌后才能继续执&#xff0c;如果桶中没有令牌&#xff0c;请求可以选择进行等待或者直接拒绝
由于桶中令牌是按照一定速率放置的&#xff0c;所以可以一定程度解决突发访问&#xff0c;如果桶中令牌最多100个&#xff0c;qps最大为100

在这里插入图片描述

2 Gateway中的限流

RequestRateLimiter 基于Redis和lua脚本实现令牌桶算法

2.1 添加依赖


2.2 修改配置


# 完整写法
routes:- id: firsturi: lb://ribbon-api-servicepredicates:filters:- name: RequestRateLimiterargs:keyResolver: &#39;#{&#64;myKeyResolver}&#39; #使用SpringEL表达式&#xff0c;从Spring容器中找对象&#xff0c;并赋值 ‘#{&#64;beanName}’redis-rate-limiter.replenishRate: 1 #每秒产生的令牌数量redis-rate-limiter.burstCapacity: 5 #桶的容量上限

2.3 算法


&#64;Component
public class MyKeyResolver implements KeyResolver{&#64;Overridepublic Mono<String> resolve(ServerWebExchange exchange){String remoteAddr &#61; exchange.getRequest().getRempteAddress().getAddress.getHostAddress();return Mono.just(remoteAddr);}
}

使用Gateway实现服务降级

gateway可以利用Hystrix实现服务降级等功能
当gateway进行路由转发时&#xff0c;如果发现下游服务连接超时允许进行服务降级
实现原理&#xff1a;当连接超时时&#xff0c;使用gateway自己的一个降级接口返回托底数据&#xff0c;保证程序继续运行

配置


# 完整写法
routes:- id: firsturi: lb://ribbon-api-servicepredicates:filters:- name: Hystrixargs:name: fallbackcmd #名字分组fallbackUri: forward:/downgrade #远程服务错误的时候&#xff0c;Gateway工程中的哪一个控制器逻辑&#xff0c;返回结果

Gateway工程中的控制器


&#64;RestController
public class DowngradeController{&#64;RequestMapping(value&#61;"/downgrade",produces&#61;"text/html;charset&#61;UTF-8")public String downgrade(){return "

Gateway返回服务器忙&#xff0c;请稍候重试
";}
}

GlobalFilter

全局过滤器不需要工厂&#xff0c;也不需要配置&#xff0c;直接对所有的路由都生效
可以使用GlobalFilter实现统一的权限验证、日志记录等希望对所有代理的项目都生效的内容都可以配置在全局过滤器中
且在项目中可以配置多个GlobalFilter的实现类&#xff0c;都可以自动执行

&#64;Component
public class MyGlobalFilter implements GlobalFilter{&#64;Overridepublic Mono<Void> filter(ServerWebExchange exchange,GatewayFilterChain chain){// 前置过滤System.out.prinln("全局过滤器执行&#xff0c;当前时刻是&#xff1a;"&#43;new Date());// 执行后续逻辑Mono<Void> result &#61; chain.filter(exchange);return result;}
}

Gateway自定义路由过滤器


&#64;Component
public class RequestPathGatewayFilterFactory extends AbstractGatewayFilterFactory<RequestPathGatewayFilterFactory.Config>{// 当前过滤器需要使用的配置内容class Config{private String name;private String path;// get set 方法}// 过滤逻辑&#64;Overridepublic GatewayFilter apply(Config config){return new GatewayFilter(){&#64;Overridepublic Mono<Void> filter(ServerWebExchange exchange,GatewayFilterChain chain){// 执行后续逻辑Mono<Void> result &#61; chain.filter(exchange);return result;}}}// 如果可以简化配置方案&#xff0c;当前方法返回简化配置参数// RequestPath&#61;nameValue,pathValue&#64;Overridepublic List<String> showtcutFieldOrder(){return Arrays.asList("name","path");}
}


推荐阅读
  • Apache Shiro 身份验证绕过漏洞 (CVE202011989) 详细解析及防范措施
    本文详细解析了Apache Shiro 身份验证绕过漏洞 (CVE202011989) 的原理和影响,并提供了相应的防范措施。Apache Shiro 是一个强大且易用的Java安全框架,常用于执行身份验证、授权、密码和会话管理。在Apache Shiro 1.5.3之前的版本中,与Spring控制器一起使用时,存在特制请求可能导致身份验证绕过的漏洞。本文还介绍了该漏洞的具体细节,并给出了防范该漏洞的建议措施。 ... [详细]
  • SpringBoot整合SpringSecurity+JWT实现单点登录
    SpringBoot整合SpringSecurity+JWT实现单点登录,Go语言社区,Golang程序员人脉社 ... [详细]
  • Spring源码解密之默认标签的解析方式分析
    本文分析了Spring源码解密中默认标签的解析方式。通过对命名空间的判断,区分默认命名空间和自定义命名空间,并采用不同的解析方式。其中,bean标签的解析最为复杂和重要。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • http:my.oschina.netleejun2005blog136820刚看到群里又有同学在说HTTP协议下的Get请求参数长度是有大小限制的,最大不能超过XX ... [详细]
  • 本文介绍了作者在开发过程中遇到的问题,即播放框架内容安全策略设置不起作用的错误。作者通过使用编译时依赖注入的方式解决了这个问题,并分享了解决方案。文章详细描述了问题的出现情况、错误输出内容以及解决方案的具体步骤。如果你也遇到了类似的问题,本文可能对你有一定的参考价值。 ... [详细]
  • 在重复造轮子的情况下用ProxyServlet反向代理来减少工作量
    像不少公司内部不同团队都会自己研发自己工具产品,当各个产品逐渐成熟,到达了一定的发展瓶颈,同时每个产品都有着自己的入口,用户 ... [详细]
  • 自动轮播,反转播放的ViewPagerAdapter的使用方法和效果展示
    本文介绍了如何使用自动轮播、反转播放的ViewPagerAdapter,并展示了其效果。该ViewPagerAdapter支持无限循环、触摸暂停、切换缩放等功能。同时提供了使用GIF.gif的示例和github地址。通过LoopFragmentPagerAdapter类的getActualCount、getActualItem和getActualPagerTitle方法可以实现自定义的循环效果和标题展示。 ... [详细]
  • 预备知识可参考我整理的博客Windows编程之线程:https:www.cnblogs.comZhuSenlinp16662075.htmlWindows编程之线程同步:https ... [详细]
  • 本文介绍了如何在Azure应用服务实例上获取.NetCore 3.0+的支持。作者分享了自己在将代码升级为使用.NET Core 3.0时遇到的问题,并提供了解决方法。文章还介绍了在部署过程中使用Kudu构建的方法,并指出了可能出现的错误。此外,还介绍了开发者应用服务计划和免费产品应用服务计划在不同地区的运行情况。最后,文章指出了当前的.NET SDK不支持目标为.NET Core 3.0的问题,并提供了解决方案。 ... [详细]
  • 如何使用Python从工程图图像中提取底部的方法?
    本文介绍了使用Python从工程图图像中提取底部的方法。首先将输入图片转换为灰度图像,并进行高斯模糊和阈值处理。然后通过填充潜在的轮廓以及使用轮廓逼近和矩形核进行过滤,去除非矩形轮廓。最后通过查找轮廓并使用轮廓近似、宽高比和轮廓区域进行过滤,隔离所需的底部轮廓,并使用Numpy切片提取底部模板部分。 ... [详细]
  • Spring框架《一》简介
    Spring框架《一》1.Spring概述1.1简介1.2Spring模板二、IOC容器和Bean1.IOC和DI简介2.三种通过类型获取bean3.给bean的属性赋值3.1依赖 ... [详细]
  • 如何自行分析定位SAP BSP错误
    The“BSPtag”Imentionedintheblogtitlemeansforexamplethetagchtmlb:configCelleratorbelowwhichi ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 本文介绍了如何使用Express App提供静态文件,同时提到了一些不需要使用的文件,如package.json和/.ssh/known_hosts,并解释了为什么app.get('*')无法捕获所有请求以及为什么app.use(express.static(__dirname))可能会提供不需要的文件。 ... [详细]
author-avatar
瑶瑶bao呗
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有