Gateway网关

一、Gateway简介

网关,在微服务架构中,主要用来路由,增强和控制对服务的访问,同时也具备负载均衡、流量控制、访问控制等能力,SpringCloud Gateway是Spring官方基于Spring5.0、SpringBoot2.0等技术开发的网关,SpringCloud Gateway旨在为微服务架构提供一种简单而有效的统一的API路由管理方式。

  • 第二代网关技术和SpringCloud配合更紧密,之前的网关技术是zuul
  • 底层Netty(网络框架,封装了NIO)性能更好,多路复用
  • 路由过滤器合理的API设计,功能更加强大

二、为什么使用网关

目前项目的问题:

  • 微服务外部调用微服务集群里面的内容时,遇到问题,服务太多,需要记住所有的服务的地址
  • 一个服务有很多台机器,需要做负载均衡,浏览器显然不能做这件事情
  • 无法对请求进行统一的统计和过滤

网关就可以解决这些问题

  • 微服务网关封装了应用程序的内部结构,客户端只需要跟网关交互,而无需直接调用特定微服务
  • 方便监控,所有的请求都可以先请求网关,方便了对请求的管理和监控
  • 统一过滤处理,方便管理
  • 可以做负载均衡

三、Gateway使用

  • 创建一个服务(coding-gateway),并注册到注册中心
  • 引入gateway网关依赖
    • <!--引入gateway网关依赖-->
      <dependency>
          <groupId>org.springframework.cloud</groupId>
          <artifactId>spring-cloud-starter-gateway</artifactId>
      </dependency>
      
    • 注意:不能导入SpringBoot Web的依赖spring-boot-start-web

  • 网关配置
    • #路由的id 可以认为是当前路由规则的名字  要求唯一性
      spring.cloud.gateway.routes[0].id=product_route
      #匹配后的路由地址 【目标服务地址】
      spring.cloud.gateway.routes[0].uri=http://localhost:8080
      #断言 也就是匹配规则
      spring.cloud.gateway.routes[0].predicates[0]=Path=/coding-product/**
      
      
      #路由的id 可以认为是当前路由规则的名字  要求唯一性
      spring.cloud.gateway.routes[1].id=order_route
      #匹配后的路由地址 【目标服务地址】
      spring.cloud.gateway.routes[1].uri=http://localhost:8090
      #断言 也就是匹配规则
      spring.cloud.gateway.routes[1].predicates[0]=Path=/coding-order/**
      
      server.port=8001
      
  • 启动项目测试
    • http://localhost:网关服务端口/coding-product/products

四、路径重写

后台接口:http://localhost:8001/coding-order/order,如果前端调用时,地址为http://localhost:8001/api/coding-order/order,那么我们需要对路径进行重写

  • 方式一
#路由的id 可以认为是当前路由规则的名字  要求唯一性
spring.cloud.gateway.routes[1].id=order_route
#匹配后的路由地址 【目标服务地址】
spring.cloud.gateway.routes[1].uri=http://localhost:8090
#断言 也就是匹配规则
# 1、添加上api
spring.cloud.gateway.routes[1].predicates[0]=Path=/api/coding-order/**
# 2、对路径进行重写,把/api/coding-order重写成/coding-order
spring.cloud.gateway.routes[1].filters[0]=RewritePath=/api/coding-order(?<segment>/?.*),/coding-order/$\{segment}

server.port=8001
spring:
    cloud:
        gateway:
            routes:
                - id: order_route
                uri: http://localhost:8090
                predicates:
                    - Path=/api/coding-order/**
                filters:
                    - RewritePath=/api/coding-order(?<segment>/?.*),/coding-order/$\{segment}
  • 方式二
    • spring:
        cloud:
          gateway:
            routes:
              - id: order_route
                uri: http://localhost:8090
                predicates:
                  - Path=/api/coding-order/**
                filters:
      #            - RewritePath=/api/coding-order(?<segment>/?.*),/coding-order/$\{segment}
                  # 去除Path中前两个路径
                  - StripPrefix=2
                  # Path中路径换成/coding-order
                  - PrefixPath=/coding-order
      server:
        port: 8001
      

五、动态路径(负载均衡)

Gateway能够以注册中心上微服务名为路径创建动态路由进行转发,从而实现动态路由的功能

  • 配置【以订单服务为例】
spring:
  cloud:
    gateway:
      routes:
        - id: order_route
#          uri: http://localhost:8090
          uri: lb://coding-order
          predicates:
            - Path=/api/coding-order/**
          filters:
#            - RewritePath=/api/coding-order(?<segment>/?.*),/coding-order/$\{segment}
            - StripPrefix=2
            - PrefixPath=/coding-order

        - id: product_route
          uri: lb://coding-product
          predicates:
            - Path=/coding-product/**
server:
  port: 8001
  • 测试
    • 同时开启两个订单服务,重复请求,查询是否访问的不是同一个

    • 订单服务控制器

    • @RestController()
      public class OrderController {
      
          @Value("${server.port}")
          private Integer port;
      
          @GetMapping("/order")
          public String getOrder(){
              return "订单服务测试..."+port;
          }
      
      }
      
    • img

    • img

    • 六、处理跨域问题

    • spring:
        cloud:
          gateway:
            globalcors:
              corsConfigurations:
                '[/**]':
                  allowedHeaders: "*"
                  allowedOrigins: "*"
                  allowCredentials: true
                  allowedMethods:
                    - GET
                    - POST
                    - DELETE
                    - PUT
                    - PATCH
                    - OPTION
      server:
        port: 8001
      

七、自定义过滤器(GlobalFilter)

案例:判断请求中是否携带token

@Component
public class MyGlobalFilter implements GlobalFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //某个参数 对不对
        String username = exchange.getRequest().getQueryParams().getFirst("username");
        if (username==null) {
            //拦截
            // 设置响应状态码
            exchange.getResponse().setStatusCode(HttpStatus.MULTI_STATUS);
            return exchange.getResponse().setComplete();
        }
        //放行
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return 0; // 多个Filter中,数值越小越先执行
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

云游墨客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值