SpringCloud(四)GateWay网关
GateWay网关
概述简介
Gateway是在 Spring生态系统之上构建的AP网关服务,基于 Spring5, Spring Boot2和 Project Reactor等技术。
Gateway旨在提供一种简单而有效的方式来对API进行路由,以及提供一些强大的过滤器功能,例如:熔断、限流、重试等
官网地址:https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.2.RELEASE/reference/html/
SpringCloud Gateway是 Spring Cloud的个全新项目,基于 Spring5.0+ Spring Boot2.0和 Project Reactor等技术开发的网关,它旨在为微服务架构提供一种简单有效的统一的API路由管理方式
SpringCloud Gateway作为 Spring Cloud生态系统中的网关,目标是替代zuul,在 Spring Cloud2.0以上版本中,没有对新版本的zuul2.0以上最新高性能版本进行集成,仍然还是使用的zuul1.×非 Reactor模式的老版本。Spring Cloud Gateway使用的 Webflux中的 reactor-netty响应式编程组件,底层使用了 Netty通讯框架
Spring Cloud Gateway的目标提供统-的路由方式且基于 Filter 链的方式提供了网关基本的功能,例如:安全,监控/指标,和限流
主要特点
作用:反向代理,鉴权,流量控制,熔断,日志监控
- 基于 Spring Framework5, Project Reactor和 Spring Boot2.0进行构建
- 动态路由:能够匹配任何请求属性
- 可以对路由指定 Predicate(断言)和 Filter(过滤器)
- 集成 Hystrix的断路器功能
- 集成 Spring Cloud服务发现功能
- 请求限流功能
- 支持路径重写
三大核心概念
Route(路由)
路由是构建网关的基本模块,它由 ID,目标URI,一系列的断言和过滤器组成,如果断言为 true 则匹配该路由
Predicate(断言)
开发人员可以匹配HTTP请求中的所有内容(例如请求头或请求参数),如果请求与断言相匹配则进行路由
Filter(过滤)
指的是 Spring框架中 Gateway Filter的实例,使用过滤器,可以在请求被路由前或者之后对请求进行修改
web请求,通过一些匹配条件,定位到真正的服务节点。并在这个转发过程的前后,进行一些精细化控制,predicate就是我们的匹配条件,而 Filter ,就可以理解为个无所不能的拦截器有了这两个元素,再加上目标 uri 就可以实现一个具体的路由了
客户端向 Spring Cloud Gateway 发出请求,然后在 Gateway Handler Mapping 中找到与请求相匹配的路由,将其发送到 Gateway Web handler,Handler再通过指定的过滤器链来将请求发送到我们实际的服务执行业务逻辑,然后返回,过滤器之间用虚线分开是因为过滤器可能会在发送代理请求之前("pre")或之后("post")执行业务逻辑
Filter在"pre"类型的过滤器可以做参数校验、权限校验、流量监控、日志输岀、协议转换等,在"post”类型的过滤器中可以做响应内容、响应头的修改,日志的输出,流量监控等有着非常重要的作用
路由配置
- 创建一个新的 module
- 导入 GateWay 依赖
<!-- Gateway -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
<version>2.2.2.RELEASE</version>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</exclusion>
</exclusions>
</dependency>
- 配置路由映射
- 第一种配置方式:在配置文件 yml 中配置
server:
port: 9527
spring:
application:
name: GateWay-Service
cloud:
gateway:
routes:
# 路由的 ID,没有固定规则但要求唯一,建议配合服务名
- id: payment-route1
# 匹配后提供服务的路由地址
uri: http://localhost:8001
# 断言,路径相匹配的进行路由
# 配置服务端的方法路径
predicates:
- Path=/payment/query/**
- id: payment-route2
uri: http://localhost:8001
predicates:
- Path=/payment/discovery/**
# Eureka
eureka:
client:
# 表示是否将自己注册到 EurekaServer
register-with-eureka: true
# 是否从 EurekaServer 抓取已有的注册信息
# 单节点无所谓,集群必须设置为 true 才能配合 ribbon 使用
fetch-registry: true
service-url:
# 单机版
# defaultZone: http://localhost:7001/eureka/
# 集群版
defaultZone: http://eureka7001.com:7001/eureka, http://eureka7002.com:7002/eureka
instance:
hostname: GateWay-Service
- 第二种配置方式:自定义配置文件
@Configuration
public class GateConfig {
/**
* 测试通过网关 跳转到 百度新闻 的页面 http://news.baidu.com/guonei
* 配置了一个 id 为 payment-route3 的路由规则
* 当访问地址为 http://localhost:9527/guonei 会自动转发到 http://news.baidu.com/guonei
* @param routeLocatorBuilder
* @return
*/
@Bean
public RouteLocator routeLocator(RouteLocatorBuilder routeLocatorBuilder){
return routeLocatorBuilder.routes()
.route( "payment-route3",r -> {
return r.path("/guonei")
.uri("http://news.baidu.com/guonei");
})
.build();
}
}
动态路由
默认情况下 Gateway会根据注册中心注册的服务列表,以注册中心上微服名为路径创建动态路由进行转发,从而实现动态路由的功能
配置 yml 配置文件
需要注意的是 uri 的协议为lb,表示启用 Gateway的负载均衡功能
lb://service Name 是spring cloud gateway在微服务中自动为我们创建的负载均衡uri
spring:
application:
name: GateWay-Service
cloud:
gateway:
discovery:
locator:
# 开启从注册中心动态创建路由的功能,利用微服务名进行路由
enabled: true
routes:
# 路由的 ID,没有固定规则但要求唯一,建议配合服务名
- id: payment-route1
# 匹配后提供服务的路由地址
# uri: http://localhost:8001 不能写死
# 匹配 服务端 的路由地址,就是微服务名
uri: lb://provider-payment-service
# 断言,路径相匹配的进行路由
# 配置服务端的方法路径
predicates:
- Path=/payment/lb/**
- id: payment-route2
uri: lb://provider-payment-service
predicates:
- Path=/payment/query/**
开启两个服务端8001和8002
实现了动态路由,可以测试到此时端口可以互相切换
Predicate使用
当开启路由网关时
SpringCloud Gateway 将路由匹配作为 Spring WebFlux HandlerMapping基础架构的部分
SpringCloud Gateway 包括许多内置的 RoutePredicate 工厂。所有这些Predicate都与HTTP请求的不同属性匹配,多个Route Predicate工厂可以进行组合
Spring Cloud Gateway创建 Route对象时,使用 RoutePredicate Factory创建 Predicate对象, Predicate对象可以赋值给Route. Spring Cloud Gateway包含许多内置的 Route predicate factories
所有这些谓词都匹配HTTP请求的不同属性。多种谓词工厂可以组合,并通过逻辑and组合
常用的 Route Predicate
After
路由规则可以匹配一个时间,设置在{arg}之后,当请求的时间在配置时间之后,才会交给 route 去处理
spring:
cloud:
gateway:
routes:
- id: after_route
uri: https://example.org
predicates:
- After=2021-01-20T17:42:47.789-07:00[China/Shanghai]
Before
路由规则可以匹配一个时间,设置在{arg}之前,当请求的时间在配置时间之前,才会交给 route 去处理
spring:
cloud:
gateway:
routes:
- id: after_route
uri: https://example.org
predicates:
- Before=2021-01-20T17:42:47.789-07:00[China/Shanghai]
Between
路由规则可以匹配一个时间,设置在{arg}之间,当请求的时间在配置时间之间,才会交给 route 去处理
spring:
cloud:
gateway:
routes:
- id: between_route
uri: https://example.org
predicates:
- Between=2021-01-20T17:42:47.789-07:00[China/Shanghai], 2021-01-21T17:42:47.789-07:00[China/Shanghai]
Cookie
需要2个参数,一个是cookie名字,另一个是值,可以为正则表达式。它用于匹配请求中,带有该名称的cookie和cookie匹配正则表达式的请求
spring:
cloud:
gateway:
routes:
- id: cookie_route
uri: https://example.org
predicates:
- Cookie=name, zhangsan
# 例
# 请求带有cookie名为name, cookie值为 zhangsan 的请求
# 将都会转发到uri为 https://example.org 的地址上
# curl 请求
# $ curl -H ‘Cookie:name=zhangsan’ localhost:8081
不带cookie访问
带cookie访问
Header
在上面的配置中,当请求的 Header 中有 X-Request-Id的header名,且header值为数字时,请求会被路由到配置的 uri
spring:
cloud:
gateway:
routes:
- id: header_route
uri: https://example.org
predicates:
- Header=X-Request-Id, \d+
# 例
# $ curl -H ‘X-Request-Id:1’ localhost:8081
Host
需要一个参数即hostname,它可以使用 . 或者 * 等去匹配host。这个参数会匹配请求头中的host的值,一致,则请求正确转发
spring:
cloud:
gateway:
routes:
- id: host_route
uri: https://example.org
predicates:
- Host=**.somehost.org,**.anotherhost.org
# 如果请求的主机标头的值为
www.somehost.org
或 beta.somehost.org
或 www.anotherhost.org
# 则此路由匹配
# curl 请求
# curl -H ‘Host:www.adou.com’ localhost:8081
Method
如果请求方法是GET或POST,则此路由匹配
spring:
cloud:
gateway:
routes:
- id: method_route
uri: https://example.org
predicates:
- Method=GET,POST
Path
当请求路径满足 /red/** ,则会经过 route 到达 https://example.org
spring:
cloud:
gateway:
routes:
- id: path_route
uri: https://example.org
predicates:
- Path=/red/**
Query
也可以只填一个参数,填一个参数时,则只匹配参数名,当请求中请求参数包含 green,则会经过 route 到达 https://example.org
spring:
cloud:
gateway:
routes:
- id: query_route
uri: https://example.org
predicates:
- Query=green
- Query=color, green
# 配置了请求中含有参数color,并且color的值匹配green.,则请求命中路由
# curl 请求
# $ curl localhost:8081?color=green
RemoterAddr
请求远程地址,则会经过 route
spring:
cloud:
gateway:
routes:
- id: remoteaddr_route
uri: https://example.org
predicates:
- RemoteAddr=192.168.1.1/24
# 如果请求的远程地址是 192.168.1.10 ,则此路由匹配
Weight
权重采用两个参数匹配 group 和 weight,当达成条件则会路由转发
spring:
cloud:
gateway:
routes:
- id: weight_high
uri: https://weighthigh.org
predicates:
- Weight=group1, 8
- id: weight_low
uri: https://weightlow.org
predicates:
- Weight=group1, 2
# 这条路线会将大约80%的流量转发到 weighthigh.org
# 将大约20%的流量转发到 weightlow.org
说白了, Predicate就是为了实现一组匹配规则,让请求过来找到对应的 Route进行处理
Filter使用
路由过滤器可用于修改进入的HTTP请求和返回的HTTP响应,路由过滤器只能指定路由进行使用
Spring Cloud Gateway内置了多种路由过滤器,他们都由 GatewayFilter 的工厂类来产生
种类:GateWayFilter,GlobalFilter
自定义过滤器
自定义全局GlobalFilter
主要继承两个接口:GlobalFilter,Ordered
作用:全局日志记录,统一网关鉴权等等
@Component
@Slf4j
public class LogGateWayFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// 获取请求的参数
String username = exchange.getRequest().getQueryParams().getFirst("username");
if (username == null){
log.info("用户名为空,找不到该用户");
// 设置状态码
exchange.getResponse().setStatusCode(HttpStatus.NOT_FOUND);
return exchange.getResponse().setComplete();
}
// 返回
log.info("进入拦截器");
return chain.filter(exchange);
}
/**
* 加载过滤器的顺序
* @return
*/
@Override
public int getOrder() {
return 0;
}
}
SpringCloud(四)GateWay网关的更多相关文章
- SpringCloud:gateway网关模块启动报错
1.错误信息 org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with na ...
- SpringCloud使用GateWay网关前端请求请求跨域处理
增加配置类 CorsConfig.java import org.springframework.context.annotation.Bean; import org.springframework ...
- Spring Cloud gateway 网关四 动态路由
微服务当前这么火爆的程度,如果不能学会一种微服务框架技术.怎么能升职加薪,增加简历的筹码?spring cloud 和 Dubbo 需要单独学习.说没有时间?没有精力?要学俩个框架?而Spring C ...
- SpringCloud + Consul服务注册中心 + gateway网关
1 启动Consul 2 创建springcloud-consul项目及三个子模块 2.1 数据模块consul-producer 2.2 数据消费模块consul-consumer 2.3 ga ...
- 实战四:Gateway网关作全局路由转发
Gateway网关的作用主要是两个:路由转发,请求过滤.此篇讲的是路由转发,下篇介绍请求过滤. 一,创建网关module,添加依赖 1,new -> module -> maven 或直接 ...
- Spring Cloud实战 | 第十一篇:Spring Cloud Gateway 网关实现对RESTful接口权限控制和按钮权限控制
一. 前言 hi,大家好,这应该是农历年前的关于开源项目 的最后一篇文章了. 有来商城 是基于 Spring Cloud OAuth2 + Spring Cloud Gateway + JWT实现的统 ...
- JHipster生成微服务架构的应用栈(四)- 网关微服务示例
本系列文章演示如何用JHipster生成一个微服务架构风格的应用栈. 环境需求:安装好JHipster开发环境的CentOS 7.4(参考这里) 应用栈名称:appstack 认证微服务: uaa 业 ...
- 微服务SpringCloud之GateWay路由
在前面博客学习了网关zuul,今天学下spring官方自带的网关spring cloud gateway.Zuul(1.x) 基于 Servlet,使用阻塞 API,它不支持任何长连接,如 WebSo ...
- Spring Cloud gateway 网关服务二 断言、过滤器
微服务当前这么火爆的程度,如果不能学会一种微服务框架技术.怎么能升职加薪,增加简历的筹码?spring cloud 和 Dubbo 需要单独学习.说没有时间?没有精力?要学俩个框架?而Spring C ...
随机推荐
- 第39天学习打卡(UDP多线程在线咨询 URL)
UDP多线程在线咨询 package com.kuang.chat; import java.io.BufferedReader; import java.io.InputStreamReade ...
- Codeblocks支持语法着色
- vue 递归调用组件出错
报错信息: Avoid mutating an injected value directly since the changes will be overwritten whenever the p ...
- ios打包的IDP证书的创建方法
在我们打包ios应用的时候,需要一个IDP证书. 那么我们如何生成这个IDP证书呢?网上介绍的方法都是需要使用mac电脑,然后用mac电脑的钥匙串访问的功能先生成csr文件,然后去苹果开发者生成,然而 ...
- 只需2分钟!PC端的报表即可转换成手机报表
转: 只需2分钟!PC端的报表即可转换成手机报表 手机制作报表,这个大家不知有没有尝试过,虽然我们平时都用电脑做,但是电脑要是不在身边了,手机就可以用来应应急.但其实小编并没有在手机上制作报表的实践经 ...
- 【白话科普】CDN & 游戏加速器,两者是一个原理吗?
说起加速,大家可能就会联想到"游戏加速"之类的场景,而说到现在流行的云服务加速,则离不开 CDN 这个词.那么 CDN 和游戏加速器是同一种东西么?从效果上看两者都是为了" ...
- 解决:layUI数据表格+简单查询
解决:layUI数据表格+简单查询 最近在用layui写项目,在做到用户查询时,发现在layui框架里只有数据表格,不能增加查询.于是自己摸索了一下,写个笔记记录一下. 我想要的效果: 1.定义查询栏 ...
- css整理之-----------技巧、黑魔法
css 看起来比较简单,但是要想做的好也不是那么容易,我们在平时开发中,主要用css 来美化我们的html结构,所有我觉得css 还是挺重要的,这里记录整理一些关于css 的技巧以及容易忘记的知识点. ...
- 部署Angular应用到Github pages
https://jeneser.github.io/blog/2017/08/08/angular-deploying-app-github-pages/ Published: August 08, ...
- hexo+github 博客绑定域名
关于博客的搭建分为以下几步: 申请域名可以在万维网上申请一个自己的独特域名,本博客的域名即为zhengwei.xyz. 域名解析域名申请成功后继续在万维网上进行操作,进入管理自己的域名界面,在要解析的 ...