gpt4 book ai didi

spring - 在 Spring Cloud Netflix Zuul 中以编程方式设置路由

转载 作者:行者123 更新时间:2023-12-05 00:51:52 27 4
gpt4 key购买 nike

我创建了两个 AWS Beanstalk 环境,每个环境都有自己的应用程序版本。这些环境的 URL 是 https://beta.myserver.com/v1073https://beta.myserver.com/v1084 .这些 url 指向负载均衡器。

现在我还有一个具有以下配置的 Zuul 实现。

    zuul:
routes:
beta:
path: /api/**
serviceId: beta-root
strip-prefix: false
sensitive-headers: Cookie,Set-Cookie

ribbon:
eureka:
enabled: false

hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 5000

beta-root:
ribbon:
listOfServers: https://beta.myserver.com

对我的应用程序的请求必须有一个版本 header 。我有一个 Zuul“预”过滤器来检查这个 header 值。目标是根据 header 值路由请求。

我已经能够拦截请求,但无法从过滤器路由它。代码片段如下。运行代码后,请求仍然尝试去 https://beta.myserver.com/api/ ...
@Override
public Object run() {
/* Logic to get version header etc */

/* Set the new route */
Map<String, ZuulRoute> routes = zuulProps.getRoutes();
ZuulRoute currentRoute = routes.get("beta-root");
currentRoute.setLocation("https://beta.myserver.com/v1073");

/* Refresh the route */
routeLocator.getRoutes();

logger.warn("Current Route:" + currentRoute.getLocation());
return null;
}

任何建议如何解决这个问题?

最佳答案

你真正需要做的是改变requestURI ,在您的情况下不是服务器位置。你可以像下面那样轻松地做到这一点。

首先,您的过滤器的顺序应该大于 PreDecorationFilter的订单目前在 Dalston 版本中为 5。 (您需要检查您正在使用的版本中的值)。PreDecorationFilter处理请求头并将必要的信息填入 RequestContext .还有这个 RequestContext将用于为您的请求定义实际 URL。 requestURI是你需要改变的关键。在您的情况下,您可以根据 header 附加或修改 requestURI。以下是您的预过滤器的片段。

@Override
public int filterOrder() {
return 6;
}

@Override
public Object run() {
RequestContext ctx = RequestContext.getCurrentContext();
// override request URI
ctx.set("requestURI", "/v1073" + ctx.get("requestURI"));
return null;
}

您的原始实现似乎有一些问题。首先,您正在尝试更改 ZuulProperties route 的位置。此对象为所有请求共享。如果您仅针对特定请求更改它,则其他可能具有不同 header 的请求可能会被路由到错误的位置。

其次,您在 ZuulRoute 中设置 location 属性对象如下。
currentRoute.setLocation("https://beta.myserver.com/v1073");

原来 location 属性值是你的 service-id - beta-root - 与您的配置。如果您使用具有“http”或“https prefix, original”的特定网址更改它RibbonRoutingFilter will not work. Instead, SimpleRoutingHostFilter will process your request. It means that your not-modified requests will be handled by RibbonRoutingFilter and modified requests will be handled by SimpleHostRoutingFilter`。

更新:根据 Http Header 路由不同的主机

如果你想根据 http 头路由到不同的主机,有几种方法可以做到这一点。

案例 1:如果您使用 Ribbon(和 RibbonRoutingFilter)

以下功能仅适用于 Edgware.SR1 和更高版本。从 Eddware.SR1,您可以为名为 FilterConstants.LOAD_BALANCER_KEY 的负载均衡器指定值在 RequestContext .此值将传递到功能区负载均衡器。您可以在预过滤器中放入任何您想要的值(任何对象)。如果要根据特殊的 http header 更改路由,可以在自定义预过滤器中执行此操作。
然后定义自己的 IRule功能区的实现。 LOAD_BALANCER_KEY将发给您的 IRule执行。因此,您可以根据 LOAD_BALANCER_KEY 的值从 Ribbon 拥有的服务器列表中选择特定服务器。你设置的。

您可以找到简短的文档 here .

您可以从 the test case in PR 中找到示例代码. (RibbonRoutingFilterLoadBalancerKeyIntegrationTests.java)

案例 2:如果您使用的是 SimpleHostRoutingFilter(不带功能区)

如果您指定 url而不是 serviceId在 zuul 的路由属性中,请求会被 SimpleHostRoutingFilter 路由,没有 Ribbon。

SimpleHostRoutingFilter 只需通过以下代码使用主机地址
RequestContext.getCurrentContext().getRouteHost();

该值由 PreDecorationFilter 设置。因此,您可以在预过滤器中更改此信息。
  • 制作您自己的自定义预过滤器,其顺序值介于 PreDecorationFilter 和 SimpleHostRoutingFilter 之间。
  • 在过滤器中,检查路由主机。如果您想根据 HTTP header 更改任何已知主机,请通过 RequestContext.getCurrentContext().setRouteHost 更改路由主机。基于 Http 头。

  • 在第二种方法的情况下,我没有尝试自己做。我认为这只是理论上的解决方案。
    第二种方法的问题在于它使用的是 SimpleHostRoutingFilter。 SimpleHostRoutingFilter 不会为请求生成任何 HystrixCommand,因此您不能在 Zuul 中使用 Hystrix 提供的任何断路器功能。如果您使用的是 Edgware 版本,那么我认为第一种方法更好。

    关于spring - 在 Spring Cloud Netflix Zuul 中以编程方式设置路由,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43740659/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com