我正在尝试禁用Zuul路由到运行时向Eureka注册的微服务(我正在使用spring boot)。
这是一个例子:
localhost/hello
localhost/world
这两个是注册的微服务。我想在运行时禁用其中一个路由而不关闭它。
有办法做到这一点吗?
谢谢,
纳米
答案 0 :(得分:0)
使用Cloud Config时,可以使用自定义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列表(Spring Boot应用程序名称),例如通过一些RESTful API管理。
答案 1 :(得分:0)
经过大量努力,我想出了这个解决方案。首先,我使用Netflix Archaius来查看属性文件。然后我继续如下:
public class ApplicationRouteLocator extends SimpleRouteLocator implements RefreshableRouteLocator {
public ApplicationRouteLocator(String servletPath, ZuulProperties properties) {
super(servletPath, properties );
}
@Override
public void refresh() {
doRefresh();
}
}
通过扩展SimpleRouteLocator并在重写的RefreshableRouteLocator接口中调用其方法,使doRefresh()方法成为公共。
然后我用我的自定义实现重新定义了bean 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()从事件中提取数据)。由于我还自动安装了ZuulProperties,因此我能够访问它。通过正确的规则,我可以找到Zuul的财产
zuul.ignoredPatterns
修改了,相应地更改了ZuulProperties中的值。
答案 2 :(得分:0)
此处刷新上下文应该有效(只要您不添加新的路由规则或删除当前存在的规则),如果要添加或删除路由规则,则必须为ZuulProperties添加新Bean并将其标记为@RefreshScope,@ Primary。
例如,您可以自动装配refreshEndpoint bean,并在侦听器上应用refreshEndpoint.refresh()。
将自定义RouteLocator标记为主要将导致问题,因为zuul已经将相同类型的bean标记为primary。