我试图禁用Zuul路由到在运行时注册Eureka的微服务(我使用的是spring引导)。Spring Zuul:动态禁用到服务的路由
这是一个例子:
localhost/hello
localhost/world
这两个都是注册微服务。我想在运行时关闭其中一个路由而不关闭它。
有没有办法做到这一点?
谢谢
纳米
我试图禁用Zuul路由到在运行时注册Eureka的微服务(我使用的是spring引导)。Spring Zuul:动态禁用到服务的路由
这是一个例子:
localhost/hello
localhost/world
这两个都是注册微服务。我想在运行时关闭其中一个路由而不关闭它。
有没有办法做到这一点?
谢谢
纳米
经过很多努力,我想出了这个解决方案。首先,我使用Netflix Archaius观看属性文件。然后我如下进行:
public class ApplicationRouteLocator extends SimpleRouteLocator implements RefreshableRouteLocator {
public ApplicationRouteLocator(String servletPath, ZuulProperties properties) {
super(servletPath, properties);
}
@Override
public void refresh() {
doRefresh();
}
}
通过在界面RefreshableRouteLocator的重写一个延伸SimpleRouteLocator并调用其方法制得的doRefresh()方法public。
然后我重新定义了豆RouteLocator与我的自定义实现:
@Configuration
@EnableConfigurationProperties({ ZuulProperties.class })
public class ZuulConfig {
public static ApplicationRouteLocator simpleRouteLocator;
@Autowired
private ZuulProperties zuulProperties;
@Autowired
private ServerProperties server;
@Bean
@Primary
public RouteLocator routeLocator() {
logger.info("zuulProperties are: {}", zuulProperties);
simpleRouteLocator = new ApplicationRouteLocator(this.server.getServletPrefix(),
this.zuulProperties);
ConfigurationManager.getConfigInstance().addConfigurationListener(configurationListener);
return simpleRouteLocator;
}
private ConfigurationListener configurationListener =
new ConfigurationListener() {
@Override
public void configurationChanged(ConfigurationEvent ce) {
// zuulProperties.getRoutes() do something
// zuulProperties.getIgnoredPatterns() do something
simpleRouteLocator.refresh();
}
}
}
每次在文件中的属性被修改事件被触发和ConfigurationEvent能够处理它(getPropertyName()和getPropertyValue ()从事件中提取数据)。由于我也Autowired ZuulProperties我能够访问它。有了正确的规则我能找到Zuul
的zuul.ignoredPatterns
财产是否被修改相应改变其在ZuulProperties值。
可选择使用云配置,定制ZuulFilter
可以使用。喜欢的东西(部分实现显示的概念):
public class BlackListFilter extends ZuulFilter {
@Override
public String filterType() {
return "pre";
}
...
@Override
public Object run() {
RequestContext ctx = RequestContext.getCurrentContext();
String uri = ctx.getRequest().getRequestURI();
String appId = uri.split("/")[1];
if (blackList.contains(appId)) {
ctx.setSendZuulResponse(false);
LOG.info("Request '{}' from {}:{} is blocked",
uri, ctx.getRequest().getRemoteHost(), ctx.getRequest().getRemotePort());
}
return null;
}
}
其中blackList
包含应用程序ID列表(春季启动应用程序的名称),通过一些RESTful API,例如管理。
我也想过一个过滤器,但我想尝试使用Zuul的本地属性:) – Nano
刷新上下文应该工作(只要不添加新的路由规则或删除当前存在的路由规则),如果要添加或删除路由规则,则必须为ZuulProperties添加一个新的bean并标记它与@RefreshScope,@Primary。
例如,您可以自动装入refreshEndpoint bean,并在侦听器上应用refreshEndpoint.refresh()。
将自定义RouteLocator标记为主将会导致问题,因为zuul已经将具有相同类型的bean标记为主。
动态地,你的意思是通过代码......如果你使用的是云配置,那么你可以从zuul属性中删除路由并通过执行器刷新它,然后路由不会发生......这听起来是动态的... –