KOCA版本 :3.x
KOCA模块 :微服务网关
模块版本 :3.x
场景 :使用koca网关,连接至注册中心,子系统有context-path
问题 :直接使用/service-id/**的方式访问网关会报404
报错细节 :
尝试解决方案:当请求中带上context-path时,可以正常请求,如下图
KOCA版本 :3.x
KOCA模块 :微服务网关
模块版本 :3.x
场景 :使用koca网关,连接至注册中心,子系统有context-path
问题 :直接使用/service-id/**的方式访问网关会报404
报错细节 :
尝试解决方案:当请求中带上context-path时,可以正常请求,如下图
这里我们先捋一下其中的几样东西。
第一,服务名,这个子服务的名称为admin
第二,子服务的context-path,这里也叫admin,更严谨一点应该是/admin
然后我们看一下配置文件,koca提供的bootapp中,一般都会有如下配置
spring:
application:
name: gateway
cloud:
gateway:
discovery:
locator:
enabled: true # 开启默认的服务路由
关键就在这里的服务发现配置。我们看一下这个配置的官方文档,koca文档中有一个中文的文档,我们从其中截取一段如下:
12.4. DiscoveryClient 路由定义定位器
您可以配置网关创建基于与DiscoveryClient
服务注册兼容的服务路由。
要启用此功能,请设置spring.cloud.gateway.discovery.locator.enabled=true
,并确保>DiscoveryClient
实现(如 Netflix Eureka、Consul 或 Zookeeper)在类路径上并已启用。
12.4.1. 为 DiscoveryClient 路由配置断言和过滤器
默认情况下,网关为通过DiscoveryClient
创建的路由定义单个断言和过滤器。
默认断言是使用 Ant 匹配/serviceId/**
定义的 Path 断言,其中serviceId
是DiscoveryClient
中服务的 ID。
缺省过滤器是带有正则表达式/serviceId/(?<remaining>.*)
和替换文本/${remaining}
的 ReWritePath 过滤器。这将请求发送到下游之前从路径中剥离服务 ID。
关键就在最后一句,开启时,这个默认的路由会剥离服务ID。并且这个默认的断言,会覆盖yml中配置的同名断言。
我们回到最初的问题。当不经过网关时,请求到后台的的路径,应该是context-path + /**
。那么经过网关时,就应该在此路径之前再加上一个服务ID,变成/service-id + context-path + /**
。
然后我们带入实际场景,就用上图的例子吧。
服务ID为admin,context-path为/admin,那么请求网关时的路径,就变成:/admin/admin/**
由于服务ID和context-path是一样的,因此这请求虽然看起来很奇怪,但是是符合配置说明的。
那么有没有什么办法,可以避免出现这种很奇怪的路径呢?
下面提供几种方式:
spring.cloud.gateway.discovery.locator.enabled=false
,从而使用用户定义的路由配置。