需求
我们使用spring cloud gateway搭建一个最简单的微服务通用访问网关(General Purpose Server-side API gateway)。
需求整理如下:
- 所有资源服务通过consul agent注册到consul server,springcloud gateway直接根据service name做应用上下文转发。
- 安全认证中心在gateway后面,springcloud gateway直接将token传递到resource server,由resource server自行做认证。
部署逻辑图如下:
配置
配置pom.xml
新建springboot工程,引入以下依赖:
<!-- spring cloud gateway 只需要引入这个包够了 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!-- 我们要使用consul的服务发现 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
<!-- 我们要使用ribbon的做负载均衡 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
配置application.properties
server.port=80
spring.application.name=gateway
#开启基于服务发现的路由转发规则
spring.cloud.gateway.discovery.locator.enabled=true
#配置服务注册与发现
spring.cloud.consul.host=localhost
spring.cloud.consul.port=8500
spring.cloud.consul.discovery.heartbeat.enabled=true
#开启应用监控治理端点
management.endpoint.gateway.enabled=true
#暴露端点
management.endpoints.web.exposure.include=gateway,info,health,loggers,mappings
至此我们就可以完整的使用spring cloud gateway了。
开发运维工具
网关服务作为应用的关键入口,我们希望它尽量稳定,我们后端服务变更或者系统配置变更时能够不用重启就可以获知变化。spring cloud gateway通过Actuator提供了响应的能力。
actuator
Actuator本身提供了很多信息查询服务,比如/info, /health, /loggers,/mappings等。
查看所有地址映射
“/actuator/mappings”提供了查看所有web 端点的能力,在我们不清楚网关代理了哪些接口时,先看看这个。
每个mapping有如下内容:
gateway actuator
spring cloud gateway通过GatewayControllerEndpoint增加了网关特有的端点。
ID | HTTP Method | Description |
---|---|---|
globalfilters | GET | 展示所有全局过滤器 |
routefilters | GET | 展示GatewayFilter factories |
refresh | POST | 清理Route缓存 |
routes | GET | 展示所有路由规则定义 |
routes/{id} | GET | 展示特定Route的定义 |
routes/{id} | POST | 添加一个新的Route定义 |
routes/{id} | DELETE | 删除一个路由定义 |
调用/actuator/gateway/globalfilters我们看到:
{
"org.springframework.cloud.gateway.filter.GatewayMetricsFilter@6221b13b": 0,
"org.springframework.cloud.gateway.filter.WebsocketRoutingFilter@e91af20": 2147483646,
"org.springframework.cloud.gateway.filter.NettyWriteResponseFilter@8c12524": -1,
"org.springframework.cloud.gateway.filter.NettyRoutingFilter@72557746": 2147483647,
"org.springframework.cloud.gateway.filter.ForwardRoutingFilter@11f23203": 2147483647,
"org.springframework.cloud.gateway.filter.ForwardPathFilter@101bdd1c": 0,
"org.springframework.cloud.gateway.filter.RouteToRequestUrlFilter@4844930a": 10000,
"org.springframework.cloud.gateway.filter.AdaptCachedBodyGlobalFilter@10a18e3e": -2147482648,
"org.springframework.cloud.gateway.filter.RemoveCachedBodyFilter@f723cdb": -2147483648,
"org.springframework.cloud.gateway.filter.LoadBalancerClientFilter@118acf70": 10100
}
调用/actuator/gateway/routefilters我们看到:
{
"[RequestHeaderToRequestUriGatewayFilterFactory@16bd7ae1 configClass = AbstractGatewayFilterFactory.NameConfig]": null,
"[ModifyRequestBodyGatewayFilterFactory@7a31ca20 configClass = ModifyRequestBodyGatewayFilterFactory.Config]": null,
"[PrefixPathGatewayFilterFactory@de579ff configClass = PrefixPathGatewayFilterFactory.Config]": null,
"[SetPathGatewayFilterFactory@4d518c66 configClass = SetPathGatewayFilterFactory.Config]": null,
"[StripPrefixGatewayFilterFactory@797fcf9 configClass = StripPrefixGatewayFilterFactory.Config]": null,
"[RetryGatewayFilterFactory@26be9a6 configClass = RetryGatewayFilterFactory.RetryConfig]": null,
"[SetStatusGatewayFilterFactory@5b0dbfb configClass = SetStatusGatewayFilterFactory.Config]": null,
"[SaveSessionGatewayFilterFactory@4b9dbf07 configClass = Object]": null,
"[RemoveResponseHeaderGatewayFilterFactory@46394f65 configClass = AbstractGatewayFilterFactory.NameConfig]": null,
"[RedirectToGatewayFilterFactory@2fd39436 configClass = RedirectToGatewayFilterFactory.Config]": null,
"[SecureHeadersGatewayFilterFactory@411fa0ce configClass = Object]": null,
"[AddRequestParameterGatewayFilterFactory@689faf79 configClass = AbstractNameValueGatewayFilterFactory.NameValueConfig]": null,
"[ModifyResponseBodyGatewayFilterFactory@21edd891 configClass = ModifyResponseBodyGatewayFilterFactory.Config]": null,
"[AddResponseHeaderGatewayFilterFactory@582e9152 configClass = AbstractNameValueGatewayFilterFactory.NameValueConfig]": null,
"[DedupeResponseHeaderGatewayFilterFactory@349c4d1c configClass = DedupeResponseHeaderGatewayFilterFactory.Config]": null,
"[AddRequestHeaderGatewayFilterFactory@357f6391 configClass = AbstractNameValueGatewayFilterFactory.NameValueConfig]": null,
"[RemoveRequestHeaderGatewayFilterFactory@60b5e80d configClass = AbstractGatewayFilterFactory.NameConfig]": null,
"[SetResponseHeaderGatewayFilterFactory@78e68401 configClass = AbstractNameValueGatewayFilterFactory.NameValueConfig]": null,
"[RewritePathGatewayFilterFactory@31aab981 configClass = RewritePathGatewayFilterFactory.Config]": null,
"[PreserveHostHeaderGatewayFilterFactory@7971c2a9 configClass = Object]": null,
"[SetRequestHeaderGatewayFilterFactory@251d7fdd configClass = AbstractNameValueGatewayFilterFactory.NameValueConfig]": null,
"[RewriteResponseHeaderGatewayFilterFactory@391515c7 configClass = RewriteResponseHeaderGatewayFilterFactory.Config]": null,
"[RequestSizeGatewayFilterFactory@15d114ce configClass = RequestSizeGatewayFilterFactory.RequestSizeConfig]": null
}
在生产实时调整日志级别
生产上我们通常会禁止debug日志,但有时需要网关上分析定位问题。这时我们可以打开访问日志。
以下日志对我们分析问题有帮助:
org.springframework.cloud.gateway //输出路由转发规则
org.springframework.http.server.reactive
org.springframework.web.reactive
org.springframework.boot.autoconfigure.web
reactor.netty //输出网络请求响应记录
redisratelimiter
可以通过/actuator/loggers地址获得所有日志名称和日志级别,然后通过以下http指令调整日志级别:
$ curl 'http://localhost:8080/actuator/loggers/reactor.netty' -i -X POST \
-H 'Content-Type: application/json' \
-d '{"configuredLevel":"debug"}'
打开后一定要记得关闭:
$ curl 'http://localhost:8080/actuator/loggers/reactor.netty' -i -X POST \
-H 'Content-Type: application/json' \
-d '{}'
从Greenwich SR3开始可以针对Netty HttpClient和HttpServer启用wiretap。通过以下配置,然后将将reator .netty日志级别设置为DEBUG或TRACE相结合时,将启用对通过网络发送和接收的头和主体等信息的日志记录。
spring.cloud.gateway.httpserver.wiretap=true
spring.cloud.gateway.httpclient.wiretap=true
参考
Spring boot 2.0 Actuator 的健康检查:https://www.jianshu.com/p/1aadc4c85f51
Spring Cloud Gateway官方文档:https://cloud.spring.io/spring-cloud-gateway/reference/html/
Spring Cloud Gateway入门: http://blueskykong.com/2018/03/10/cloud-Gateway-1/