SpringCloudGateway搭建和常见使用方法
**Spring Cloud Gateway:**提供一种简单而有效的方式来对API进行路由,并为他们提供切面,例如:安全性,监控/指标 和弹性等。
温馨提示:在学习新技术之前建议先看看 官方文档
1.如何在工程中引用Spring Cloud Gateway
-
引入jar包
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency> <!-- SpringCloud Ailibaba Nacos --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <!-- SpringCloud Ailibaba Nacos Config --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </dependency> <!-- SpringBoot Actuator --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
-
配置注册中心地址
spring: application: name: dyzh-gateway cloud: nacos: discovery: enabled: true register-enabled: true server-addr: 127.0.0.1:8848
-
配置路由
- Route 路由:gateway的基本构建模块。它由ID、目标URI、断言集合和过滤器集合组成。如果聚合断言结果为真,则匹配到该路由。
-
Predicate 断言:这是一个Java 8 Function Predicate。输入类型是 Spring Framework
ServerWebExchange
。这允许开发人员可以匹配来自HTTP请求的任何内容,例如Header或参数。 -
Filter 过滤器:这些是使用特定工厂构建的 Spring Framework
GatewayFilter
实例。 。Spring cloud gateway中的filter分为两种类型的Filter,分别是Gateway Filter和Global Filter(全局)。过滤器Filter将会对请求和响应进行修改处理 所以可以在返回请求之前或之后修改请求和响应的内容。
spring: cloud: gateway: discovery: locator: # 注册中心自动发现 默认为 false enabled: false #手动配置路由 routes: #路由id,可以自定义设置 - id: dyzh-demo-service #目标URI, URI上的'lb`前缀,使用Spring Cloud Netflix Ribbon 客户端负载均衡。 uri: lb://dyzh-demo-service predicates: - Path=/sys/**
2.Actuator API
/gateway
的actuator端点允许监视Spring Cloud Gateway应用程序并与之交互。要进行远程访问,必须在应用程序属性中暴露HTTP或JMX 端口。
-
开启actuator
management: endpoint: gateway: # 默认为false enabled: true endpoints: web: exposure: include: gateway
-
下表列出了Spring Cloud Gateway执行器端点(请注意,每个端点都
/actuator/gateway
作为基本路径):
ID | HTTP Method | Description |
---|---|---|
globalfilters |
GET | Displays the list of global filters applied to the routes. |
routefilters |
GET | Displays the list of GatewayFilter factories applied to a particular route. |
refresh |
POST | Clears the routes cache. |
routes |
GET | Displays the list of routes defined in the gateway. |
routes/{id} |
GET | Displays information about a particular route. |
routes/{id} |
POST | Adds a new route to the gateway. |
routes/{id} |
DELETE | Removes an existing route from the gateway. |
1.检索所有的路由【 global filters 】
curl -X GET http://localhost:your-port/actuator/gateway/globalfilters
返回结果如下:
{
"oraaa@qq.com195113de": -1,
"aaa@qq.come689": 2147483647,
"aaa@qq.comfeb6b0": 0,
"org.saaa@qq.com3e900e1a": -2147482648,
"aaa@qq.com9": 0,
"aaa@qq.com3ebc955b": -2147483648,
"aaa@qq.com5aa781f2": 2147483646,
"oraaa@qq.com25974207": 10100,
"oaaa@qq.com21a46ff1": 10000,
"aaa@qq.comb5f4e2": 2147483647
}
返回结果包含已就绪的global filters的详细信息(如 oraaa@qq.com25974207。对于每个global filters,返回结果字符串对应过滤器链中的相应顺序。
2.检索所有的路由【 global filters 】
curl -X GET http://localhost:9001/actuator/gateway/routefilters
返回结果如下:
{
"[aaa@qq.com configClass = RequestSizeGatewayFilterFactory.RequestSizeConfig]": null,
"[aaa@qq.com configClass = AbstractNameValueGatewayFilterFactory.NameValueConfig]": null,
"[aaa@qq.com configClass = RedirectToGatewayFilterFactory.Config]": null,
"[aaa@qq.com configClass = RewritePathGatewayFilterFactory.Config]": null,
"[aaa@qq.com configClass = RetryGatewayFilterFactory.RetryConfig]": null,
"[aaa@qq.com configClass = AbstractGatewayFilterFactory.NameConfig]": null,
"[aaa@qq.com configClass = StripPrefixGatewayFilterFactory.Config]": null,
"[aaa@qq.com configClass = RequestHeaderSizeGatewayFilterFactory.Config]": null,
"[aaa@qq.com configClass = AbstractNameValueGatewayFilterFactory.NameValueConfig]": null,
"[aaa@qq.com configClass = AbstractGatewayFilterFactory.NameConfig]": null,
"[aaa@qq.com configClass = SetStatusGatewayFilterFactory.Config]": null,
"[aaa@qq.com configClass = ModifyRequestBodyGatewayFilterFactory.Config]": null,
"[aaa@qq.com configClass = AbstractNameValueGatewayFilterFactory.NameValueConfig]": null,
"[aaa@qq.com configClass = AbstractNameValueGatewayFilterFactory.NameValueConfig]": null,
"[aaa@qq.com configClass = RewriteLocationResponseHeaderGatewayFilterFactory.Config]": null,
"[aaa@qq.com configClass = DedupeResponseHeaderGatewayFilterFactory.Config]": null,
"[aaa@qq.com configClass = Object]": null,
"[aaa@qq.com configClass = AbstractGatewayFilterFactory.NameConfig]": null,
"[aaa@qq.com configClass = Object]": null,
"[aaa@qq.com configClass = AbstractNameValueGatewayFilterFactory.NameValueConfig]": null,
"[aaa@qq.com configClass = SetPathGatewayFilterFactory.Config]": null,
"[aaa@qq.com configClass = AbstractGatewayFilterFactory.NameConfig]": null,
"[aaa@qq.com configClass = RewriteResponseHeaderGatewayFilterFactory.Config]": null,
"[aaa@qq.com configClass = MapRequestHeaderGatewayFilterFactory.Config]": null,
"[aaa@qq.com configClass = ModifyResponseBodyGatewayFilterFactory.Config]": null,
"[aaa@qq.com configClass = PrefixPathGatewayFilterFactory.Config]": null,
"[aaa@qq.com configClass = Object]": null
}
返回结果包含应用于所有路由的GatewayFilter的详细信息。显示每个工厂提供字符串格式的相应对象(例如, [aaa@qq.com configClass = Object])。请注意,
null
值是由于endpoint controller实现不完整造成的,因为它尝试在filter chain中设置对象的顺序,这不适用于GatewayFilter工厂对象。
3.清除路由的缓存
curl -X POST http://localhost:9001/actuator/gateway/refresh
没有返回值,只有200的状态码
4.检测网关中定义的路由
curl -X GET http://localhost:9001/actuator/gateway/routes
返回结果如下
[
{
"predicate": "Paths: [/sys/**], match trailing slash: true",
"route_id": "dyzh-demo-service",
"filters": [],
"uri": "lb://dyzh-demo-service",
"order": 0
}
]
结果中包含网关中所有定义的路由信息
Path | Type | Description |
---|---|---|
id |
String | The route ID. |
predicates |
Array | The collection of route predicates. Each item defines the name and the arguments of a given predicate. |
filters |
Array | The collection of filters applied to the route. |
uri |
String | The destination URI of the route. |
order |
Number | The route order. |
5.获取单个路由信息
curl -X GET http://localhost:9001/actuator/gateway/routes/{id}
返回结果如下:
{
"predicate": "Paths: [/sys/**], match trailing slash: true",
"route_id": "dyzh-demo-service",
"filters": [],
"uri": "lb://dyzh-demo-service",
"order": 0
}
6. 创建一个路由
curl -X POST
http://localhost:9001/actuator/gateway/routes/test
-H ‘Content-Type: application/json’
-d ‘{
“id”:“dyzh-back-server”,
“uri”:“lb//dyzh-back-server”
}’
请求成功返回201的状态码
7.删除一个路由
curl -X DELETE http://localhost:9001/actuator/gateway/routes/dyzh-demo-service
3.跨域拦截
spring:
cloud:
gateway:
globalcors:
corsConfigurations:
'[/**]':
allowedOrigins: "https://domain"
allowedMethods:
- GET
allowHeaders:
- Content-Type
4.过滤器 GateWayFilter
Spring Cloud Gateway的filte只有两个:“pre”和“post”:
-
pre:这种过滤器在请求被路由之前调用。可以利用这个过滤器实现身份验证、在集群中选择请求的微服务、记录调试的信息。
-
post:这种过滤器在路由到服务器之后执行。这种过滤器可用来为响应添加HTTP Header、统计信息和指标、响应从微服务发送给客户端等。
Spring Cloud gateway的filter分为两种:GatewayFilter和Globalfilter。GlobalFilter会应用到所有的路由上,而Gatewayfilter将应用到单个路由或者一个分组的路由上。
如果要自定义一个GatewayFilter,需要实现GatewayFilterFactory
。下面是一个你需要集成的抽象类 AbstractGatewayFilterFactory
。
PreGatewayFilterFactory.java.
public class PreGatewayFilterFactory extends AbstractGatewayFilterFactory<PreGatewayFilterFactory.Config> {
public PreGatewayFilterFactory() {
super(Config.class);
}
@Override
public GatewayFilter apply(Config config) {
// grab configuration from Config object
return (exchange, chain) -> {
//If you want to build a "pre" filter you need to manipulate the
//request before calling chain.filter
ServerHttpRequest.Builder builder = exchange.getRequest().mutate();
//use builder to manipulate the request
return chain.filter(exchange.mutate().request(request).build());
};
}
public static class Config {
//Put the configuration properties for your filter here
}
}
PostGatewayFilterFactory.java.
public class PostGatewayFilterFactory extends AbstractGatewayFilterFactory<PostGatewayFilterFactory.Config> {
public PostGatewayFilterFactory() {
super(Config.class);
}
@Override
public GatewayFilter apply(Config config) {
// grab configuration from Config object
return (exchange, chain) -> {
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
ServerHttpResponse response = exchange.getResponse();
//Manipulate the response in some way
}));
};
}
public static class Config {
//Put the configuration properties for your filter here
}
}
5.全局过滤器 GlobalFilter
Spring Cloud Gateway根据作用范围分为GatewayFilter和GlobalFilter,二者区别如下:
GatewayFilter : 需要通过spring.cloud.routes.filters 配置在具体路由下,只作用在当前路由上或通过spring.cloud.default-filters配置在全局,作用在所有路由上。
当请求与路由匹配时,过滤Web处理程序会将的所有实例GlobalFilter
和所有特定GatewayFilter
于路由的实例添加到过滤器链中。该组合的过滤器链按org.springframework.core.Ordered
接口排序,您可以通过实现该getOrder()
方法进行设置。
ExampleConfiguration.java
@Bean
public GlobalFilter customFilter() {
return new CustomGlobalFilter();
}
public class CustomGlobalFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
log.info("custom global filter");
return chain.filter(exchange);
}
@Override
public int getOrder() {
return -1;
}
}
6.http超时配置
connect-timeout必须以毫秒为单位指定。 response-timeout
必须指定为java.time.Duration
- 全局http超时示例
spring:
cloud:
gateway:
httpclient:
connect-timeout: 1000
response-timeout: 5s
- 要配置每个路由超时:
connect-timeout
必须以毫秒为单位指定。response-timeout
必须以毫秒为单位指定
- id: per_route_timeouts
uri: https://example.org
predicates:
- name: Path
args:
pattern: /delay/{timeout}
metadata:
response-timeout: 200
connect-timeout: 200
欢迎大家关注我的微信公众号共同学习进步: