2016-10-24 47 views
2

我试图禁用Zuul路由到在运行时注册Eureka的微服务(我使用的是spring引导)。Spring Zuul:动态禁用到服务的路由

这是一个例子:

localhost/hello 
localhost/world 

这两个都是注册微服务。我想在运行时关闭其中一个路由而不关闭它。

有没有办法做到这一点?

谢谢

纳米

+0

动态地,你的意思是通过代码......如果你使用的是云配置,那么你可以从zuul属性中删除路由并通过执行器刷新它,然后路由不会发生......这听起来是动态的... –

回答

0

经过很多努力,我想出了这个解决方案。首先,我使用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值。

0

可选择使用云配置,定制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,例如管理。

+0

我也想过一个过滤器,但我想尝试使用Zuul的本地属性:) – Nano

0

刷新上下文应该工作(只要不添加新的路由规则或删除当前存在的路由规则),如果要添加或删除路由规则,则必须为ZuulProperties添加一个新的bean并标记它与@RefreshScope,@Primary。

例如,您可以自动装入refreshEndpoint bean,并在侦听器上应用refreshEndpoint.refresh()。

将自定义RouteLocator标记为主将会导致问题,因为zuul已经将具有相同类型的bean标记为主。

相关问题