Spring Zuul: динамическое отключение маршрута к службе

Я пытаюсь отключить маршрут Zuul к микросервису, зарегистрированному в Eureka во время выполнения (я использую весеннюю загрузку).

Вот пример:

localhost/hello
localhost/world

Эти два являются зарегистрированными микросервисами. Я хотел бы отключить маршрут к одному из них во время выполнения, не выключая его.

Есть ли способ сделать это?

Спасибо,

Нано


person Nano    schedule 24.10.2016    source источник
comment
Под динамическим вы подразумеваете через код... если вы используете облачную конфигурацию, то вы можете удалить маршрутизацию из свойств zuul и обновить ее с помощью привода, тогда маршрутизация не произойдет... для меня это звучит динамично...   -  person Grinish Nepal    schedule 24.10.2016


Ответы (3)


В качестве альтернативы использованию 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 содержит список идентификаторов приложений (имя приложения Spring Boot), управляемых, например, через какой-либо RESTful API.

person Martin Krauskopf    schedule 26.10.2016
comment
Я тоже думал о фильтре, но хотел попробовать использовать родные свойства Зуула :) - person Nano; 28.10.2016

После долгих усилий я пришел к этому решению. Сначала я использовал Netflix Archaius для просмотра файла свойств. Затем я поступил следующим образом:

public class ApplicationRouteLocator extends SimpleRouteLocator implements RefreshableRouteLocator {

public ApplicationRouteLocator(String servletPath, ZuulProperties properties) {
    super(servletPath, properties );
}


@Override
public void refresh() {
   doRefresh();
}
}

Сделал метод doRefresh() общедоступным, расширив SimpleRouteLocator и вызвав его метод в переопределенном интерфейсе RefreshableRouteLocator.

Затем я переопределил 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() для извлечения данных из события). Так как я также Autowired ZuulProperties, я смог получить к нему доступ. С правильным правилом я мог бы найти, является ли собственность Зуула

zuul.ignoredPatterns

был изменен соответствующим образом, изменив его значение в ZuulProperties.

person Nano    schedule 24.05.2017
comment
Не удается разрешить метод «getServletPrefix» в «ServerProperties» - person withoutOne; 07.10.2020

Здесь должен работать контекст обновления (пока вы не добавляете новое правило маршрутизации или не удаляете существующее в настоящее время), если вы добавляете или удаляете правила маршрутизации, вам нужно добавить новый bean-компонент для ZuulProperties и пометить его с помощью @RefreshScope, @Начальный.

Например, вы можете автоматически связать компонент refreshEndpoint и применить refreshEndpoint.refresh() к слушателю.

Пометка пользовательского RouteLocator как основного вызовет проблемы, поскольку в zuul уже есть bean-компонент того же типа, помеченный как основной.

person Karim Masoud    schedule 26.09.2017