依赖引入
网关也是微服务,也需要注册到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/24filters: 过滤,可以直接放行一些路径比如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限流)