GateWay网关应用案例(跨域、限流、黑白名单)
Spring Cloud Gateway是基于Spring Boot 2.x,Spring WebFlux和Project Reactor 构建的。属于异步非阻塞架构
Spring Cloud Gateway与Spring Data 和Spring Securit 技术不能同时使用
Spring Cloud Gateway基于Spring Boot和Spring Webflux提供的Netty运行。它在传统的Servlet容器中或用WAR的方式构建时不起作用
网关基本的功能 :鉴权、流量控制、熔断、路径重写、⽇志监控等
GateWay核心概念
路由(route): 网关最基础的部分,也是网关比较基础的工作单元。
路由由一个ID、一个目标 URL(最终路由到的地址)、一系列的断言(匹配条件判断)和Filter过滤器(精细化控制)组成。
如果断言为true,则匹配该路由。断言(predicates):参考了Java8中的断言java.util.function.Predicate
开发人员可以匹配Http 请求中的所有内容(包括请求头、请求参数等)(类似于Nginx中的location匹配一样)
如果断言与请求相匹配则路由。过滤器(filter):⼀个标准的Spring webFilter,使用过滤器,可以在请求之前或者之后执行业务逻辑。
GateWay工作过程
解释:
客户端向Spring Cloud GateWay发出请求,然后在GateWay Handler Mapping中找到与请求相匹配的路由,将其发送到GateWay Web Handler;
Handler再通过指定的过滤器链来将请求发送到我们实际的服务执行业务逻辑,然后返回。
过滤器之间用虚线分开是因为过滤器可能会在发送代理请求之前(pre)或者之后(post)执行业务逻辑。
Filter在“pre”类型过滤器中可以做参数校验、权限校验、流量监控、日志输出、协议转换等;
在“post”类型的过滤器中可以做响应内容、响应头的修改、日志的输出、流量监控等。
GateWay应用
GateWay不需要使用web模块,它引入的是WebFlux(类似于SpringMVC)
<!--GateWay ⽹关--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency>
<!--引⼊webflux-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
application.yml
server:port: 88spring:application:name: payment-gatewaycloud:nacos:discovery:server-addr: 127.0.0.1:8848gateway:routes: # 路由可以有多个##产品服务路由器,拦截/api/product请求,并重写url地址- id: product_route # ⾃定义的路由 ID,保持唯⼀uri: lb://payment-product # ⽬标服务地址 lb表是负载均衡,payment-product 服务名predicates: # 断言- Path=/api/product/**filters: # 过滤器- RewritePath=/api/(?<segment>/?.*), /$\{segment}
GateWay断言详解
Spring Cloud GateWay 帮我们内置了很多 Predicates功能,实现了各种路由匹配规则
时间点后匹配 :
spring:cloud:gateway:routes:- id: after_routeuri: https://example.orgpredicates:- After=2017-01-20T17:42:47.789-07:00[America/Denver]
时间点前匹配 :
spring:cloud:gateway:routes:- id: before_routeuri: https://example.orgpredicates:- Before=2017-01-20T17:42:47.789-07:00[America/Denver]
时间区间匹配 :
spring:cloud:gateway:routes:- id: between_routeuri: https://example.orgpredicates:- Between=2017-01-20T17:42:47.789-07:00[America/Denver], 2017-01-21T17:42:47.789-07:00[America/Denver]
指定Cookie正则匹配指定值 :
spring:cloud:gateway:routes:- id: cookie_routeuri: https://example.orgpredicates:- Cookie=chocolate, ch.p
指定Header正则匹配指定值 :
spring:cloud:gateway:routes:- id: header_routeuri: https://example.orgpredicates:- Header=X-Request-Id, \d+
请求Host匹配指定值 :
spring:cloud:gateway:routes:- id: host_routeuri: https://example.orgpredicates:- Host=**.somehost.org,**.anotherhost.org
请求Method匹配指定请求方式 :
spring:cloud:gateway:routes:- id: method_routeuri: https://example.orgpredicates:- Method=GET,POST
请求路径正则匹配 :
spring:cloud:gateway:routes:- id: path_routeuri: https://example.orgpredicates:- Path=/red/{segment},/blue/{segment}
请求包含某参数 :
spring:cloud:gateway:routes:- id: query_routeuri: https://example.orgpredicates:- Query=green
远程地址匹配 :
spring:cloud:gateway:routes:- id: remoteaddr_routeuri: https://example.orgpredicates:- RemoteAddr=192.168.1.1/24
权重规则匹配:
spring:cloud:gateway:routes:- id: weight_highuri: https://weighthigh.orgpredicates:- Weight=group1, 8- id: weight_lowuri: https://weightlow.orgpredicates:- Weight=group1, 2
该路由会将约80%的流量转发至https://weighthigh.org并将约20%的流量转发至https://weighlow.org/
GateWay过滤器
Header头部过滤器:
spring:cloud:gateway:routes:- id: add_request_parameter_routeuri: https://example.orgfilters:- AddRequestParameter=red, blue
该过滤器将会把X-Request-red:blue
添加到请求头信息中。
Parameter请求参数过滤器:
spring:cloud:gateway:routes:- id: add_request_parameter_routeuri: https://example.orgfilters:- AddRequestParameter=red, blue
该过滤器将会添加red=blue
参数到所有匹配下游请求中。
Path路径过滤器:
spring:cloud:gateway:routes:- id: rewritepath_routeuri: https://example.orgpredicates:- Path=/red/**filters:- RewritePath=/red(?<segment>/?.*), $\{segment}
请求路径/red/blue
,将会被修改为/blue
。
重试过滤器:
spring:cloud:gateway:routes:- id: retry_testuri: http://localhost:8080/flakeypredicates:- Host=*.retry.comfilters:- name: Retryargs:retries: 3statuses: BAD_GATEWAYmethods: GET,POSTbackoff:firstBackoff: 10msmaxBackoff: 50msfactor: 2basedOnPreviousValue: false
参数详解:
retries
:重试次数,默认值是3次series
:状态码,符合的某段状态码才会进行重试逻辑,默认值是SERVER_ERROR,值是5,也就是5XX(5开头的状态码),共有5个值:
public enum Series {INFORMATIONAL(1),SUCCESSFUL(2),REDIRECTION(3),CLIENT_ERROR(4),SERVER_ERROR(5);
}
methods
:指定哪些方法的请求需要进行重试逻辑,默认值是GET方法,取值如下
public enum HttpMethod {GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE;
}
exceptions
:指定哪些异常需要进行重试逻辑,默认值是java.io.IOException
和TimeoutException
Hystrix过滤器:
内置了 HystrixGatewayFilterFactory ,只需要配置即可实现熔断回退功能
spring:cloud:gateway:routes:- id: hystrix_routeuri: lb://backing-service:8088predicates:- Path=/consumingserviceendpointfilters:- name: Hystrixargs:name: fallbackcmdfallbackUri: forward:/fallback- RewritePath=/consumingserviceendpoint, /backingserviceendpoint
@RequestMapping("/fallback")public Object fallback(){return "降级";}
注意:项目需要引入Hystrix依赖
fallbackUri 是发生熔断时回退的 URI 地址,目前只支持 forward 模式。如果服务被降级,该请求会被转发到该 URI 中
自定义过滤器:
案例:自定义全局过滤器实现IP访问限制(黑白名单)
请求过来时,判断发送请求的客户端的ip,如果在黑名单中,拒绝访问
/**
* 定义全局过滤器,会对所有路由⽣效
*/
@Slf4j
@Component // 让容器扫描到,等同于注册了
public class BlackListFilter implements GlobalFilter, Ordered {// 模拟⿊名单(实际可以去数据库或者redis中查询)private static List<String> blackList = new ArrayList<>();static {blackList.add("0:0:0:0:0:0:0:1"); // 模拟本机地址}/*** 过滤器核⼼⽅法* @param exchange 封装了request和response对象的上下⽂* @param chain ⽹关过滤器链(包含全局过滤器和单路由过滤器)* @return*/@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {// 思路:获取客户端ip,判断是否在⿊名单中,在的话就拒绝访问,不在的话就放⾏// 从上下⽂中取出request和response对象ServerHttpRequest request = exchange.getRequest();ServerHttpResponse response = exchange.getResponse();// 从request对象中获取客户端ipString clientIp = request.getRemoteAddress().getHostString();// 拿着clientIp去⿊名单中查询,存在的话就决绝访问if(blackList.contains(clientIp)) {// 决绝访问,返回response.setStatusCode(HttpStatus.UNAUTHORIZED); // 状态码log.debug("IP:" + clientIp + " 在⿊名单中,将被拒绝访问! ");String data = "Request be denied!";DataBuffer wrap = response.bufferFactory().wrap(data.getBytes());return response.writeWith(Mono.just(wrap));}// 合法请求,放⾏,执⾏后续的过滤器return chain.filter(exchange);}/** * 返回值表示当前过滤器的顺序(优先级),数值越⼩,优先级越⾼*/@Overridepublic int getOrder() {return 0;}
}
解决跨域问题:
可以在网关利用springboot提供的CorsWebFilter,对请求头添加跨域的信息
@Configuration
public class CorsConfiguration {@Beanpublic CorsWebFilter corsWebFilter() {UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();//配置跨域CorsConfiguration config = new CorsConfiguration();//任意请求头config.addAllowedHeader("*");//任意方式config.addAllowedMethod("*");//任意请求来源config.addAllowedOrigin("*");//允许携带cookie跨域config.setAllowCredentials(true);source.registerCorsConfiguration("/**", config);return new CorsWebFilter(source);}
}
也可以在网关直接配置解决跨域问题:
spring:cloud:gateway:globalcors:cors-configurations:'[/**]':allowedOrigins: "https://docs.spring.io"allowedMethods:- GET
允许https://docs.spring.io
路径下所有GET请求跨域
接口限流:
配置限流的过滤器信息:
server:port: 8084
spring:redis:host: 127.0.0.1port: 6379cloud:gateway:routes:- id: useruri: lb://SERVICE-USERpredicates:- Path=/house/**filters:- name: RequestRateLimiterargs:redis-rate-limiter.replenishRate: 10redis-rate-limiter.burstCapacity: 20key-resolver: "#{@ipKeyResolver}"
GateWay限流是基于Redis使用令牌桶算法实现的,所以要引入Redis依赖,以及配置Redis参数信息
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>
参数详解:
- filter 名称必须是 RequestRateLimiter。
- redis-rate-limiter.replenishRate:允许用户每秒处理多少个请求。
- redis-rate-limiter.burstCapacity:令牌桶的容量,允许在 1s 内完成的最大请求数。
- key-resolver:使用 SpEL 按名称引用 bean。
@Configuration
public class AppCoonfig {@Beanpublic KeyResolver ipKeyResolver(){return new KeyResolver() {@Overridepublic Mono<String> resolve(ServerWebExchange exchange) {return Mono.just(exchange.getRequest().getPath().value());}};}
}
GateWay高可用
网关作为非常核心的⼀个部件,如果挂掉,那么所有请求都可能无法路由处理,因此我们需要做GateWay的高可用。
GateWay的高可用很简单: 可以启动多个GateWay实例来实现高可用,在GateWay的上游使用Nginx等负载均衡设备进行负载转发以达到高可用的目的。
启动多个GateWay实例(假如说两个,一个端口9002,⼀个端口9003),剩下的就是使用Nginx等完成负载代理即可。
示例如下:
#配置多个GateWay实例
upstream gateway {server 127.0.0.1:9002;server 127.0.0.1:9003;
}
location / {proxy_pass http://gateway;
}
GateWay网关应用案例(跨域、限流、黑白名单)相关推荐
- SpringCloud工作笔记043---SpringCloud 从整体上解决跨域问题_zuul网关配置实现跨域
JAVA技术交流QQ群:170933152 自己用的: 注意,测试,发现如果网关做了跨域处理,其他地方就不要再做了,比如其他微服务,否则前端 访问的时候会报跨域问题. ---------------- ...
- 如何在nginx下配置网关,实现跨域请求
1.在nginx下配置网关,实现跨域请求 首先进入虚拟机,打开nginx,开机自启命令 docker update nginx --restart=always 进入nginx下的conf目录下 ...
- Gateway网关-网关的cors跨域配置
什么是跨域问题 跨域:域名不一致就是跨域,主要包括: 域名不同: www.taobao.com 和 www.taobao.org 和 www.jd.com 和 miaosha.jd.com 域名相同, ...
- .Netcore 2.0 Ocelot Api网关教程(7)- 限流
本文介绍Ocelot中的限流,限流允许Api网关控制一段时间内特定api的总访问次数. 限流的使用非常简单,只需要添加配置即可. 1.添加限流 修改 configuration.json 配置文件,对 ...
- c++突破网关屏蔽_通过API网关实现微服务管控-限流,熔断和降级
今天准备谈下基于API网关来实现微服务治理管控中的服务限流,熔断和降级方面的内容.在前面谈微服务架构的时候也谈到过类似通过Hystrix,Sentinel来是服务限流熔断.包括也不断地在谈去中心化架构 ...
- 谷粒商城--API三级分类--网关统一配置跨域
什么是跨域,为什么会有跨域问题的出现 一.什么是同源策略? 1.同源策略/SOP(Same origin policy)是一种约定,由Netscape公司1995年引入浏览器,它是浏览器最核心也最基本 ...
- java 接口 白名单,SpringBoot HTTP接口跨域调用及白名单实现
背景 系统之前为一个单页应用提供过Rest接口,部署时这个单页应用与系统不在同一域内,出现跨域无法访问的问题.Spring 从 4.2 版本开始提供了@CrossOrigin注解,让这个问题的解决变得 ...
- SpringCloud+Vue在线教育网站——整合Gateway网关
一.网关基本概念 1.API网关介绍 API 网关出现的原因是微服务架构的出现,不同的微服务一般会有不同的网络地址,而外部客户端可能需要调用多个服务的接口才能完成一个业务需求,如果让客户端直接与各个微 ...
- .NET6之MiniAPI(二十一):限流
限流,可以网络的基础设施进行配置实现,也可以在网关的地方进行限流,但服务本身的限流也不可或缺,因为当多副本时,一个副本故障,流量对于其他副本来说会提高,如果超过其承受请求量的范围,会引起服务连续崩塌, ...
最新文章
- 实际程序调用IndexWriter* writer = NULL
- 全球及中国海洋工程装备行业产值规模价值及投资风险预警报告2021-2027年版
- 温度记录仪开发_TinkerNode NBIoT物联网开发板
- html跳动爱心代码,html+css实现跳动爱心❥(^_-)-Go语言中文社区
- Facebook 有序队列服务设计原理和高性能浅析
- IT学子成长指导类文章链接(十二)
- 为什么 Nginx 比 Apache 更牛叉?
- 基于R实现统计中的检验方法---卡方检验
- Zephyr Team Hiring
- win7 计算机右键没有属性,Win7系统右键点击计算机没有属性选项怎么办
- 计算机中英文打字文章,中英文打字练习文章.docx
- kiriki模拟器Android9,Kirikiroid2模拟器
- C语言中的除法运算符( /)
- forEach 终止循环
- 山东、江苏实施水泥错峰停产,细化到每条生产线
- 多个正方体叠加所得立体图形的表面积
- Linux操作系统之虚拟化
- 6-8 Percolate Up and Down (20 分)【堆结点的插入与删除】
- java生成word样式变形的解决方案(freemarker生成word的样式不对)
- 程序员的三大优点:懒惰、急躁和傲慢