SpringCloud网关服务

一、介绍

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

二、为什么要使用网关

        在微服务架构中,每个微服务都有各自的容器或服务器,都有不同的IP,那么前端程序在访问后端程序的时候,需要根据不同的微服务配置不同的Ajax请求地址,这样无疑加大了前端开发人员的工作量;其次在常规的程序中,基本都涉及到登录验证以及鉴定权限的功能,那么基于微服务架构,是不是每个微服务都需要验证请求是否合法或者是否具备权限,这样也同样加大了后端开发人员的工作量。

网关很好的解决了这些问题,网关如何解决?

网关的核心功能:请求路由、权限控制、限流

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

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

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

架构图:

三、快速搭建一个网关服务

1、创建一个GateWay服务

2、引入网关的依赖

网关需要转发请求,所以也需要导入注册中心

<!--网关-->
<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>

至此,网关服务其实已经搭建完成,核心点在于网关的配置‘

3、编写基础配置和路由规则:

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/开头就符合要求

路由配置包括:

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

4、此时即可进行网关服务的启动,并测试

5、网关路由的流程图

四、断言工厂

gateway里面的断言条件是predicates属性,它的作用就是过滤访问条件,满足它设置的条件才放行例如上述例子的配置文件中的,满足 - PATH = /USER/**:这个就是满足访问路径为/user开头的才放行;

常规来说实际应用中Path使用的比较多,其他的比较少

以下列举一系列断言:

名称

说明

示例

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

权重处理

五、过滤器

· 网关的过滤器与常规的过滤器功能类似,都是拦截请求,并对当前请求进行一系列的操作,例如登录验证、权限鉴定等;网关提供了过滤器工厂,可以通过配置的方式快速的完成过滤器的配置,以下列举部分:

名称

说明

AddRequestHeader

给当前请求添加一个请求头

RemoveRequestHeader

移除请求中的一个请求头

AddResponseHeader

给响应结果中添加一个响应头

RemoveResponseHeader

从响应结果中移除有一个响应头

RequestRateLimiter

限制请求的流量

配置方式:

路由过滤器:

        直接在网关的配置中添加filters+实际的过滤条件即可,如下所示,就是在当前的routes中添加一个AddRequestHeader过滤器,并在每个请求头中添加一个Truth属性,属性值为TestFilter

spring:
  cloud:
    gateway:
      routes:
      - id: user-service 
        uri: lb://userservice 
        predicates: 
        - Path=/user/** 
        filters: # 过滤器
        - AddRequestHeader=Truth, TestFilter! # 添加请求头

默认过滤器:

        上述配置可以看到,filters是配置在routes中的,只对当前配置的routes有效,在实际应用中网关会配置很多条routes,如果存在相同的过滤器配置,那每条routes都需要相同的过滤器配置,这样很麻烦,于是就有了default-filters配置:

spring:
  cloud:
    gateway:
      routes:
      - id: user-service 
        uri: lb://userservice 
        predicates: 
        - Path=/user/**
      default-filters: # 默认过滤项
      - AddRequestHeader=Truth, TestFilter! 

default-filters的配置作用跟filters相同,只是default-filters是对所有路由生效,只需要配置一次

全局过滤器:

        这是比default-filters作用范围更广的过滤器,上述的两种过滤器都是可以进行配置的,全局过滤器需要开发人员自己写代码实现过滤规则,需要实现核心接口GlobalFilter:如下实现是否为admin的判断

@Componentpublic 
class AuthFilter implements GlobalFilter {
    @Override    
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {

        //获取请求头中的auth属性        
        String auth = exchange.getRequest().getQueryParams().getFirst("auth");

        //判断是否为管理员        
        if ("admin".equals(auth)){
            //放行           
             return chain.filter(exchange);
        }

        //不具备admin权限拦截            
        //设置返回的状态码        
        exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);

        //结束请求,并返回        
        return exchange.getResponse().setComplete();


    }

PS:过滤器实现的顺序:

当然也可以通过@Order注解进行手动排序,此处不做说明

六、跨域问题处理

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

  • 域名不同: www.taobao.com 和 www.taobao.org 和 www.jd.com 和 miaosha.jd.com
  • 域名相同,端口不同:localhost:8080和localhost8081

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

网关提供了解决跨域的配置

spring:
  cloud:
    gateway:
      # 。。。
      globalcors: # 全局的跨域处理
        add-to-simple-url-handler-mapping: true # 解决options请求被拦截问题
        corsConfigurations:
          '[/**]':
            allowedOrigins: # 允许哪些网站的跨域请求 
              - "http://localhost:8090"
            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、付费专栏及课程。

余额充值