请求路由
路由转发
第一步: 新建一个SpringBoot工程如gateway模块, 引入网关依赖和nacos服务发现依赖
<!--网关依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!--nacos服务发现依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
第二步: 在gateway模块
中编写启动类
@SpringBootApplication
public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class,args);
}
}
第三步: 编写基础配置和路由规则
路由名称(id)
: 路由的唯一表示,用户自定义只需要唯一即可路由目标地址(uri)
: 可以路由到某个固定地址,也可以路由到某个服务然后根据负载均衡规则选择一个服务实例路由断言(predicates)
: 判断请求是否符合路由规则的条件(可以设置多个规则),符合则转发到匹配的主机或者接口上路由过滤器(filters)
: 对请求或响应进行一些处理操作
server:
port: 10010 # 网关端口
spring:
application:
name: gateway # 服务名称
cloud:
nacos:
server-addr: localhost:8848 # 将网关服务注册到nacos
#server-addr: localhost:80 # 使用nginx反向代理功能
gateway:
routes: # 网关路由配置
- id: userservice
uri: lb://userservice # 配置userservice服务的路由规则
# uri: http://localhost:8081
predicates:
- Path=/user/** # 按照路径匹配,只要是以/user开头的请求路径就符合规则
- id: orderservice
uri: lb://orderservice # 配置orderservice服务的路由规则
predicates:
- Path=/order/** # 按照路径匹配,只要是以/order开头的请求路径就符合规则
第四步: 启动网关服务,网关会根据指定的路由规则将请求转发到对应的服务实例,此时会将网关端口号后面的地址拼接到要转发地址的端口号后面
- 访问
http://localhost:10010/user/1
时网关会将请求转发到http://userservice/user/1
- 访问
http://localhost:10010/order/101
时网关会将请求转发到http://orderservice/order/101
{
"id": 1,
"username": "柳岩",
"address": "湖南省衡阳市"
}
{
"id": 101,
"price": 699900,
"name": "Apple 苹果 iPhone 12 ",
"num": 1,
"userId": 1,
"user": {
"id": 1,
"username": "柳岩",
"address": "湖南省衡阳市"
}
}
网关实现路由的基本流程
断言工厂
常见的断言规则
我们在配置文件中写的断言规则只是字符串,这些断言规则会被Predicate Factory(断言工厂)
读取并转变为路由判断的条件
SpringCloudGatewway提供了11种基本的断言工厂,用来读取用户定义的断言条件并对请求做出判断
Path表示按照路径匹配
,这个规则由org.springframework.cloud.gateway.handler.predicate.PathRoutePredicateFactory
处理
- 支持使用
**
表示匹配任意多层路径,{xx}
表示占位符可以匹配一层路径 - 支持设置多个路径规则,规则之间以逗号分隔
predicates:
# 最终将请求地址拼接到转发地址的端口号后面
- Path=/red/{segment},/blue/**
# 同时segment这个参数也可以通过网关过滤工厂拿到
Map<String, String> uriVariables = ServerWebExchangeUtils.getUriTemplateVariables(exchange);
String segment = uriVariables.get("segment");
After
表示在xx时间之后才能转发到路由目标地址,可以应用于上传网站做活动
predicates:
- After=2031-04-13T15:14:47.433+08:00[Asia/Shanghai]
Before
表示在xx时间之前才能转发到路由目标地址
predicates:
- Before=2017-01-20T17:42:47.789-07:00[America/Denver]
Between
表示在两个时间之间才能转发到路由目标地址
predicates:
- Between=2017-01-20T17:42:47.789-07:00[America/Denver], 2017-01-21T17:42:47.789-07:00[America/Denver]
Cookie
表示请求必须在cookie里配置对应的key及其value才能转发到路由目标地址
predicates:
- Cookie=chocolate, ch.p
Header
表示请求必须配置请求头X-Request-Id ,\d+
表示值为数值类型,符合以上条件才能转发到路由目标地址
predicates:
- Header=X-Request-Id, \d+
Host
表示请求的主机必须符合指定的表达式才能转发到路由目标地址
predicates:
- Host=**.somehost.org,**.anotherhost.org
Method
表示请求的请求的方法为GET或者POST才能转发到路由目标地址
predicates:
- Method=GET,POST
Query
表示请求必须包含指定的请求参数name和value,value可以设置多个且以逗号隔开,支持.
匹配任意字母
predicates:
# key为Query,value为red或gree.或greet或greed等
- Query=red, gree.
RemoteAddr
表示请求的IP地址必须在指定的范围,参数是一个数组可以配置多个,参数格式为IP/子网掩码
predicates:
- RemoteAddr=192.168.1.1/24
Weight
表示将多个路由目标地址分为一组,然后给不同的地址设置不同的权重
spring:
cloud:
gateway:
routes:
- id: weight_high
uri: https://weighthigh.org
predicates:
- Weight=group1, 8 # 80%的请求会路由给https://weighthigh.org
- id: weight_low
uri: https://weightlow.org
predicates:
- Weight=group1, 2 # 20%的请求会路由给https://weightlow.org