Ограничение вызова Spring Boot Rest конечная точка, пока отображение из базы данных не будет выполнено - PullRequest
0 голосов
/ 13 апреля 2020

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

Запрос к БД может быть выполнен за 8 минут, и я выполняю их с помощью EventListener

@Override
@EventListener(ApplicationReadyEvent.class)
public void getValuesFromDB() {
    loaderService.getValuesFromDBToCache();
}

Проблема в том, что мне нужно сделать это при создании контекста и создании кэша, поэтому я не могу это сделать в PostConstruct.

Как ограничить прием вызовов на конечной точке, пока loaderService.getValuesFromDBToCache (); работает?

1 Ответ

1 голос
/ 13 апреля 2020

Я думаю, что такой подход, запрещающий вызовы API в течение 8 минут, не очень хороший. Вы должны попытаться изменить его на ленивую загрузку, если это возможно.

Если вы хотите сделать это с некоторой определенной c задержкой или до того момента, когда кэш завершит загрузку, один из способов - перехватить вызовы. с приведенным ниже кодом, приведенным ниже,

public class SampleInterceptor extends HandlerInterceptorAdapter {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        String theMethod = request.getMethod();

        if (checkIsCacheProcessingDone()) {

            return true;
        }
        else {
            //not allowed
            response.sendError(HttpStatus.METHOD_NOT_ALLOWED.value());
            return false;
        }
    }

private boolean checkIsCacheProcessingDone(){
//a boolean should be created in cache or where ever you prefer which is accessible from this context and check if that value is true or not
}

Теперь зарегистрируйте его, используя приведенный ниже код,

@Configuration
public class SampleConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new SampleInterceptor()).addPathPatterns(yourPath);
    }
}

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

Не go этот маршрут, если вы не уверены, что хотите заблокировать пользователя.

EDIT ================================================ ===============

Другой подход, который мне пришёл в голову: создать контекст приложения без веб, затем заполнить кеш (надеюсь, вы используете внешний кеш, например redis et c и не в памяти), и как только это будет сделано, чтение базы данных завершится, перезапустите приложение. Пример будет выглядеть следующим образом:

ConfigurableApplicationContext configurableApplicationContext = SpringApplicationBuilder(OmsBasketApiApplication.class).web(
                WebApplicationType.NONE).run(args);

try {
    addToredis(configurableApplicationContext);
} catch (Exception exception){
    //do something else? System.exit(1)?
} finally {
    configurableApplicationContext.close();
}

configurableApplicationContext = SpringApplicationBuilder(OmsBasketApiApplication.class).run(args);

Надеюсь, это поможет

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...