实现微服务网关的技术有很多。
我们使用gateway
这个网关技术,无缝衔接到基于spring cloud
的微服务开发中来。
Gateway官网:https://spring.io/projects/spring-cloud-gateway
GatewayFilter
和 Global Filter
。过滤器 Filter将会对请求和响应进行修改处理。<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-gatewayartifactId>
dependency>
discovery:
locator:
#开启从注册中心动态创建路由的功能,网关自动映射处理逻辑:http://gatewayIP:gatewayPort/微服务名称/微服务请求地址
enabled: false # 把网关请求自动转发到微服务请求地址: http://微服务名称/微服务请求地址
lower-case-service-id: true #开启服务名称小写装换,Eureka 对服务名称默认大写管理
# ========以上配置就已经实现请求转发的功能了============
# 如 http://localhost:9003/springcloud-alibaba-account/account/findAll 自动转发到 http://springcloud-alibaba-account/account/findAll
# 商业开发中,enable 一般不设置,使用默认值false ,避免不必要的自动转发规则
globalcors: # 跨域配置
corsConfigurations:
'[/**]':
allowedHeaders: "*"
allowedOrigins: "*"
allowCredentials: true
allowedMethods:
- GET
- POST
- DELETE
- PUT
- OPTION
httpclient: # 配置全局 http 超时
connect-timeout: 1000 #必须以毫秒为单位指定
response-timeout: 5s #必须指定为 java.time.Duration
一个route
包括 id、 predicates(断言、谓词)、filters(过滤器)、uri 等属性。
- id: account # 路由定义的命名 唯一即可
# uri: http://localhost:9000
uri: lb://springcloud-alibaba-account
# 当前路由定义对应的转发地址 lb:服务名称 使用LoadBalancerClient 实现负载均衡
#配置谓词集合 RoutePredicateFactory
predicates:
# 谓词名称是有套路的,是GatewayPredicate接口实现类的命名前缀 XxxRoutePredicateFactory
- Path=/account/**,/aaa/** #定义一个谓词 格式:谓词名字=参数 或者 name:名字 args:参数 所有以/account/开始的请求都将路由到uri http://springcloud-alibaba-account
# http://localhost:9004/account/account/findAll 转发到 http://localhost:9000/account/findAll
# 配置过滤集合
filters:
- StripPrefix=1 # 将请求中的第一个路径去掉 请求路径以/区分,一个/表示一个路径,如:/api/account 会变成/account
#- PrefixPath=/brand # 为请求路径添加前缀/brand
在Route
中的uri
属性中可以使用lb
实现负载均衡。
通过 LoadBalancerClient 路由过滤器(客户端负载均衡)
例如:我们启动两个Account服务的实例:
先以9000端口启动Account服务,
然后修改接口返回信息,在以9001端口启动。
在浏览器访问:http://localhost:9004/aaa/account/findAll
看后台控制台打印信息:
9004网关服务:
Account9000服务:
Account9001服务:
可以看到AbstractRoutePredicateFactory
有许多的实现类,这些类的前缀
就是我们谓词的参数,比如:Path、Header、Before、Query、Host、Method、Weight、Cookie、After、Between、Read等。
- id: account # 路由定义的命名 唯一即可
uri: http://localhost:9000
#uri: ld://springcloud-alibaba-account/ # 当前路由定义对应的转发地址 lb:服务名称 使用LoadBalancerClient 实现负载均衡
#配置谓词集合 RoutePredicateFactory
predicates:
# 谓词名称是有套路的,是GatewayPredicate接口实现类的命名前缀 XxxRoutePredicateFactory
- Path=/account/** #定义一个谓词 格式:谓词名字=参数 或者 name:名字 args:参数
# http://localhost:9004/account/account/findAll 转发到 http://localhost:9000/account/findAll
# 配置过滤集合
filters:
- StripPrefix=1 # 将请求中的第一个路径去掉 请求路径以/区分,一个/表示一个路径,如:/api/good 会变成/good
- id: baidu
uri: https://www.baidu.com
predicates:
# http://localhost:9004/bd/ 转发至 https://www.baidu.com
# 断言匹配到Path 转发 https://www.baidu.com/bd 去掉/bd路径
- Path=/bd/**
filters:
- StripPrefix=1
比如 http://localhost:9004/account/account/findAll
就会被Path
断言匹配到,而转发到 http://localhost:9000/account/account/findAll
,经过StripPrefix
会去除一个路径,最终变为:http://localhost:9000/account/findAll
http://localhost:9004/bd/
可以断言匹配转发到百度,而http://localhost:9004/bd/a
则转发失败,原因是断言后的转发路径是https://www.baidu.com/a
。
- id: queryuri
uri: https://www.qq.com/
predicates:
# http://localhost:9004/?uri=qq 转发至 https://www.qq.com
# http://localhost:9004/?uri=qq&url=baidu 也可以转发到 https://www.qq.com
# http://localhost:9004/?url=baidu&uri=qq 也可以转发到 https://www.qq.com
# 由此可见: 只要路径中有uri=qq 就可以匹配转发 ,且断言匹配是由上到下的
# uri中匹配qq
- Query=uri,qq
metadata: # 配置每条路由超时
response-timeout: 200 # 必须以毫秒为单位指定。
connect-timeout: 200 # 必须以毫秒为单位指定。
- id: queryurl
uri: https://www.baidu.com
predicates:
# http://localhost:9004/?url=baidu 转发至 https://www.baidu.com
# url 中匹配 baidu
- Query=url,baidu
- id: queayname
uri: https://www.baidu.com
predicates:
# 参数name的值包含zs则会匹配成功
- Query=name,zs.*
- id: header
uri: http://localhost:9000
predicates:
# http://localhost:9004/header/account/findAll 转发至 http://localhost:9000/account/findAll
# 路径匹配 header ,请求头中必须myheader:zhangsan 并去除 一个路径 header 才能成功转发
- Path=/header/**
- name: Header
args:
# key: value
header: myheader
regexp: zhangsan.*
filters:
- StripPrefix=1
- id: queayname
uri: https://www.baidu.com
predicates:
# http://localhost:9004/?url=baidu 转发至 https://www.baidu.com
- Query=name,zs.*
- Method=GET
使用Method属性指定方法的请求格式,如以上配置只允许GET请求:
如果修改为:- Method=GET,POST
,则允许GET和POST请求:
- id: queryurl
uri: https://www.baidu.com
predicates:
# http://localhost:9004/?url=baidu 转发至 https://www.baidu.com
- Query=url,baidu
# Cookie 接收两个参数,cookie 名字和一个正则表达式。 判断请求cookie是否具有给定名称且值与正则表达式匹配。
- Cookie= username,admin.*
After:在时间之后进行转发,之前不转发。
Before:在时间之前的进行转发,之后不转发。
Between:即在时间分为之内的才进行转发。
- id: queayname
uri: https://www.baidu.com
predicates:
# http://localhost:9004/?url=baidu 转发至 https://www.baidu.com
- Query=name,zs.*
# 请求方法 GET、POST、 PUT、DELETE
- Method=GET,POST
# IP地址 判断请求主机地址是否在地址段中,将匹配192.168.1.1~192.168.1.254之间的IP地址 其中24为子网掩码255.255.255.0 172.30.0.105
# - RemoteAddr=192.168.1.1/24
# Cookie 接收两个参数,cookie 名字和一个正则表达式。 判断请求cookie是否具有给定名称且值与正则表达式匹配。
# - Cookie= username,admin.*
# 时间之前 不做转发
- After= 2021-08-01T00:00:00.000+08:00[Asia/Shanghai]
# 时间之后 不做转发
- Before=2021-08-03T14:03:00.789+08:00[Asia/Shanghai]
# 请求必须在设定是时间之内才能请求转发
- Between=2021-08-01T00:00:00.000+08:00[Asia/Shanghai],2021-08-03T14:03:00.789+08:00[Asia/Shanghai]
负载均衡中的权重,同一个组中URI进行负载均衡 语法: weight=组名,负载均衡权重,两个的路由的Path是一样的, 但是组名都是 orderGroup 其中80%被转发到order-one,20%被转发到 order-two。
一般用于多版本发布的时候。
- id: weight1
uri: ld://order-one
predicates:
-Path=/order/**
# 负载均衡中的权重,同一个组中URI进行负载均衡 语法: weight=组名,负载均衡权重
-Weight=orderGroup,8
filters:
- StripPrefix=1
-
- id: weight2
uri: ld://order-two
predicates:
-Path=/order/**
# 两个的路由的Path是一样的, 但是组名都是 orderGroup 其中80%被转发到order-one,20%被转发到 order-two
-Weight=orderGroup,2
filters:
- StripPrefix=1
这两个不知道怎么用:
Host:判断请求的Host是否满足匹配规则。
RemoteAddr:接收一个IP地址段,判断请求主机地址是否在地址段中。
-PrefixPath
:添加一个路径
filters:
- PrefixPath=/brand # 为请求路径添加前缀/brand
请求路径以 /
区分 一个/
代表一个路径
-StripPrefix
:去掉一个路径
filters:
- StripPrefix=1
server:
port: 9004
spring:
application:
# 应用名称
name: api-service
# profiles:
# 环境配置
# active: dev
cloud:
nacos:
discovery:
# 服务注册地址
server-addr: 127.0.0.1:8848
gateway:
httpclient: # 配置全局 http 超时
connect-timeout: 1000 #必须以毫秒为单位指定
response-timeout: 5s #必须指定为 java.time.Duration
globalcors: # 跨域配置
corsConfigurations:
'[/**]':
allowedHeaders: "*"
allowedOrigins: "*"
allowCredentials: true
allowedMethods:
- GET
- POST
- DELETE
- PUT
- OPTION
discovery:
locator:
#开启从注册中心动态创建路由的功能,网关自动映射处理逻辑:http://gatewayIP:gatewayPort/微服务名称/微服务请求地址
enabled: false # 把网关请求自动转发到微服务请求地址: http://微服务名称/微服务请求地址
lower-case-service-id: true #开启服务名称小写装换,Eureka 对服务名称默认大写管理
# ========以上配置就已经实现请求转发的功能了============
# 商业开发中,enable 一般不设置,使用默认值false ,避免不必要的自动转发规则
routes:
# 配置网关中的一个完整路由 包括 命名、地址、谓词集合(规则)、过滤器集合
# Spring系列配置文件中,可以直接使用字符串赋值的类型有哪些?
# 8种基本数据类型、包装类型、String、URI统一资源路径地址、Class、Resource资源文件位置:classpath:xx/*.xml
- id: queryuri
uri: https://www.qq.com/
predicates:
# http://localhost:9004/?uri=qq 转发至 https://www.qq.com
# http://localhost:9004/?uri=qq&url=baidu 也可以转发到 https://www.qq.com
# http://localhost:9004/?url=baidu&uri=qq 也可以转发到 https://www.qq.com
# 由此可见: 只要路径中有uri=qq 就可以匹配转发 ,且断言匹配是由上到下的
- Query=uri,qq
metadata: # 配置每条路由超时
response-timeout: 200 # 必须以毫秒为单位指定。
connect-timeout: 200 # 必须以毫秒为单位指定。
- id: queryurl
uri: https://www.baidu.com
predicates:
# http://localhost:9004/?url=baidu 转发至 https://www.baidu.com
- Query=url,baidu
# Cookie 接收两个参数,cookie 名字和一个正则表达式。 判断请求cookie是否具有给定名称且值与正则表达式匹配。
- Cookie= username,admin.*
- id: queayname
uri: https://www.baidu.com
predicates:
# http://localhost:9004/?url=baidu 转发至 https://www.baidu.com
- Query=name,zs.*
# 请求方法 GET、POST、 PUT、DELETE
- Method=GET,POST
# 时间之前 不做转发
- After= 2021-08-01T00:00:00.000+08:00[Asia/Shanghai]
# 时间之后 不做转发
# - Before=2021-08-03T14:03:00.789+08:00[Asia/Shanghai]
# 请求必须在设定是时间之内才能请求转发
# - Between=2021-08-01T00:00:00.000+08:00[Asia/Shanghai],2021-08-03T14:03:00.789+08:00[Asia/Shanghai]
- id: weight1
uri: ld://order-one
predicates:
- Path=/order/**
# 负载均衡中的权重,同一个组中URI进行负载均衡 语法: weight=组名,负载均衡权重
- Weight=orderGroup,8
filters:
- StripPrefix=1
- id: weight2
uri: ld://order-two
predicates:
- Path=/order/**
# 两个的路由的Path是一样的, 但是组名都是 orderGroup 其中80%被转发到order-one,20%被转发到 order-two
- Weight=orderGroup,2
filters:
- StripPrefix=1
- id: pathbaidu
uri: https://www.baidu.com
predicates:
# http://localhost:9004/bd/ 转发至 https://www.baidu.com
# 断言匹配到Path 转发 https://www.baidu.com/bd 去掉/bd路径
- Path=/bd/**
filters:
- StripPrefix=1
- id: header
uri: http://localhost:9000
predicates:
# http://localhost:9004/header/account/findAll 转发至 http://localhost:9000/account/findAll
# 路径匹配 header ,请求头中必须myheader:zhangsan 并去除 一个路径 header 才能成功转发
- Path=/header/**
- name: Header
args:
# key: value
header: myheader
regexp: zhangsan.*
filters:
- StripPrefix=1
# 账户服务
- id: account # 路由定义的命名 唯一即可
# uri: http://localhost:9000
uri: lb://springcloud-alibaba-account
# 当前路由定义对应的转发地址 lb:服务名称 使用LoadBalancerClient 实现负载均衡
#配置谓词集合 RoutePredicateFactory
predicates:
# 谓词名称是有套路的,是GatewayPredicate接口实现类的命名前缀 XxxRoutePredicateFactory
- Path=/account/**,/aaa/** #定义一个谓词 格式:谓词名字=参数 或者 name:名字 args:参数 所有以/account/开始的请求都将路由到uri http://springcloud-alibaba-account
# http://localhost:9004/account/account/findAll 转发到 http://localhost:9000/account/findAll
# 配置过滤集合
filters:
- StripPrefix=1 # 将请求中的第一个路径去掉 请求路径以/区分,一个/表示一个路径,如:/api/account 会变成/account
#- PrefixPath=/brand # 为请求路径添加前缀/brand
# 订单服务
- id: order
uri: lb://springcloud-alibaba-order
predicates:
- Path=/order/**
filters:
- StripPrefix=1
# 库存服务
- id: storage
uri: lb://springcloud-alibaba-storage
predicates:
- Path=/storage/**
filters:
- StripPrefix=1
SpringCloud微服务API网关Gateway的使用和配置(二)过滤器:
https://blog.csdn.net/DreamsArchitects/article/details/119351793
源码已上传码云:
https://gitee.com/L1692312138/spring-cloud-alibaba