
本文共 2873 字,大约阅读时间需要 9 分钟。
Spring Cloud Gateway作为取代zuul的新一代网关出来已经有一段时间了。一直没有尝试使用过,最近在使用Spring反应式微服务就尝试了一把,遇到了一些坑,写一些文字记录一下。
主要是写一下在Spring Cloud Gateway和服务发现整合的过程中遇到的一些坑。
Spring Cloud Gateway和服务发现整合在网上也有很多博客有介绍。笔者刚开始想的Spring Cloud Gateway出来这么久了,跟着网上的随便一个博客就应该可以轻松整合成功。刚开始也确实是这样,但是发现自己有一些额外的需求没有满足时,让人抓头的事情就发生了。
Spring Cloud Gateway和服务发现的整合方式有两种,一种是Spring自动帮我们完成,一种是我们自己手动的去设置。
自动的方式
直接委托给Spring,让Spring自动帮我们创建Route,这种方式很简单,只需要一个配置就可以。配置方式如下:
spring: cloud: gateway: discovery: locator: enabled: true
这样,Spring就会自动的帮我们创建在服务发现中注册服务的Route。比如我有两个服务account-service,gateway-service,那么Spring就会创建对应的这两个服务的Route。其实刚接触网关的时候都会有一个困惑,我要通过什么样的url才能通过访问网关再转发到目的服务。特别是自己手动跟着网上博客配置的时候。在上面的自动配置的方式,目的服务的地址是{网关ip:网关端口号/目的服务id/对应的服务下的路由。
例子
在account-service下有一个/test/save api,gateway的ip和端口号为localhost:9529,那我们可以通过localhost:9529/account-service/test/save访问通过网关访问account-service下的/test/save api了。
手动的方式
我们可以看到自动的方式很方便,也很简单。当有先的服务注册的时候也不用修改网关,网关会每隔一段时间从注册中心拉取信息创建Route。但是,自动的坏处就是不灵活,什么东西都是Spring配置好了。比如有同学会觉得localhost:9529/account-service/test/save太长了,他想通过localhost:9529/account/test/save进行访问,但是他不想去改服务的id。当然在实际的业务中可能还有更多的需求,比如加统一的前缀,不想暴露服务id到前端等等。
这个时候手动的设置方式就派上用场了,它可以灵活的自己进行各种配置。但是我们手动的设置方式可以取代自动的吗?手动的会使用注册中心的服务的?回答是可以的。
使用如下的方式进行配置就可以做到了:
spring: cloud: gateway: discovery: locator: enabled: false lower-case-service-id: false routes: - id: account-route ##lb://服务id uri: lb://account-service ##拦截的地址 predicates: - Path=/account/**
上面的配置主要做了两件事情:
-
关闭了spring自动创建注册中心服务Route的开关
-
创建了一个叫account-route的路由。lb:account-service表示它从注册中心访问服务,predicates的Path表明它拦截处理的url。
这样我们应该就可以通过localhost:9529/account/test/save访问我们的服务了。如果不关闭自动创建的开关,那就还是可以通过原来的localhost:9529/account-service/test/save访问到服务。
经过一顿操作之后,你的服务可能返回:
{ "timestamp": "2021-02-21 23:53:47", "path": "/accunt/test/save", "status": 404, "error": "Not Found", "message": "", "requestId": "1ca7dec3-4"}
使用新的技术不怕遇到错误,关键是这遇到的这个错日志也没有打印什么有用的信息出来。日志的级别也设置了,没用。
logging: level: org.springframework.cloud.gateway: debug
。。。。一大段时间过去了,头发也掉了不少,终于找到了原因。
在打印出来的日志中,发现了一个叫ForwardRoutingFilter的filter,对它进行断点发现,它最后进行访问的是localhost:9527/account/test/save(9527是account-service的端口号,正确的访问地址应该是localhost:9527/test/save,没有account)。也就是说我们手动设置的方式,Spring Gateway并没有去掉/account,所以需要我们自己做这个操作。
spring: cloud: gateway: discovery: locator: enabled: false lower-case-service-id: false routes: - id: account-route ##lb://服务id uri: lb://account-service ##拦截的地址 predicates: - Path=/account/**filters: - StripPrefix=1
注意新加上的StripPrefix,它就是用来做这个事情的。
Sping Cloud Gateway和服务发现的整合简单的介绍了一下,中间遇到的坑也进行了说明。总结下来是自己对Spring Cloud Gateway的了解还不够,对于一些配置都还不是很清楚。通过解决一些坑也渐渐的熟悉了起来,Spring Cloud Gateway还有很多其他功能可以很方便的解决我们的问题,后面还需要多学习。
感谢阅读,希望对你有帮助。
参考资料
Spring Cloud Gateway官方文档
发表评论
最新留言
关于作者
