依赖引入

网关也是微服务,也需要注册到nacos

需要引入gateway依赖

需要引入loadbalancer依赖,用于负载均衡

<dependencies>
    <!--nacos 服务注册发现-->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-gateway</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-loadbalancer</artifactId>
    </dependency>
</dependencies>

启动类

需要开启服务发现

@SpringBootApplication
@EnableDiscoveryClient // 启用服务发现客户端
public class GatewayApplication {
    public static void main(String[] args) {
        SpringApplication.run(GatewayApplication.class, args);
    }
}

配置文件

spring:
  application:
    name: api-gateway  #服务名称
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848 # Nacos 服务器地址
    gateway:
      routes:
        - id: item-service
          uri: lb://item-service # 使用lb负载均衡
          # uri: http://localhost:8081 # 不使用负载均衡
          predicates:
            - Path=/items/**
		  filters:
		  	- RewritePath= 
        - id: card-service
          uri: lb://card-service # 使用lb负载均衡
          predicates:
            - Path=/card/**

配置文件解析:

  • spirng.gateway.routes:

    每个 - 后面都是一个路由。

    id: 为这个路由的编号,具有唯一性。

    uri: 为要访问的服务器地址,可以写死,如果使用了负载均衡必须要引入nacos依赖和loadbalancer依赖。

    predicates: 断言,匹配路径 - Path=/items/**,意思是如果是这个通配符下的路径全部负载均衡到上面uri配置的服务地址。

    # 1. Path 路径匹配:匹配以 /api/ 开头的请求
    - Path=/api/**
    
    # 2. Method 方法匹配:匹配 GET 或 POST 请求
    - Method=GET, POST
    
    # 3. Header 请求头匹配:请求头必须包含 X-Request-Id,且值符合正则表达式
    - Header=X-Request-Id, \d+
    
    # 4. Cookie 匹配:请求必须包含名为 loginId 的 cookie,其值符合正则表达式
    - Cookie=loginId, .+
    
    # 5. Host 主机名匹配:匹配 Host 为 `**.example.com` 的请求
    - Host=**.example.com
    
    # 6. Query 参数匹配:请求必须包含名为 `token` 的查询参数,值可选(也可以像Header一样指定值正则)
    - Query=token
    # - Query=token, abc.  # 表示必须有token参数,且值匹配正则 `abc.`
    
    # 7. After/Before/Between 时间匹配(基于ZonedDateTime)
    - After=2023-01-20T17:42:47.789-07:00[America/Denver]
    - Before=2023-01-21T17:42:47.789-07:00[America/Denver]
    - Between=2023-01-20T17:42:47.789-07:00[America/Denver], 2023-01-21T17:42:47.789-07:00[America/Denver]
    
    # 8. RemoteAddr 远程地址匹配:匹配来自指定IP段(CIDR表示法)的请求
    - RemoteAddr=192.168.1.1/24
    

    filters: 过滤,可以直接放行一些路径比如swagger文档之类的

    # 1. Path 重写:将请求路径中的 `/user-service` 替换成空
    # 原始请求:/user-service/api/users -> 转发后的请求:/api/users
    - RewritePath=/user-service/?(?<segment>.*), /$\{segment}
    # 2. 添加请求头:在转发前添加一个请求头 `X-Gateway-Flag: true`
    - AddRequestHeader=X-Gateway-Flag, true
    
    # 3. 添加响应头:在收到下游响应后,给客户端响应添加一个头 `X-Response-From: gateway`
    - AddResponseHeader=X-Response-From, gateway
    
    # 4. 剥离路径前缀:去掉路径的前面一部分(例如这里去掉1级路径)
    # 原始请求:/api/user/1 -> 转发后的请求:/user/1
    - StripPrefix=1
    
    # 5. 请求参数处理:添加一个参数 `source=gateway`
    - AddRequestParameter=source, gateway
    
    # 6. 熔断器(Hystrix/Resilience4j):集成熔断,提供降级能力
    - name: Hystrix
      args:
        name: fallbackcmd
        fallbackUri: forward:/fallback # 熔断时转发到网关内的 /fallback 端点
    
    # 7. 重试机制:对特定情况(如5xx错误)进行重试
    - name: Retry
      args:
        retries: 3
        statuses: BAD_GATEWAY, INTERNAL_SERVER_ERROR # 遇到这些状态码才重试
        methods: GET # 只对GET方法重试
    
    # 8. 请求体缓存(通常用于需要读取请求体的过滤器,如修改请求体)
    - CacheRequestBody=REQUEST_BODY_CACHE
    
    # 9. 修改请求路径:简单直接地设置新路径
    - SetPath=/api/v2/$\{segment} # 需要与其他提取参数的Predicate/Filter配合使用
    # 10. 限流(RequestRateLimiter):通常配合Redis使用,基于令牌桶算法
    - name: RequestRateLimiter
      args:
        redis-rate-limiter.replenishRate: 10 # 每秒允许的请求数
        redis-rate-limiter.burstCapacity: 20 # 每秒最大处理的请求数(突发流量)
        key-resolver: "#{@userKeyResolver}" # 指定限流键的解析器Bean(例如按用户、IP限流)