SpringCloud微服务学习日志-Gateway网关

一.为什么需要网关

在某些情况下,部分接口需要权限分级。若是在每个微服务模块都配置一套权限框架的话,代价实在太大。所以,我们需要一个中心,来统一处理这样的请求控制。这就需要网关的作用:

SpringCloud微服务学习日志-Gateway网关_第1张图片

网关的作用不仅只是身份认证和权限控制,还有以下作用 

  •  身份验证和权限管理
  • 限流
  • 负载均衡
  • ................

 二.网关的使用

(一).前置处理

网关作为一个模块,也要注册到nacos注册中心里面,所以需要在父工程创建一个模块叫Gateway,测试其启动无误,并且成功注册到nacos中心。

1.启动类

package org.white;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

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

2.applicaiton.yml

server:
  port: 6532
spring:
  application:
    name: Gateway
  cloud:
    nacos:
      server-addr: http://127.0.0.1:8848

 3.依赖

    
        //这里千万别导成web了,会报错的
        
            org.springframework.boot
            spring-boot-starter-webflux
        
        
            com.alibaba.cloud
            spring-cloud-alibaba-nacos-discovery
            2.2.0.RELEASE
        
    

启动成功后即可进入下一步

(二).引入依赖

        
            org.springframework.cloud
            spring-cloud-starter-gateway
        

(三).编写路由配置 

server:
  port: 6532
spring:
  application:
    name: Gateway
  cloud:
    nacos:
      server-addr: http://127.0.0.1
    gateway:
      routes:
        - id: ServiceB   //路由ID,随便起,不重名即可
          uri: lb://ServiceB   //地址,lb://表示负载均衡
          predicates:          //路由断言
            - Path=/serviceB/**       //断言规则,匹配/serviceB开头的所有URI,由断言工厂处理
        - id: ServiceA
          uri: lb://ServiceA
          predicates:
            - Path=/serviceA/**

重启后访问网关的地址就可以进入相应的服务了。

三.断言工厂

上面的路由断言我们仅仅只是使用了字符串便可以让Gateway识别到我们采用的是哪一种匹配规则。其实都是依托于PathRoutePredicateFactory这个类来处理的。

例如允许某个时间点后才可以访问:

    gateway:
      routes:
        - id: ServiceB   //路由ID,随便起,不重名即可
          uri: lb://ServiceB   //地址,lb://表示负载均衡
          predicates:          //路由断言
            - Path=/serviceB/**       //断言规则,匹配/serviceB开头的所有URI,由断言工厂处理
            - After=2025-05-28+08:00[Asia/Shanghai]   //断言规则,2025年5月28日后可以进入

断言工厂还有好十多种种规则:

详情也可以进入Spring官网查看:
https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gateway-request-predicates-factories

 四.过滤器

 过滤器可以让我们在处理发送和接受微服务请求时做出调整:

SpringCloud微服务学习日志-Gateway网关_第2张图片

 然而,Spring官方给出的过滤器高达30多种,具体可以前往Spring官网查看:

Gateway过滤器:

Spring Cloud Gateway

 这里对AddRequestParameter这个过滤器进行一个测试:

(一).局部过滤器:

1.在gateway的application.yml添加filters节点

    gateway:
      routes:
        - id: ServiceB
          uri: lb://ServiceB
          predicates:
            - Path=/serviceB/**
        - id: ServiceA
          uri: lb://ServiceA
          predicates:
            - Path=/serviceA/**
          filters:
            - AddRequestParameter=pm, 666 //","前面的是参数名,后面是值
            

2.改造serviceA的Controller 

    @GetMapping("test")
    public String ServiceATest(@RequestParam String pm){
        String result = serviceB.serviceB(pm);
        return "ServiceA Working and " + result;
    }

3.查看结果 

 想要给所有路由都添加过滤器的话,可以使用default-filter:

    gateway:
      routes:
        - id: ServiceB
          uri: lb://ServiceB
          predicates:
            - Path=/serviceB/**
        - id: ServiceA
          uri: lb://ServiceA
          predicates:
            - Path=/serviceA/**
          filters:
            - AddRequestParameter=pm, 666  //只对ServiceA生效
      default-filters:   //对所有路由生效
        - AddRequestParameter=pm, 666

 (二).全局过滤器:

这个全局过滤器,从名字听起来,和上面的default-filters有点功能重复了的意思。其实这个全局过滤器叫它自定义过滤器更合适。上面我们添加的过滤器毕竟是Spring定义好了给我们的,但是如果我们想要实现更复杂的功能的话必须要手动定义过滤器。

public interface GlobalFilter {
    Mono filter(ServerWebExchange exchange, GatewayFilterChain chain);
}

exchange代表上文,chain可以放行

比如,我们想获取请求参数Auth的值是否为admin,如果是则放行:

@Component
@Order(-1)
public class AuthFilter implements GlobalFilter {
    @Override
    public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        MultiValueMap queryParams = request.getQueryParams();
        String auth = queryParams.getFirst("auth");
        if ("auth".equals(auth)) {
            return chain.filter(exchange);
        }

        exchange.getResponse().setStatusCode(HttpStatus.FORBIDDEN);

        exchange.getResponse().setComplete();


        return chain.filter(exchange);
    }
}

 (三).过滤器顺序

  • 当存在orde值的时候,order越小越先执行
  • 当order值一样的时候,执行顺序是:DefaultFilter>局部过滤器>GlobalFilter

五.跨域配置 

Gateway也自带了跨域配置,我们在网关配置跨域配置后,在微服务上就不用单独配置跨域了:

    gateway:
      routes:
        - id: ServiceB
          uri: lb://ServiceB
          predicates:
            - Path=/serviceB/**
        - id: ServiceA
          uri: lb://ServiceA
          predicates:
            - Path=/serviceA/**
          filters:
            - AddRequestParameter=pm, 666
      globalcors:
        add-to-simple-url-handler-mapping: true    //允许Options
        cors-configurations: //跨域配置
          '[/**]':
            allowedOrigins:
              - "http://127.0.0.1:8080"     //允许跨域的地址
            allowedMethods:   //允许跨域的请求
              - GET
              - POST
              - DELETE
              - PUT
              - OPTIONS
            allowCredentials: true   //允许携带Cookie
            maxAge: 36000   //允许跨域的有效期

 以上就是gateway的全部内容

你可能感兴趣的:(微服务,spring,cloud,学习)