首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

微服务网关终结者?Spring Cloud推出新成员Spring Cloud Gateway

导语:Spring Cloud Gateway基于Spring Boot 2,该项目提供了一个构建在Spring 生态之上的 API 网关。Spring Cloud Gateway旨在提供一种简单而有效的途径来发送API。

当传统的服务(例如数据库、消息队列、搜索引擎)在Cloud Foundry生态系统中广泛的应用和交易,有两种你可能不知道的服务发现方式。卷(Volume)服务[1]允许你做一个持久挂载的系统到你的应用。路由服务[2]允许拦截到你应用的所有HTTP流量。

路由服务

路由服务可以被用于很多目的,例如日志、限流、认证,从而做到应用无感知。

首先,让我们了解一下路由服务的工作原理。当路由服务绑定到应用,路由器将拦截到应用的所有请求,添加一些HTTP头以及保证请求完整性的签名,并将请求路由到对应服务(或者修改URL,或者仅仅返回一个错误的响应)。路由服务能做的事情请查看路由服务文档。

简单日志服务

这一节,我们学习如何使用Spring Cloud团队推出的API网关Spring Cloud Gateway构建一个简单的路由服务。这是一个简单的服务,它仅仅在日志中记录请求的详细信息,然后将请求转发到目标地址(类似路由服务文档中的Spring Boot实例[3])。

创建项目

首先,创建一个新的Spring项目。你必须保证使用Spring Boot 2.x版本(当前最新版本2.0.0 RC1),并且包含Gateway和Reactive Web的依赖。在这个例子中,我根据自己的偏爱使用Gradle,当然你也可以使用Maven。

路由谓词

接下来,我们需要设置网关路由,用于处理请求。如路由服务文档在Headers部分提到的,这里有3个header用于标识一个路由服务请求:

X-CF-Forwarded-Url:请求的目标URL

X-CF-Proxy-Signatur:验证请求用的token

X-CF-Proxy-Metadata:解析和验证X-CF-Proxy-Signature的帮助信息

上面这个Spring Cloud Gateway路由服务围绕谓词构建。在这个例子中,有3个基于Predicate的简单Header。如果一个请求,这3个谓词全都匹配,那我们转发该请求到http://google.com:80(很明显真实的场景不能这么做,后面我们将使用filter更新目标地址)。我们使用./gradlew bootRun命令启动服务,并且使用http客户端验证服务是否正常工作。

如你所见,路由服务处理了这3个Header,并且如我们所期待的将请求转发到google了(google返回了301作为响应)。

日志Filter

接下来,我们构建一个简单的Filter,用于记录进来的请求的一些信息。

最后调用chain.filter(exchange),表明这个Filter已经处理完成,并且将请求传给Filter链中的下一个Filter进行处理,或者如果这是链中最后一个Filter,则对请求放行。接下来,我们需要确保当路由服务处理请求时会调用Filter。

如你所见,我们使用filters()方法增加了日志过滤器。f是GatewayFilterSpec[4]类的实例,包含了常用filters的简便方法,例如添加Header、转发,或者开启Hystrix[5]。

如果我们使用HTTP客户端再次测试,我们将看到我们日志中的详细信息:

转发到目标URL

最后,我们需要确保请求被转发到了目标URI,而不是google。我们能使用另外的Filter完成这个目的。

这个值从X-CF-Forwarded-Url中获取,并且存储在Spring Cloud Gateway的特殊属性中,用于发送最终的请求。如果产生了异常,网关将停止处理请求,并且返回一个500。注意,和其他类型的路由服务一样,这是用于拒绝请求的通用模式。如果你需要拒绝请求,你可以仅仅返回500状态码,同时停止处理请求。

现在,在路由中写一个新的Filter:

ROUTE_TO_URL_FILTER_ORDER是一个常量,表明RouteToRequestUrlFilter类型的Filter在运行。我们需要确保我们前面定义的Filter 在它之后运行,这样我们的GATEWAY_REQUEST_URL_ATTR就不会被覆盖。另外,你可能要注意,我们从f.add换成了f.filter。这是因为当前版本的Spring Cloud Gateway不允许通过add方法进行设置。

我们通过HTTP客户端再验证一次:

注意,我们通过X-CF-Forwarded-Url的Header属性使用reddit替换掉了google。

部署

到这里,路由服务就可以部署了。你应该构建应用(Gradle用户使用./gradlew build命令),参照路由服务文档中的教程[6]部署。

总结

Spring Cloud Gateway刚出来不是很久,但是对于那些想在Cloud Foundry应用前面做一层处理的Java开发者来说,是非常有用的选择。如果你想看简单路由服务的最终源代码,在这里[7]。另外,有必要看看Spring Gloud Gateway的文档,包含了很多当前教程没有提到的有用的谓词和Filter。

文中链接

[1] https://docs.cloudfoundry.org/devguide/services/using-vol-services.html

[2] https://docs.cloudfoundry.org/services/route-services.html

[3] https://github.com/nebhale/route-service-example

[4] https://github.com/spring-cloud/spring-cloud-gateway/blob/v2.0.0.M6/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/route/builder/GatewayFilterSpec.java

[5] https://github.com/Netflix/Hystrix

[6] https://docs.cloudfoundry.org/services/route-services.html#tutorial

[7] https://github.com/Fitzoh/simple-gateway-route-service

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180725B0B8E100?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券