Gateway服务网关

Gateway服务网关

Spring Cloud Gateway 是 Spring Cloud 的一个全新项目,该项目是基于 Spring 5.0,Spring Boot 2.0 和 Project Reactor 等响应式编程和事件流技术开发的网关,它旨在为微服务架构提供一种简单有效的统一的 API 路由管理方式。

1为什么需要网关

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

网关的核心功能:

  • 请求路由
  • 权限控制
  • 限流

架构图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-C1poxBKB-1693053166324)(C:\Users\19627\AppData\Roaming\Typora\typora-user-images\image-20230825203446233.png)]

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

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

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

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

  • gateway
  • zuul

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

2gateway快速入门

下面,我们就演示下网关的基本路由功能。基本步骤如下:

  1. 创建SpringBoot工程gateway,引入网关依赖
  2. 编写启动类
  3. 编写基础配置和路由规则
  4. 启动网关服务进行测试

2.1创建gateway服务,引入依赖

        <!--网关依赖-->
        <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.2编写启动类

@SpringBootApplication
public class GateApplication {
    public static void main(String[] args) {
        SpringApplication.run(GateApplication.class, args);
    }
}

2.3编写基础配置和路由规则

server:
  port: 10010
spring:
  application:
    name: gateway
  cloud:
    nacos:
      server-addr: localhost:8848 #nacos地址
    gateway:
      routes:
        - id: user-service #路由标识,必须唯一
          uri: lb://userservice
          predicates: #判断请求是否符合规则
            - Path=/user/** #路径断言,判断路径是否以/user开头,如果是则符合
        - id: order-service
          uri: lb://orderservice
          predicates:
            - Path=/order/**

2.4启动

访问localhost:10010/user/1

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zugYf5MW-1693053166327)(C:\Users\19627\AppData\Roaming\Typora\typora-user-images\image-20230826190836701.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UMju0ty5-1693053166328)(C:\Users\19627\AppData\Roaming\Typora\typora-user-images\image-20230826190932259.png)]

总结:

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

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

路由配置包括:

1.路由id:路由的唯一标识

2.路由目标uri:路由的目标路径,http代表固定地址,lb代表根据服务名负载均衡

3.路由断言predicates:判断路由的规则

4.路由过滤器filters:对请求或响应做处理

3路由断言工厂Route Predicate Factory

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

例如Path=/user/**是按照路径匹配,这个规则是由

org.springframework.cloud.gateway.handler.predicate.PathRoutePredicateFactory类来

处理的,像这样的断言工厂在SpringCloudGateway还有十几个:

名称说明示例
After是某个时间点后的请求- After=2037-01-20T17:42:47.789-07:00[America/Denver]
Before是某个时间点之前的请求- Before=2031-04-13T15:14:47.433+08:00[Asia/Shanghai]
Between是某两个时间点之前的请求- Between=2037-01-20T17:42:47.789-07:00[America/Denver], 2037-01-21T17:42:47.789-07:00[America/Denver]
Cookie请求必须包含某些cookie- Cookie=chocolate, ch.p
Header请求必须包含某些header- Header=X-Request-Id, \d+
Host请求必须是访问某个host(域名)- Host=.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
Weight权重处理

我们只需要掌握Path这种路由工程就可以了。

4路由过滤器 GatewayFilter

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ac8lIb8p-1693053166329)(C:\Users\19627\AppData\Roaming\Typora\typora-user-images\image-20230826192508895.png)]

4.1路由过滤器的种类

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

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

4.2请求头过滤器

以AddRequestHeader为例讲解

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

实现方法:

server:
  port: 10010
spring:
  application:
    name: gateway
  cloud:
    nacos:
      server-addr: localhost:8848 #nacos地址
    gateway:
      routes:
        - id: user-service #路由标识,必须唯一
          uri: lb://userservice
          predicates: #判断请求是否符合规则
            - Path=/user/** #路径断言,判断路径是否以/user开头,如果是则符合
          filters:
            - AddRequestHeader=wuhu,qifei #添加请求头
        - id: order-service
          uri: lb://orderservice
          predicates:
            - Path=/order/**

当前过滤器写在userservice路由下,因此仅仅对访问userservice的请求有效。

4.3默认过滤器

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

      default-filters:
        - AddRequestHeader=wuhu,qifei #添加请求头

4.4自定义全局过滤器

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

  • 参数中是否含有authorization
  • authorization参数值是否为admin

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

在gateway中添加一个过滤器的类


@Component
//@Order(0) //顺序值,默认值21亿,值越小,优先级越高,负21亿优先级最高
public class AutherizeFilter implements GlobalFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //获取请求参数
        ServerHttpRequest request = exchange.getRequest();
        //获取参数中的authorization参数
        MultiValueMap<String, String> params = request.getQueryParams();
        //判断参数值是否等于admin
        String auth = params.getFirst("authorization");

        if ("admin".equals(auth)) {
            //相等 放行
            return chain.filter(exchange);
        }

        //不等 拦截
        //设置状态码
        exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);//未登录401
        //拦截请求
        return exchange.getResponse().setComplete();
    }

    @Override
    public int getOrder() {
        return -1;
        //顺序值,默认值21亿,值越小,优先级越高,负21亿优先级最高
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bkwmCRFi-1693053166329)(C:\Users\19627\AppData\Roaming\Typora\typora-user-images\image-20230826195722743.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3W3S89hI-1693053166330)(C:\Users\19627\AppData\Roaming\Typora\typora-user-images\image-20230826195733211.png)]

4.5过滤器执行顺序

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

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8FPvSmIp-1693053166330)(C:\Users\19627\AppData\Roaming\Typora\typora-user-images\image-20230826200143527.png)]

排序规则:

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7SROn6YG-1693053166331)(C:\Users\19627\AppData\Roaming\Typora\typora-user-images\image-20230826200820143.png)]

4.6gateway跨域问题处理

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

  • 域名不同:www.taobao.com和ww.taobao.org www.jd.com和miaosha.jd.com
  • 域名相同,端口不同:localhost:8080和localhost:8081
  • 跨域问题:浏览器禁止请求的发起者与服务端发生跨域ajax请求,请求被浏览器拦截的问题

解决方案: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 # 这次跨域检测的有效期
    allowedMethods: # 允许的跨域ajax的请求方式
          - "GET"
          - "POST"
          - "DELETE"
          - "PUT"
          - "OPTIONS"
        allowedHeaders: "*" # 允许在请求中携带的头信息
        allowCredentials: true # 是否允许携带cookie
        maxAge: 360000 # 这次跨域检测的有效期



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值