一、监控
Actuator
是Spring Boot
提供的用来对应用系统进行监控的功能模块,借助于Actuator
开发者可以很方便地对应用系统某些监控指标进行查看、统计等。
Actuator
的核心是端点Endpoint
。
Endpoint
可以让我们监视应用程序并与其交互。Spring Boot
包含许多内置端点,并允许您添加自己的端点。
我们可以启用或禁用每个端点,启用或禁用端点控制是否创建端点并且其bean
存在于应用程序上下文中。 要进行远程访问,还必须通过JMX
或HTTP
公开端点。大多数端点HTTP
访问默认是关闭的。
二、开启Gateway的Actuator
2.1 引入Actuator依赖
在 gateway/pom.xml
新增以下内容:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency
2.2 启动监控端点
在gateway/src/main/resources/bootstrap.yml
中新增以下内容:
management.endpoint.gateway.enabled: true # default value
management.endpoints.web.exposure.include: gateway
开启监控端点,访问/actuator/gateway/*
与Spring Cloud Gateway
应用程序进行交互。
2.3 详细访问格式
Spring Cloud Gateway
监控端点(注意每个端点都有/actuator/gateway
基本路径):
ID | 方法 | 描述 |
---|---|---|
globalfilters | GET | 获取网关中定义(应用于所有路由)的全局过滤器列表。 |
routefilters | GET | 获取网关中定义(应用于路由)的GatewayFilterFactory 列表。 |
refresh | POST | 清除路由缓存。 |
routes | GET | 获取网关中定义的路由列表。 |
routes/{id} | GET | 获取指定路由的信息。 |
routes/{id} | POST | 向网关添加新的路由。 |
routes/{id} | DELETE | 从网关中删除指定路由。 |
2.3.1 获取路由明细
通过/actuator/gateway/routes
获取网关中定义的路由列表:
[{
"predicate": "Paths: [/provider/**], match trailing slash: true",
"route_id": "54c58c6b-de67-4381-a9de-5f39690a35c3",
"filters": ["[[StripPrefix parts = 1], order = 0]"],
"uri": "http://localhost:4000",
"order": 0
}, {
"predicate": "Paths: [/lb/**], match trailing slash: true",
"route_id": "36e46476-f309-473c-87c3-5f6a41f9b9a0",
"filters": ["[[StripPrefix parts = 1], order = 0]"],
"uri": "lb://nacos-discovery-http-provider",
"order": 0
}, {
"predicate": "Paths: [/csdn/**], match trailing slash: true",
"route_id": "ce24523b-50e8-468d-b581-cfbb063ab64b",
"filters": ["[[RewritePath /csdn/(?<remaining>.*) = '/${remaining}'], order = 0]"],
"uri": "https://blog.csdn.net:443",
"order": 0
}, {
"predicate": "Paths: [/provider/**], match trailing slash: true",
"route_id": "http-provider-route",
"filters": ["[[StripPrefix parts = 1], order = 1]"],
"uri": "http://localhost:4000",
"order": 0
}, {
"predicate": "(Paths: [/lb/**], match trailing slash: true && com.gm.demo.gateway.component.CustomRoutePredicateFactory$1@41a0a5ba)",
"route_id": "nacos-discovery-http-provider-route",
"filters": ["[[StripPrefix parts = 1], order = 1]"],
"uri": "lb://nacos-discovery-http-provider",
"order": 0
}, {
"predicate": "(XForwardedRemoteAddrRoutePredicateFactory$$Lambda$1155/0x000000080141f938 && Paths: [/proxy/**], match trailing slash: true)",
"route_id": "xforwarded_remoteaddr_route",
"filters": ["[[StripPrefix parts = 1], order = 1]", "[[RedirectTo 302 = http://baidu.com], order = 2]"],
"uri": "http://127.0.0.1:9999/",
"order": 0
}, {
"predicate": "Paths: [/rate/**], match trailing slash: true",
"route_id": "requestratelimiter_route",
"filters": ["[[StripPrefix parts = 1], order = 1]", "[com.gm.demo.gateway.filter.CustomRequestRateLimiterGatewayFilterFactory$$Lambda$1181/0x0000000801432860@6ee76969, order = 2]"],
"uri": "lb://nacos-discovery-http-provider",
"order": 0
}, {
"predicate": "Paths: [/day/**], match trailing slash: true",
"route_id": "day_requestratelimiter_route",
"filters": ["[[StripPrefix parts = 1], order = 1]", "[com.gm.demo.gateway.filter.DayRequestRateLimitGatewayFilterFactory$$Lambda$1182/0x0000000801432ac0@5c25c28d, order = 2]"],
"uri": "lb://nacos-discovery-http-provider",
"order": 0
}, {
"predicate": "Paths: [/delay/**], match trailing slash: true",
"metadata": {
"connect-timeout": 200,
"response-timeout": 200
},
"route_id": "per_route_timeouts",
"filters": ["[[StripPrefix parts = 1], order = 1]"],
"uri": "https://example.org:443",
"order": 0
}]
响应包含网关中定义的所有路由的详细信息。下表描述了响应的每个元素(每个都是一个路由)的结构:
名称 | 类型 | 描述 |
---|---|---|
route_id | String | 路由标识 |
predicate | Object | 路由断言 |
filters | Array | 应用于路由的GatewayFilterFactory 集合 |
order | Number | 路由顺序 |
默认情况下启用此功能。要禁用它,请设置以下属性:
spring.cloud.gateway.actuator.verbose.enabled: false
2.3.2 检索全局过滤器
通过/actuator/gateway/globalfilters
获取网关中定义(应用于所有路由)的全局过滤器列表:
{
"org.springframework.cloud.gateway.filter.NettyWriteResponseFilter@684a802a": -1,
"org.springframework.cloud.gateway.filter.AdaptCachedBodyGlobalFilter@3a589eed": -2147482648,
"org.springframework.cloud.gateway.filter.RouteToRequestUrlFilter@69d902f9": 10000,
"org.springframework.cloud.gateway.filter.ReactiveLoadBalancerClientFilter@10a064bd": 10150,
"org.springframework.cloud.gateway.filter.ForwardPathFilter@3ca3eba2": 0,
"org.springframework.cloud.gateway.filter.NettyRoutingFilter@2ff8d39b": 2147483647,
"org.springframework.cloud.gateway.filter.RemoveCachedBodyFilter@7b5c9412": -2147483648,
"org.springframework.cloud.gateway.filter.ForwardRoutingFilter@547052": 2147483647,
"org.springframework.cloud.gateway.filter.LoadBalancerServiceInstanceCookieFilter@2de7fe0e": 10151,
"org.springframework.cloud.gateway.filter.WebsocketRoutingFilter@23c00420": 2147483646,
"com.gm.demo.gateway.filter.ApiLoggingFilter@352e4b6d": 2147483647,
"org.springframework.cloud.gateway.filter.GatewayMetricsFilter@22f046b": 0
}
响应包含现有全局过滤器的详细信息。对于每个全局过滤器,都有过滤器对象的字符串表示和过滤器链中的相应顺序。
2.3.4 路由过滤器
通过/actuator/gateway/routefilters
获取网关中定义(应用于路由)的GatewayFilterFactory
列表:
{
"[DedupeResponseHeaderGatewayFilterFactory@336070ab configClass = DedupeResponseHeaderGatewayFilterFactory.Config]": null,
"[RequestRateLimiterGatewayFilterFactory@433b546f configClass = RequestRateLimiterGatewayFilterFactory.Config]": null,
"[RedirectToGatewayFilterFactory@3dec769 configClass = RedirectToGatewayFilterFactory.Config]": null,
"[RetryGatewayFilterFactory@3d405fe5 configClass = RetryGatewayFilterFactory.RetryConfig]": null,
"[PrefixPathGatewayFilterFactory@20a4cba7 configClass = PrefixPathGatewayFilterFactory.Config]": null,
"[RewriteResponseHeaderGatewayFilterFactory@19d9ba89 configClass = RewriteResponseHeaderGatewayFilterFactory.Config]": null,
"[AddRequestHeaderGatewayFilterFactory@2419a5db configClass = AbstractNameValueGatewayFilterFactory.NameValueConfig]": null,
"[RewritePathGatewayFilterFactory@9de1b85 configClass = RewritePathGatewayFilterFactory.Config]": null,
"[StripPrefixGatewayFilterFactory@3436d3d7 configClass = StripPrefixGatewayFilterFactory.Config]": null,
"[SetRequestHostHeaderGatewayFilterFactory@dbca149 configClass = SetRequestHostHeaderGatewayFilterFactory.Config]": null,
"[DayRequestRateLimitGatewayFilterFactory@7dc92a06 configClass = DayRequestRateLimitGatewayFilterFactory.Config]": null,
"[RewriteLocationResponseHeaderGatewayFilterFactory@484876a1 configClass = RewriteLocationResponseHeaderGatewayFilterFactory.Config]": null,
"[RequestSizeGatewayFilterFactory@2e47a71e configClass = RequestSizeGatewayFilterFactory.RequestSizeConfig]": null,
"[CacheRequestBodyGatewayFilterFactory@6be80629 configClass = CacheRequestBodyGatewayFilterFactory.Config]": null,
"[ModifyRequestBodyGatewayFilterFactory@383e6734 configClass = ModifyRequestBodyGatewayFilterFactory.Config]": null,
"[CustomRequestRateLimiterGatewayFilterFactory@2a73a64f configClass = RequestRateLimiterGatewayFilterFactory.Config]": null,
"[AddResponseHeaderGatewayFilterFactory@516037be configClass = AbstractNameValueGatewayFilterFactory.NameValueConfig]": null,
"[SetRequestHeaderGatewayFilterFactory@323c6f9c configClass = AbstractNameValueGatewayFilterFactory.NameValueConfig]": null,
"[SaveSessionGatewayFilterFactory@60ef30b1 configClass = Object]": null,
"[RemoveRequestHeaderGatewayFilterFactory@282c5075 configClass = AbstractGatewayFilterFactory.NameConfig]": null,
"[RemoveRequestParameterGatewayFilterFactory@2ed35f24 configClass = AbstractGatewayFilterFactory.NameConfig]": null,
"[ModifyResponseBodyGatewayFilterFactory@3be50b2c configClass = ModifyResponseBodyGatewayFilterFactory.Config]": null,
"[SecureHeadersGatewayFilterFactory@4b475742 configClass = SecureHeadersGatewayFilterFactory.Config]": null,
"[RequestHeaderToRequestUriGatewayFilterFactory@3f40568e configClass = AbstractGatewayFilterFactory.NameConfig]": null,
"[PreserveHostHeaderGatewayFilterFactory@10f10230 configClass = Object]": null,
"[SetStatusGatewayFilterFactory@20163008 configClass = SetStatusGatewayFilterFactory.Config]": null,
"[RemoveResponseHeaderGatewayFilterFactory@362b384c configClass = AbstractGatewayFilterFactory.NameConfig]": null,
"[SetResponseHeaderGatewayFilterFactory@68550d86 configClass = AbstractNameValueGatewayFilterFactory.NameValueConfig]": null,
"[MapRequestHeaderGatewayFilterFactory@52bb3dcd configClass = MapRequestHeaderGatewayFilterFactory.Config]": null,
"[SetPathGatewayFilterFactory@52c6e959 configClass = SetPathGatewayFilterFactory.Config]": null,
"[RequestHeaderSizeGatewayFilterFactory@37b470df configClass = RequestHeaderSizeGatewayFilterFactory.Config]": null,
"[AddRequestParameterGatewayFilterFactory@654db80b configClass = AbstractNameValueGatewayFilterFactory.NameValueConfig]": null
}
2.3.5 刷新路由缓存
要清除路由缓存,发出请求/actuator/gateway/refresh
。该请求返回 200
,但没有响应正文。
2.3.6 获取网关中定义的路由
通过/actuator/gateway/routes
获取网关中定义的路由列表:
[{
"predicate": "Paths: [/provider/**], match trailing slash: true",
"route_id": "54c58c6b-de67-4381-a9de-5f39690a35c3",
"filters": ["[[StripPrefix parts = 1], order = 0]"],
"uri": "http://localhost:4000",
"order": 0
}, {
"predicate": "Paths: [/lb/**], match trailing slash: true",
"route_id": "36e46476-f309-473c-87c3-5f6a41f9b9a0",
"filters": ["[[StripPrefix parts = 1], order = 0]"],
"uri": "lb://nacos-discovery-http-provider",
"order": 0
}, {
"predicate": "Paths: [/csdn/**], match trailing slash: true",
"route_id": "ce24523b-50e8-468d-b581-cfbb063ab64b",
"filters": ["[[RewritePath /csdn/(?<remaining>.*) = '/${remaining}'], order = 0]"],
"uri": "https://blog.csdn.net:443",
"order": 0
}, {
"predicate": "Paths: [/provider/**], match trailing slash: true",
"route_id": "http-provider-route",
"filters": ["[[StripPrefix parts = 1], order = 1]"],
"uri": "http://localhost:4000",
"order": 0
}, {
"predicate": "(Paths: [/lb/**], match trailing slash: true && com.gm.demo.gateway.component.CustomRoutePredicateFactory$1@3715ba94)",
"route_id": "nacos-discovery-http-provider-route",
"filters": ["[[StripPrefix parts = 1], order = 1]"],
"uri": "lb://nacos-discovery-http-provider",
"order": 0
}, {
"predicate": "(XForwardedRemoteAddrRoutePredicateFactory$$Lambda$1155/0x000000080141f938 && Paths: [/proxy/**], match trailing slash: true)",
"route_id": "xforwarded_remoteaddr_route",
"filters": ["[[StripPrefix parts = 1], order = 1]", "[[RedirectTo 302 = http://baidu.com], order = 2]"],
"uri": "http://127.0.0.1:9999/",
"order": 0
}, {
"predicate": "Paths: [/rate/**], match trailing slash: true",
"route_id": "requestratelimiter_route",
"filters": ["[[StripPrefix parts = 1], order = 1]", "[com.gm.demo.gateway.filter.CustomRequestRateLimiterGatewayFilterFactory$$Lambda$1181/0x0000000801432860@711c23ed, order = 2]"],
"uri": "lb://nacos-discovery-http-provider",
"order": 0
}, {
"predicate": "Paths: [/day/**], match trailing slash: true",
"route_id": "day_requestratelimiter_route",
"filters": ["[[StripPrefix parts = 1], order = 1]", "[com.gm.demo.gateway.filter.DayRequestRateLimitGatewayFilterFactory$$Lambda$1182/0x0000000801432ac0@58145bb, order = 2]"],
"uri": "lb://nacos-discovery-http-provider",
"order": 0
}, {
"predicate": "Paths: [/delay/**], match trailing slash: true",
"metadata": {
"connect-timeout": 200,
"response-timeout": 200
},
"route_id": "per_route_timeouts",
"filters": ["[[StripPrefix parts = 1], order = 1]"],
"uri": "https://example.org:443",
"order": 0
}]
2.3.6 获取指定路由信息
通过/gateway/routes/{id}
获取指定路由的信息:
{
"predicate": "Paths: [/provider/**], match trailing slash: true",
"route_id": "54c58c6b-de67-4381-a9de-5f39690a35c3",
"filters": ["[[StripPrefix parts = 1], order = 0]"],
"uri": "http://localhost:4000",
"order": 0
}
下表描述了响应结构:
名称 | 类型 | 描述 |
---|---|---|
route_id | String | 路由标识 |
predicate | Object | 路由断言 |
filters | Array | 应用于路由的GatewayFilterFactory 集合 |
order | Number | 路由顺序 |
2.3.7 创建路由
要创建路由需指定路由字段的 JSON
正文发出POST
请求,/gateway/routes/{id_route_to_create}
。
其中 JSON
正文内容请见2.3.6获取指定路由信息。
2.3.8 删除路由
通过/gateway/routes/{id_route_to_delete}
请DELETE
请求删除路由。
三、多网关实例路由共享
Spring Cloud Gateway
提供了两种RouteDefinitionRepository
实现。
第一个是 InMemoryRouteDefinitionRepository
仅存在于一个网关实例的内存中的。这种类型的存储库不适合跨多个网关实例路由共享。
为了在 Spring Cloud Gateway
实例集群之间共享路由,需要启动RedisRouteDefinitionRepository
存储库。
3.1 引入redis-reactive依赖
在 gateway/pom.xml
新增以下内容:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>
3.2 启用存储库
在gateway/src/main/resources/bootstrap.yml
中新增以下内容启用Redis
存储库:
spring.cloud.gateway.redis-route-definition-repository.enabled: true
通过配置文件配置的静态路由和 redis
动态路由同时存在时取并集。
需与监控端点配置使用。在下文具体描述。
3.3 测试步骤及效果
3.3.1 移除静态路由
删除配置文件中的静态路由配置
此步骤可省略
3.3.2 添加路由
通过监控端点添加路由,通过Postman
进行:
示例JSON
请求体:
{
"id": "baidu_route",
"predicates": [{
"name": "Path",
"args": {
"_genkey_0": "/baidu/**"
}
}],
"filters": [{
"name": "StripPrefix",
"args": {
"path": 1
}
}],
"uri": "https://www.baidu.com",
"order": 0
}
JSON
请求体格式最好是参照PredicateFactory
的Config
属性和GatewayFilterFactory
的Config
属性进行配置
请求成功后,新添加的路由并没有马上生效,需要等待路由刷新后才正式生效
3.3.3 查看redis
发现新添加的路由在存储在Redis
中,key
的命名规则是routedefinition_*
:
3.3.4 重启网关服务
重新进行访问,原持久化至Redis
被再次生效: