SpringCloud集成统一网关Gateway

目录

  • 一、为什么需要网关
  • 二、搭建网关
    • 1.创建module,引入依赖和nacos的发现组件
    • 2.编写路由配置和nacos地址
    • 3. 路由断言工厂RoutePredicateFactory
      • 3.1 按照时间
    • 4. 路由过滤器工厂GatewayFilterFactories
      • 4.1. 给所有进入userservice的请求添加一个请求头
  • 三、全局过滤器GlobalFilter
    • 2.过滤器的执行顺序
  • 四、网关跨域问题
  • 五、GatewayFilter

一、为什么需要网关

SpringCloud集成统一网关Gateway_第1张图片
SpringCloud集成统一网关Gateway_第2张图片

在SpringCloud的网关的实现包含如下两种

  • gateway
  • zuul

zuul是基于Servlet的实现,属于阻塞时编程。而Gateway则是基于Sprng5中提供的WebFlux,属于响应式编程的实现,具有更好的性能。

二、搭建网关

1.创建module,引入依赖和nacos的发现组件


<dependency>
    <groupId>org.springframework.cloudgroupId>
    <artifactId>spring-cloud-starter-gatewayartifactId>
dependency>

<dependency>
    <groupId>com.alibaba.cloudgroupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
dependency>

<dependency>
    <groupId>com.alibaba.cloudgroupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-configartifactId>
dependency>

2.编写路由配置和nacos地址

切记如下,如果具体的服务的地址是/orders开头。则下面要注释掉,否则访问http://127.0.0.1:8888/orders/1显示404
#default-filters: #全局用于配置所有路由共享过滤器
# - StripPrefix=1 #去掉- Path=/auth 前缀
# - PreserveHostHeader #发送原主机头

server:
  port: 8888

spring:
  application:
    name: edevp-gateway
  profiles:
    active: dev

  cloud:
    nacos:
      discovery: #服务注册与发现
        server-addr: ${NACOS_HOST:nacos-host}:${NACOS_PORT:7102} #nacos地址
        username: dev
        password: xxxx
        namespace: edevp-demo #指定命名空间 可以删掉namespace不写默认public

      #配置文件组成 : 通俗点 服务名称-指定环境.后缀名称  name-active.file-extension
      config: #动态配置
        server-addr: ${spring.cloud.nacos.discovery.server-addr} #nacos地址
        username: dev
        password: xxxx
        file-extension: yml #配置文件类型  非常重要后缀一定要一致 xxx.yml
        namespace: edevp-demo #指定命名空间 可以删掉namespace不写默认public
        shared-configs:
          - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}

    gateway:
      discovery:
        locator:
          # 是否可以通过其他服务的serviceId来转发到具体的服务实例。默认为false
          # 为true,自动创建路由,路由访问方式:http://Gateway_HOST:Gateway_PORT/大写的serviceId/**,其中微服务应用名默认大写访问
          # 让gateway通过服务发现组件找到其他的微服务,如果是true则自动,false才可以配置routes属性生效
          enabled: false
          # 服务名默认必须大写,否则会抛404错误,如果服务名要用小写,可在属性配置文件中添加spring.cloud.gateway.discovery.locator.lowerCaseServiceId=true配置解决
          lower-case-service-id: true
      #default-filters:  #全局用于配置所有路由共享过滤器
      #  - StripPrefix=1 #去掉- Path=/auth 前缀
      #  - PreserveHostHeader #发送原主机头
      routes: # 网关路由配置
        - id: edevp-user # 路由id,自定义,只要唯一即可
          # uri: http://127.0.0.1:8202 # 路由的目标地址,http就是固定地址
          uri: lb://edevp-user # 路由的目的地址,lb就是负载均衡,后面跟服务名称
          predicates: # 路由断言,也就是判断请求是否符合路由规则的调价
            - Path=/users/** # 这个是按照规则匹配,只要以/user/开头就符合要求
        - id: edevp-order
          uri: lb://edevp-order
          predicates: # 路由断言,也就是判断请求是否符合路由规则的调价
            - Path=/orders/** # 这个是按照规则匹配,只要以/user/开头就符合要求

3. 路由断言工厂RoutePredicateFactory

具体配置可以参照:官网文档
SpringCloud集成统一网关Gateway_第3张图片

3.1 按照时间

spring:
  cloud:
    gateway:
      routes:
      - id: after_route
        uri: https://example.org
        predicates:
        - After=2017-01-20T17:42:47.789-07:00[America/Denver]

4. 路由过滤器工厂GatewayFilterFactories

有多达31中不通的工厂,开参考官网文档https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gatewayfilter-factories
SpringCloud集成统一网关Gateway_第4张图片
SpringCloud集成统一网关Gateway_第5张图片

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

spring:
  cloud:
    gateway:
      routes:
      - id: edevp-user # 路由id,自定义,只要唯一即可
		# uri: http://127.0.0.1:8202 # 路由的目标地址,http就是固定地址
		uri: lb://edevp-user # 路由的目的地址,lb就是负载均衡,后面跟服务名称
		predicates: # 路由断言,也就是判断请求是否符合路由规则的调价
		  - Path=/users/** # 这个是按照规则匹配,只要以/user/开头就符合要求
		filters:
		  - AddRequestHeader=X-Request-red, blue
      default-filters:
        - AddRequestHeader=X-Request-red, green

如果是给全局增加请求头default-filters:

在user-service中的controller中添加如下

@GetMapping("/info/{id}")
    public R<UserInfoDTO> get(@PathVariable("id") String id, @RequestHeader(value = "X-Request-red", required = true) String header) {
        UserInfoDTO data = new UserInfoDTO();
        data.setName(properties.getValue()+"-"+id+"-"+header);
        return R.ok(data);
    }

浏览器访问{{gateway-host}}/users/info/1发现两个header都被设置

{
    "code": 0,
    "data": {
        "name": "李四-1-true,green,blue"
    }
}

三、全局过滤器GlobalFilter

SpringCloud集成统一网关Gateway_第6张图片## 1. 通过全局过滤器校验权限
拦截请求参数中Authorization的值是否等于admin,如果是则放行

order最好设置-200,否则遇到Unable to find instance会直接先跳到ErrorWebExceptionHandler

/**
 * @author lean
 * //Order 顺序,值越小,优先级越高
 */
@Order(-200)
@Component
public class AuthorizeFilter implements GlobalFilter {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 1. 获取请求参数
        ServerHttpRequest request = exchange.getRequest();
        MultiValueMap<String, String> params = request.getQueryParams();
        // 2.获取参数中的authorization 参数
        String auth = params.getFirst("authorization");
        // 3.判断参数值是否等于admin
        if("admin".equals(auth)){
            // 4.放行
            return chain.filter(exchange);
        }
        // 5. 否拦截
        // 5.1 设置状态码
        exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
        // 5.2 拦截请求
        return exchange.getResponse().setComplete();
    }
}

2.过滤器的执行顺序

从下图可以知道网关中的所有服务器最终都是GatewayFilter,因为是可以合并到一个集合排序的
SpringCloud集成统一网关Gateway_第7张图片

SpringCloud集成统一网关Gateway_第8张图片
SpringCloud集成统一网关Gateway_第9张图片

四、网关跨域问题

SpringCloud集成统一网关Gateway_第10张图片

'[/]'*表示检测所有请求
allowCredentials: true 是否允许携带cookie

spring:
  cloud:
    gateway:
      # 允许跨域请求配置
      globalcors:
        add-to-simple-url-handler-mapping: true   # 允许来自所有域名(allowedOrigins)的所有请求方式(allowedMethods)发出CORS请求
        cors-configurations:
          '[/**]': # 拦截所有请求
            # 允许任何域名使用
            allowedOrigins: "*"
            # 允许任何头
            allowedHeaders: "*"
            # 允许任何方法(post、get等)
            allowedMethods: "*"
            # sessionid 多次访问一致
            allowCredentials: true
        # 允许来自所有域名(allowedOrigins)的所有请求方式(allowedMethods)发出CORS请求

允许指定ip端口访问

spring:
  cloud:
    gateway:
      globalcors:
        cors-configurations:
          '[/**]':
            # 允许携带认证信息
            # 允许跨域的源(网站域名/ip),设置*为全部
            # 允许跨域请求里的head字段,设置*为全部
            # 允许跨域的method, 默认为GET和OPTIONS,设置*为全部
            # 跨域允许的有效期
            allow-credentials: true
            allowed-origins:
              - "http://localhost:13009"
              - "http://localhost:13010"
            allowed-headers: "*"
            allowed-methods:
              - OPTIONS
              - GET
              - POST
              - PUT
            max-age: 3600

五、GatewayFilter

只支持配置的方式,不支持如下代码

@Slf4j
@Component
@Order(-100)
public class AuthGatewayFilter implements GatewayFilter

你可能感兴趣的:(SpringCloud,java,spring,cloud,大数据)