如果在 API 端点路由中传递@RequestParam,Istio 虚拟服务会返回 404
Istio Virtual Service gives 404 if passed @RequestParam in API end points routing
我想通过 Istio 虚拟服务路由到我的微服务。当我在前缀中使用基于 @RequestParam
的输入时,甚至在精确输入时,它会为 /api/cities/{city_id}/tours
抛出 404
,但其余的工作正常。
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: app
namespace: nsapp
spec:
gateways:
- app-gateway
hosts:
- app.*.*.*
http:
- match:
- uri:
prefix: "/api/cities/{city_id}/tours"
- uri:
prefix: "/api/countries/{country_id}/cities"
- uri:
prefix: "/api/countries"
route:
- destination:
host: appservice
port:
number: 9090
前缀匹配匹配文字字符串。
/api/countries
也匹配您打算与 /api/countries/{country_id}/cities
匹配的内容
/api/cities/{city_id}/tours
但是,不起作用。
对于更复杂的匹配,您可以使用精确匹配和正则表达式,如 VirtualService
文档中所述。
也许是这样的(未经测试):
exact: "/api/countries"
regex: "/api/countries/[^/]*/cities"
这个片段
- uri:
prefix: "/api/cities/{city_id}/tours"
- uri:
prefix: "/api/countries/{country_id}/cities"
会按字面意思理解。 {city_id}
和 {country_id}
不会替换为您的自定义 ID。此时,istio 将查找字面意思为 /api/cities/{city_id}/tours
或 /api/countries/{country_id}/cities
的前缀,该前缀不存在(您会收到错误 404)。如果要将表达式与自定义 ID 匹配,则必须使用正则表达式。看看this doc. There you will find information about the capabilities of the StringMatch: exact
, prefix
or regex
. You can find the syntax of the regular expressions used in istio here.
总结:
您应该将 prefix
更改为 regex
,然后创建您自己的正则表达式以匹配您的自定义 ID。示例:
- uri:
regex: "/api/cities/[a-zA-Z]+/tours"
- uri:
regex: "/api/countries/[a-zA-Z]+/cities"
在我的示例中,ID 中只有字母(大写或小写)。在这里,您必须根据 this documentation.
创建自己的正则表达式
方法一:-
我尝试了以下方法并发现它可以工作,添加了我测试过并且正在工作的解决方案。基本上,执行的步骤是:-
删除前缀:“/api/countries/{country_id}/cities” 因为 /api/countries/ 是 2 个 API 的通用字符串,最终,它能够路由到原始应用服务主机上的 API 分别与 /api/cities.
相同
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: app
namespace: nsapp
spec:
gateways:
- app-gateway
hosts:
- app.*.*.*
http:
- match:
- uri:
prefix: "/api/cities"
- uri:
prefix: "/api/countries"
route:
- destination:
host: appservice
port:
number: 9090
我想通过 Istio 虚拟服务路由到我的微服务。当我在前缀中使用基于 @RequestParam
的输入时,甚至在精确输入时,它会为 /api/cities/{city_id}/tours
抛出 404
,但其余的工作正常。
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: app
namespace: nsapp
spec:
gateways:
- app-gateway
hosts:
- app.*.*.*
http:
- match:
- uri:
prefix: "/api/cities/{city_id}/tours"
- uri:
prefix: "/api/countries/{country_id}/cities"
- uri:
prefix: "/api/countries"
route:
- destination:
host: appservice
port:
number: 9090
前缀匹配匹配文字字符串。
/api/countries
也匹配您打算与 /api/countries/{country_id}/cities
/api/cities/{city_id}/tours
但是,不起作用。
对于更复杂的匹配,您可以使用精确匹配和正则表达式,如 VirtualService
文档中所述。
也许是这样的(未经测试):
exact: "/api/countries"
regex: "/api/countries/[^/]*/cities"
这个片段
- uri:
prefix: "/api/cities/{city_id}/tours"
- uri:
prefix: "/api/countries/{country_id}/cities"
会按字面意思理解。 {city_id}
和 {country_id}
不会替换为您的自定义 ID。此时,istio 将查找字面意思为 /api/cities/{city_id}/tours
或 /api/countries/{country_id}/cities
的前缀,该前缀不存在(您会收到错误 404)。如果要将表达式与自定义 ID 匹配,则必须使用正则表达式。看看this doc. There you will find information about the capabilities of the StringMatch: exact
, prefix
or regex
. You can find the syntax of the regular expressions used in istio here.
总结:
您应该将 prefix
更改为 regex
,然后创建您自己的正则表达式以匹配您的自定义 ID。示例:
- uri:
regex: "/api/cities/[a-zA-Z]+/tours"
- uri:
regex: "/api/countries/[a-zA-Z]+/cities"
在我的示例中,ID 中只有字母(大写或小写)。在这里,您必须根据 this documentation.
创建自己的正则表达式方法一:-
我尝试了以下方法并发现它可以工作,添加了我测试过并且正在工作的解决方案。基本上,执行的步骤是:-
删除前缀:“/api/countries/{country_id}/cities” 因为 /api/countries/ 是 2 个 API 的通用字符串,最终,它能够路由到原始应用服务主机上的 API 分别与 /api/cities.
相同apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: app
namespace: nsapp
spec:
gateways:
- app-gateway
hosts:
- app.*.*.*
http:
- match:
- uri:
prefix: "/api/cities"
- uri:
prefix: "/api/countries"
route:
- destination:
host: appservice
port:
number: 9090