Gateway服务网关

一、初识Gateway服务网关

1.为什么需要网关?

在微服务中,各个模块之间的调用,也可以称其为远程调用!但是,如果是外部(用户)对微服务进行访问时,发的请求能不加处理的直接访问微服务吗?

答案肯定是不能的!!!

例如,不是所有的业务都是对外公开的,如果"放任"任何用户都能对其进行访问,那么这是不安全的!所以,需要一个安全组件------网关!

Gateway网关是我们服务的守门神,所有微服务的统一入口。

2.图解微服务架构

3.Zuul与Gateway对比

在SpringCloud中网关的实现有两种--Zuul和Gateway

Zuul是基于Servlet实现的,属于阻塞式编程。

而SpringCloudGateway则是基于Spring5中提供的WebFlux,属于响应式编程的实现,具有更好的性能!!!

二、Gateway网关的作用

1.权限控制

网关作为微服务入口,需要校验用户是否有请求资格,如果没有则进行拦截。

2.路由和负载均衡

一切请求都必须先经过Gateway。但网关不处理业务,而是根据某种规则,把请求转发到某个微服务,这个过程叫做路由。当然路由的目标服务有多个时,还需要做负载均衡。

3.限流

当请求流量过高时,在网关中按照下流的微服务能够接受的速度来放行请求,避免服务压力过大。

三、Gateway快速入门

我们这里先体验一下Gateway的使用,以Gateway的路由功能为例,大致可以分为四个步骤:

(1)创建一个SpringBoot工程gateway模块,引入网关依赖

(2)编写启动类

(3)编写基础配置和路由规则

(4)启动网关服务进行测试

1.创建SpringBoot工程gateway模块,引入网关依赖

引入依赖:

这里也是需要nacos的注册发现依赖,Gateway本身也是一个服务,也需要注册到nacos或者从nacos上拉取服务!

2.编写启动类

3.编写基本配置和路由规则

创建application.yml文件,配置gateway服务和路由规则

我们将符合Path规则的一切请求,都代理到uri参数指定的地址。

本例中,我们将/user/**开头的请求,代理到lb://userservice,lb是负载均衡,根据服务名拉取服务列表,实现负载均衡。

4.重启服务测试

重启网关,访问localhost:10010/user/1,符合/user/**规则,请求转发到uri:userservice/user/1

网关路由的流程图:

当我们有了网关开始,所有的请求都会经过网关,然后由网关路由到相应的服务中去。

小结 :

网关搭建步骤:

1.创建项目,引入nacos服务发现和gateway依赖

2.配置application.yml,包括服务基本信息、nacos地址、路由

路由配置包括:

  • 路由id:路由的唯一标示
  • 路由目标(uri):路由的目标地址,http代表固定地址,lb代表根据服务名负载均衡
  • 路由断言(predicates):判断路由的规则
  • 路由过滤器(filters):对请求或响应做处理

四、断言工厂(Predicate Factory)

我们在配置文件中写的断言规则只是字符串,这些字符串会被断言工厂读取并解析,转变为路由判断的条件

断言工厂的作用:读取用户定义的断言规则"字符串",对其进行解析,并对收到的请求做出判断!

这里面的Path=/user/**是按照路径匹配,这个规则是由org.springframework.cloud.gateway.handler.predicate.Path**RoutePredicateFactory**类来处理的,像这样的断言工厂在springCloudGateway还有十几个

Spring中提供的断言工厂:

|------------|-------------------|----------------------------------------------------------------------------------------------------------|
| 名称 | 说明 | 示例 |
| After | 是某个时间点后的请求 | -After=2037-01-20T17:42:47.789-07:00America/Denver |
| Before | 是某个时间点之前的请求 | -Before=2031-04-13T15:14:47.433+08:00Asia/Shanghai |
| Between | 是某两个时间点之间的请求 | -Between=2037-01-20T17:42:47.789-07:00America/Denver,2037-01-21T17:42:47.789-07:00America/Denver |
| Cookie | 请求必须包含某些cookie | -Cookie=chocolate,ch.p |
| Header | 请求必须包含某些header | -Header=X=Request-ld,\d+ |
| Host | 请求必须是访问某个host(域名) | -Hoost=.somehost.org.somehost.org,.anotherhost.org |
| Method | 请求方式必须是指定方式 | -Method=GET,POST |
| Path | 请求路径必须符合指定规则 | -Path=/red/{segment},/blue/** |
| Query | 请求参数必须包含指定参数 | -Query=name,Jack或者-Query=name |
| RemoteAddr | 请求者的ip必须是指定范围 | -RemoteAddr=192.168.1.1/24 |

五、过滤器工厂

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

路由过滤器的种类:

Spring提供了31种不同的路由过滤器工厂,以下是几种常见的:

|----------------------|----------------|
| 名称 | 说明 |
| AddRequestHeader | 给当前请求添加一个请求头 |
| RemoveRequestHeader | 移除请求中的一个请求头 |
| AddResponseHeader | 给响应结果中添加一个响应头 |
| RemoveResponseHeader | 从响应结果中移除有一个响应头 |
| RequestRateLimiter | 限制请求的流量 |

请求头过滤器:

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

对于这个需求其实很简单,只要修改gateway服务的application.yml文件,添加路由过滤即可

如下,我们给userservice添加请求头:Truth=THGN

我们想要看看刚刚添加的请求头,可以通过在UserController中使用@RequestHeader注解获取请求头并打印

访问localhost:10010/user/1,观察控制台

默认过滤器:

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

格式如下:

注意:局部过滤器是在routes下的,而default-filters(默认过滤器)是和routes平级的!

小结:

1.过滤器的作用是什么?

(1)对路由的请求或响应做加工处理,比如添加请求头

(2)配置在路由下的过滤器只对当前路由的请求失效

2.default-Filters的作用是什么?

对所有路由都生效的过滤器

六、全局过滤器

对于过滤器,网关提供了31种,但每一种过滤器的作用都是固定的。如果我们希望拦截请求,做自己的业务逻辑则没办法实现。

更直白一个说,就是之前提到的default-Filters,我们只能通过application.yml文件来配置其参数,具体的业务逻辑是Spring实现的,我们无从干涉。

而当我们想要自己编写过滤器的逻辑呢?

显然仅仅default-Filters是不够的,这时候就需要全局过滤器

1.全局过滤器的作用

全局过滤器的作用也是处理一切进入网关的请求和微服务响应,与GatewayFilters的作用一样。

区别在于GatewayFilter通过配置定义,处理逻辑是固定的;而GlobalFilter的逻辑需要自己写代码实现。

如何实现GlobalFilter呢?

仅需一步即可------定义方式是实现GlobalFilter接口

GlobalFilter接口如下所示:

  • exchange:请求上下文,即当请求进入网关开始,一直到结束,整个过程中exchange对象一直都是可见的!
  • chain:用于放行的,将信息交给下一个过滤器来处理。

2.自定义全局过滤器

需求分析:

定义全局过滤器,拦截请求,判断请求的参数是否满足下面条件:

(1)参数中是否有authorization

(2)authorization参数值是否为admin

如果同时满足则放行,否则拦截!

代码实现:

在gateway模块中定义一个过滤器

运行结果:

当我们访问的路径中存在authorization参数,且其值为admin时,可以获取到正确的结果

七、跨域问题

1.什么是跨域问题

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

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

解决方案:CORS

2.解决跨域问题

在gateway服务的application.yml文件中,添加下面的配置:

相关推荐
EMTime43 分钟前
Docker运行OpenWRT
运维·docker·容器
橙淮1 小时前
并发编程(六)
java·jvm
拽着尾巴的鱼儿1 小时前
springboot openfeign 自定义feign 接口重试机制
java·spring boot·后端
白露与泡影1 小时前
2026大厂Java面试题大全!牛客网最新版
java·开发语言
lolo大魔王1 小时前
Linux 文件系统超全面详解(原理、结构、挂载、分区、inode、日志、管理命令)
linux·运维·服务器
EntyIU2 小时前
JVM内存与GC笔记
java·jvm·笔记
XS0301062 小时前
并发编程 六
java·后端
yaoxin5211232 小时前
419. 现代 Java IO 最佳实践 - 写入文本文件
java·windows·python
雪宫街道2 小时前
synchronized 锁的范围:对象锁、类锁与代码块锁
java·jvm·后端·面试
x***r1513 小时前
linux安装 jdk-8u291-linux-x64.tar.gz 详细步骤(解压配置环境变量)
java