统一网关Gateway

1、为什么需要网关

网关功能:

  1. 身份认证和权限校验
  2. 服务路由、负载均衡
  3. 请求限流

2、网关的技术实现

在SpringCloud中网关的实现包括两种:

  1. gateway
  2. zuul

Zuul是基于Servlet的实现,属于阻塞式编程。而SpringCloudGateway则是基于Spring5中提供的WebFlux,属于响应式编程的实现,具备更好的性能。

总结:

网关的作用:
① 对用户请求做身份认证、权限校验
② 将用户请求路由到微服务,并实现负载均衡
③ 对用户请求做限流

3、搭建网关服务

1、创建新的module,引入SpringCloudGateway的依赖和nacos的服务发现依赖

<!--网关依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!--nacos服务发现依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

2、编写路由配置及nacos地址

server:
port: 10010 # 网关端口
spring:
application:
name: gateway # 服务名称
cloud:
nacos:
server-addr: localhost:8848 # nacos地址
gateway:
routes: # 网关路由配置
- id: user-service # 路由id,自定义,只要唯一即可
# uri: http://127.0.0.1:8081 # 路由的目标地址 http就是固定地址
uri: lb://userservice # 路由的目标地址 lb就是负载均衡,后面跟服务名称
predicates: # 路由断言,也就是判断请求是否符合路由规则的条件
- Path=/user/** # 这个是按照路径匹配,只要以/user/开头就符合要求

3、图示

总结:

1、网关搭建步骤:
① 创建项目,引入nacos服务发现和gateway依赖
② 配置application.yml,包括服务基本信息、nacos地址、路由
2、路由配置包括:
① 路由id:路由的唯一标示
② 路由目标(uri):路由的目标地址,http代表固定地址,lb代表根据服务名负载均衡
③ 路由断言(predicates):判断路由的规则,
④ 路由过滤器(filters):对请求或响应做处理

4、路由断言工厂Route Predicate Factory

网关路由可以配置的内容包括:

  1. 路由id:路由唯一标示
  2. uri:路由目的地,支持lb和http两种 predicates:
  3. 路由断言,判断请求是否符合要求,符合则转发到路由目的地 filters:
  4. 路由过滤器,处理请求或响应
  5. 我们在配置文件中写的断言规则只是字符串,这些字符串会被Predicate Factory读取并处理,转变为路由判断的条件
  6. 例如Path=/user/**是按照路径匹配,这个规则是由org.springframework.cloud.gateway.handler.predicate.PathRoutePredicateFactory类来处理的
  7. 像这样的断言工厂在SpringCloudGateway还有十几个

Spring提供了11种基本的Predicate工厂:

总结:

PredicateFactory的作用是什么?
读取用户定义的断言条件,对请求做出判断
Path=/user/**是什么含义?
路径是以/user开头的就认为是符合的

5、路由过滤器 GatewayFilter

GatewayFilter是网关中提供的一种过滤器,可以对进入网关的请求和微服务返回的响应做处理

6、过滤器工厂 GatewayFilterFactory

Spring提供了31种不同的路由过滤器工厂:

案例:给所有进入userservice的请求添加一个请求头

给所有进入userservice的请求添加一个请求头:Truth=itcast is freaking awesome!

实现方式:在gateway中修改application.yml文件,给userservice的路由添加过滤器:

spring:
cloud:
gateway:
routes: # 网关路由配置
- id: user-service
uri: lb://userservice
predicates:
- Path=/user/**
filters: # 过滤器
- AddRequestHeader=Truth, Itcast is freaking awesome! # 添加请求头

7、默认过滤器

如果要对所有的路由都生效,则可以将过滤器工厂写到default下。格式如下:

spring:
application:
name: gateway # 服务名称
cloud:
nacos:
server-addr: localhost:8848 # nacos地址
gateway:
routes: # 网关路由配置
- id: user-service
uri: lb://userservice
predicates:
- Path=/user/**
- id: order-service
uri: lb://orderservice
predicates:
- Path=/order/**
default-filters: # 默认过滤器,会对所有的路由请求都生效
- AddRequestHeader=Truth, Itcast is freaking awesome! # 添加请求头

总结:

过滤器的作用是什么?
对路由的请求或响应做加工处理,比如添加请求头
配置在路由下的过滤器只对当前路由的请求生效
defaultFilters的作用是什么?
对所有路由都生效的过滤器

8、全局过滤器 GlobalFilter

全局过滤器的作用也是处理一切进入网关的请求和微服务响应,与GatewayFilter的作用一样。 区别在于GatewayFilter通过配置定义,处理逻辑是固定的。而GlobalFilter的逻辑需要自己写代码实现。 定义方式是实现GlobalFilter接口。

public interface GlobalFilter {
/**
* 处理当前请求,有必要的话通过{@link GatewayFilterChain}将请求交给下一个过滤器处理
*
* @param exchange 请求上下文,里面可以获取Request、Response等信息
* @param chain 用来把请求委托给下一个过滤器
* @return {@code Mono<Void>} 返回标示当前过滤器业务结束
*/
Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain);
}

案例:定义全局过滤器,拦截并判断用户身份

需求:定义全局过滤器,拦截请求,判断请求的参数是否满足下面条件: 参数中是否有authorization, authorization参数值是否为admin 如果同时满足则放行,否则拦截

步骤1:自定义过滤器

自定义类,实现GlobalFilter接口,添加@Order注解:

@Order(-1)
@Component
public class AuthorizeFilter implements GlobalFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// 1.获取请求参数
MultiValueMap<String, String> params = exchange.getRequest().getQueryParams();
// 2.获取authorization参数
String auth = params.getFirst("authorization");
// 3.校验
if ("admin".equals(auth)) {
// 放行
return chain.filter(exchange);
}
// 4.拦截
// 4.1.禁止访问
exchange.getResponse().setStatusCode(HttpStatus.FORBIDDEN);
// 4.2.结束处理
return exchange.getResponse().setComplete();
}
}

总结:

全局过滤器的作用是什么?
对所有路由都生效的过滤器,并且可以自定义处理逻辑
实现全局过滤器的步骤?
实现GlobalFilter接口
添加@Order注解或实现Ordered接口
编写处理逻辑

9、过滤器执行顺序

请求进入网关会碰到三类过滤器:当前路由的过滤器、DefaultFilter、GlobalFilter

请求路由后,会将当前路由过滤器和DefaultFilter、GlobalFilter,合并到一个过滤器链(集合)中,排序后依次执行每个过滤器

  1. 每一个过滤器都必须指定一个int类型的order值,order值越小,优先级越高,执行顺序越靠前。
  2. GlobalFilter通过实现Ordered接口,或者添加@Order注解来指定order值,由我们自己指定
  3. 路由过滤器和defaultFilter的order由Spring指定,默认是按照声明顺序从1递增。
  4. 当过滤器的order值一样时,会按照 defaultFilter > 路由过滤器 > GlobalFilter的顺序执行。

可以参考下面几个类的源码来查看:

org.springframework.cloud.gateway.route.RouteDefinitionRouteLocator#getFilters()方法
是先加载defaultFilters,然后再加载某个route的filters,然后合并。 org.springframework.cloud.gateway.handler.FilteringWebHandler#handle()方法
会加载全局过滤器,与前面的过滤器合并后根据order排序,组织过滤器链

总结:

路由过滤器、defaultFilter、全局过滤器的执行顺序?
order值越小,优先级越高
当order值一样时,顺序是defaultFilter最先,然后是局部的路由过滤器,最后是全局过滤器

10、跨域问题处理

跨域:域名不一致就是跨域,主要包括:

  域名不同: www.taobao.com 和 www.taobao.org 和 www.jd.com 和 miaosha.jd.com

  域名相同,端口不同:localhost:8080和localhost8081

跨域问题:浏览器禁止请求的发起者与服务端发生跨域ajax请求,请求被浏览器拦截的问题

解决方案:CORS

网关处理跨域采用的同样是CORS方案,并且只需要简单配置即可实现:

spring:
cloud:
gateway:
# 。。。
globalcors: # 全局的跨域处理
add-to-simple-url-handler-mapping: true # 解决options请求被拦截问题
corsConfigurations:
'[/**]':
allowedOrigins: # 允许哪些网站的跨域请求
- "http://localhost:8090"
- "http://www.leyou.com"
allowedMethods: # 允许的跨域ajax的请求方式
- "GET"
- "POST"
- "DELETE"
- "PUT"
- "OPTIONS"
allowedHeaders: "*" # 允许在请求中携带的头信息
allowCredentials: true # 是否允许携带cookie
maxAge: 360000 # 这次跨域检测的有效期

总结:

CORS跨域要配置的参数包括哪几个?
允许哪些域名跨域?
允许哪些请求头?
允许哪些请求方式?
是否允许使用cookie?
有效期是多久?

SpringCloud-05-Gateway的更多相关文章

  1. 【SpringCloud】Gateway 配置全局过滤器获取请求参数和响应值

    [SpringCloud]Gateway 配置全局过滤器获取请求参数和响应值 实现Ordered接口getOrder()方法,数值越小越靠前执行,记得这一点就OK了. 获取请求参数RequestBod ...

  2. SpringCloud之Gateway

    一.为什么选择SpringCloud Gateway而不是Zuul? Gateway和Zuul的职责一样,都承担着请求分发,类似Nginx分发到后端服务器. 1.SpingCloud Gateway ...

  3. 微服务SpringCloud之GateWay路由

    在前面博客学习了网关zuul,今天学下spring官方自带的网关spring cloud gateway.Zuul(1.x) 基于 Servlet,使用阻塞 API,它不支持任何长连接,如 WebSo ...

  4. 微服务SpringCloud之GateWay服务化和过滤器

    Spring Cloud Gateway 提供了一种默认转发的能力,只要将 Spring Cloud Gateway 注册到服务中心,Spring Cloud Gateway 默认就会代理服务中心的所 ...

  5. springcloud中gateway的实际应用

    之前我一直用的是Zuul网关,用过gateway以后感觉比Zuul功能还是强大很多. Spring Cloud Gateway是基于Spring5.0,Spring Boot2.0和Project R ...

  6. springcloud zookeeper+gateway

    搭建springcloud项目的时候以 zookeeper为注册中心  gateway为路由 启动时出现以下报错: ****************************************** ...

  7. SpringCloud实战 | 第四篇:SpringCloud整合Gateway实现API网关

    一. 前言 微服务实战系列是基于开源微服务项目 有来商城youlai-mall 版本升级为背景来开展的,本篇则是讲述API网关使用Gateway替代Zuul,有兴趣的朋友可以进去给个star,非常感谢 ...

  8. springcloud组件gateway断言(Predicate)

    Spring Cloud Gateway是SpringCloud的全新子项目,该项目基于Spring5.x.SpringBoot2.x技术版本进行编写,意在提供简单方便.可扩展的统一API路由管理方式 ...

  9. SpringCloud创建Gateway模块

    1.说明 本文详细介绍Spring Cloud创建Gateway模块的方法, 基于已经创建好的Spring Cloud父工程, 请参考SpringCloud创建项目父工程, 和已经创建好的Eureka ...

  10. 深入理解SpringCloud之Gateway

    虽然在服务网关有了zuul(在这里是zuul1),其本身还是基于servlet实现的,换言之还是同步阻塞方式的实现.就其本身来讲它的最根本弊端也是再此.而非阻塞带来的好处不言而喻,高效利用线程资源进而 ...

随机推荐

  1. java8 Steam流及Optional的使用

    目录 Stream流: 获取流 1. list获取: 2. Map获取 3. 数组获取 流方法分类: 1. forEach(终结方法) 2. count计数(终结方法) 3.filter过滤 4.li ...

  2. 应届生必读:Java真实项目的开发流程和常用工具

    本文出自本人写的书,谢绝转载,更勿抄袭. 本人有多年的Java面试官经验,经常要和一些包装项目经验的求职者打交道.当然平时也兼职做些Java面试辅导工作,最近也陆续帮一些在校生朋友成功找到Java工作 ...

  3. Web Components从技术解析到生态应用个人心得指北

    Web Components浅析 Web Components 是一种使用封装的.可重用的 HTML 标签.样式和行为来创建自定义元素的 Web 技术. Web Components 自己本身不是一个 ...

  4. 《深入理解计算机系统》实验五 —— Perfom Lab

    本次实验是CSAPP的第5个实验,这次实验主要是让我们熟悉如何优化程序,如何写出更具有效率的代码.通过这次实验,我们可以更好的理解计算机的工作原理,在以后编写代码时,具有能结合软硬件思考的能力. @ ...

  5. linux驱动开发中copy_from_user open read write等常用函数总结

    目录 open read write copy_to_user copy_from_user open 函数定义: int open( const char * pathname, int flags ...

  6. freeswitch的gateway配置方案优化

    概述 freeswitch是一款简单好用的VOIP开源软交换平台. 在之前的文章中,我们简单介绍过gateway的三种配置方案,但是实际应用之后发现,方案中的参数设置有缺陷,会导致一些问题. 本文档中 ...

  7. Mycat 实现分库分表及读写分离

    本文为博主原创,未经允许不得转载: Mycat 官网: http://mycat.org.cn/ MyCat 权威指南 文档:http://www.mycat.org.cn/document/myca ...

  8. 在Linux上安装和使用免费版本的PyMol

    技术背景 PyMol是一个类似于VMD的分子可视化工具,也是在PyQt的基础上开发的.但是由于其商业化运营,软件分为了教育版.开源版和商业版三个版本.其中教育版会有水印,商业版要收费,但是官方不提供开 ...

  9. 介绍这个库:C# Blazor中显示Markdown文件

    1 讲目的 前几天上线了一个在线Icon转换工具,为了让大家使用放心,改了点代码,在转换下载Icon图标后立即删除临时文件,并在工具下面贴上了工具的开发步骤和代码,大家看这样改是否合适,见Issue ...

  10. 0xGame 2023【WEEK1】Crypto全解

    What's CBC? 题目信息 from Crypto.Util.number import * from secret import flag,key def bytes_xor(a,b): a, ...