Gateway网关

网关GateWay

官方文档:https://docs.spring.io/spring-cloud-gateway/docs/3.1.2/reference/html/#gateway-how-it-works

核心概念

  • 路由: 网关的核心数据结构,定义了网关如何处理请求. 一条路由信息包含路由的唯一标识ID,目的地URI, 一组断言(用于判断当前请求是否匹配这条路由信息), 以及一组过滤器组成. 当网关收到一个请求时,如果某条路由信息的所有断言都为真,那么改请求匹配这条路由,会被发往改路由的目的uri。
  • 断言: 可以根据Http请求的路径,请求头或者请求参数对于一个请求进行路由匹配判断。
  • 过滤器: 当请求匹配上某个路由信息时,由配置的过滤器依次处理。

网关节点搭建

引入依赖

xml 复制代码
<dependencies>
        <!--   引入nacos 注册中心依赖  注册服务   -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
<!--    gateway网关的依赖,注意,不要引用 starter-web依赖,否则启动报错    -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
<!--     这个依赖可以查看网关的路由信息   -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
    </dependencies>

启动类

java 复制代码
package com.qf.gateway;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

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

配置文件

yaml 复制代码
server:
  port: 80
spring:
  application:             #这是注册在注册中心的服务名
    name: service-gateway
  cloud:
    nacos:
      discovery:   #注册中心的地址
        server-addr: 127.0.0.1:8848
    gateway:
      # 打开如下配置,自动发现 Nacos 注册中心的服务,并自动生成路由信息
      discovery:
        locator:
          enabled: true
          lower-case-service-id: true  # 让网关自动生成的服务名为小写
      routes:
        - id: aa
          # 断言的作用,判断网关收到的请求是否匹配当前的路由信息
          predicates:
            - Path=/pro/**
          filters:  # 重写Url 去掉pro
            - RewritePath=/pro/?(?<segment>.*), /$\{segment}
          uri: lb://service-provide  #lb代表 负载均衡  写服务名
        - id: ss
          # 断言的作用,判断网关收到的请求是否匹配当前的路由信息
          predicates:
            - Path=/sss/**
          filters:
            - RewritePath=/sss/?(?<segment>.*), /$\{segment}
          uri: http://localhost:8081/
        - id: baidu
          # 断言的作用,判断网关收到的请求是否匹配当前的路由信息
          predicates:
            - Path=/baidu/jmj/lll/**
          filters:
            # 去掉前缀几个 /**
            - StripPrefix=3
          uri: http://www.baidu.com


#开启 监控功能#开启 监控功能  http://localhost/actuator/gateway/routes
management:
  endpoints:
    enabled-by-default: true #暴露所有端点信息
    web:
      exposure:
        include: '*'  #以web方式暴露

查看路由信息

http://localhost/actuator/gateway/routes

手动添加路由信息

yaml 复制代码
spring:
  cloud:
    gateway:
      routes:
        - id: baidu
        	# 断言的作用,判断网关收到的请求是否匹配当前的路由信息 
          predicates:
            - Path=/**
          uri: http://www.baidu.com

尝试发送如下请求,并观察响应结果

http://localhost/s?wd=onepiece

添加路由信息到内部微服务

将路径/sss的请求发送给micro1微服务处理

yml 复制代码
spring:
  cloud:
    gateway:
      routes:
        - id: micro1
          predicates:
            - Path=/sss/**
          uri: http://localhost:9100/
        - id: baidu
          predicates:
            - Path=/**
          uri: http://www.baidu.com

错误原因分析,在micro1节点观察日志,请求路径为 /sss/test1。

解决办法:使用gateway提供的URL重写功能。配置url重写过滤器。

URL重写

当断言为true时,gateway会把当前请求路径完整的发送给后端uri,因此需要特别注意后端实际的接口地址是否匹配。

例如,后端真实接口地址为:http://localhost:8900/test1

那么,gateway真正转发给后端的请求为http://localhost:8900/sss/test1。

如果需要,可以重写发送给后端接口的真实uri路径。代码如下:

当匹配sss路径的请求发送给网关时,真正转发的路径去掉了sss,仅仅保留后面的路径信息

yaml 复制代码
spring:
  cloud:
    gateway:
      routes:
        - id: micro1
          predicates:
            - Path=/sss/**
          filters:
            - RewritePath=/sss/?(?<segment>.*), /$\{segment}
          uri: http://localhost:9100/
        - id: baidu
          predicates:
            - Path=/**
          uri: http://www.baidu.com

或者使用内置过滤器实现URL重写

yaml 复制代码
spring:
  cloud:
    gateway:
      routes:
        - id: baidu
          predicates:
            - Path=/baidu/**
          # 内置过滤器 StripPrefix,可以去掉Path中的前n个前缀(n为StripPrefix配置的值) 
          filters:
            - StripPrefix=1
          uri: http://www.baidu.com

负载均衡调用内部微服务

uri: lb://micro1 , 双斜线后面写微服务的名称

yml 复制代码
spring:
  application:
    name: gateway
  cloud:
    gateway:
      routes:
        - id: micro1
          predicates:
            - Path=/sss/**
          filters:
            - RewritePath=/sss/?(?<segment>.*), /$\{segment}
          uri: lb://micro1

整合Nacos自动生成微服务路由信息

注意:如果gateway想要自动生成eureka中注册服务的路由信息,需要开启如下配置:

yaml 复制代码
spring:
  cloud:
    gateway:
      # 打开如下配置,自动发现eureka注册中心的服务,并自动生成路由信息      
      discovery:
        locator:
          enabled: true 
          lower-case-service-id: true  # 让网关自动生成的服务名为小写

http://localhost/actuator/gateway/routes

断言配置

yaml 复制代码
spring:
  cloud:
    gateway:
      routes:
        - id: search
          uri: lb://micro1  #服务名
          predicates:
            - Path=/sss/**
            - After=2022-01-20T17:42:47.789-07:00[America/Denver] # 还有一个Before 
            - Cookie=chocolate, ch.p   #cookie  chocolate=chop
            - Header=X-Request-Id, \d+  # 请求头里   X-Request-Id= 1-任意个(0-9)的整数
          filters:
            - RewritePath=/sss/?(?<segment>.*), /$\{segment}
相关推荐
Swift社区3 小时前
在 Swift 中实现字符串分割问题:以字典中的单词构造句子
开发语言·ios·swift
没头脑的ht3 小时前
Swift内存访问冲突
开发语言·ios·swift
没头脑的ht3 小时前
Swift闭包的本质
开发语言·ios·swift
wjs20243 小时前
Swift 数组
开发语言
吾日三省吾码4 小时前
JVM 性能调优
java
stm 学习ing4 小时前
FPGA 第十讲 避免latch的产生
c语言·开发语言·单片机·嵌入式硬件·fpga开发·fpga
湫ccc5 小时前
《Python基础》之字符串格式化输出
开发语言·python
弗拉唐5 小时前
springBoot,mp,ssm整合案例
java·spring boot·mybatis
oi775 小时前
使用itextpdf进行pdf模版填充中文文本时部分字不显示问题
java·服务器