Spring Boot: лучший способ вернуть 503 HttpStatus в ResponseEntity, если источником данных является ВНИЗ - PullRequest
0 голосов
/ 06 февраля 2020

Я использую Spring Boot 2.2.4.RELEASE и у меня есть REST API, выставляя несколько конечных точек. Если база данных не работает, я хотел бы вернуть 503 вызывающей стороне.

Я мог бы использовать DataSourceHealthIndicator, предоставленный бесплатно Spring Boot, если DataSource настроен и т. д. c примерно так:

@Autowired 
private DataSourceHealthIndicator d;

@PostMapping(value = "/{id}")
public ResponseEntity<jsonResponse> someMethod()(
            @PathVariable String id, 
            @Valid @RequestBody SomeDto someDto) {

  //some code

  if("DOWN".equals(d.getHealth(false).getStatus().getCode())) {
    return new ResponseEntity<>(jsonResponse, HttpStatus.SERVICE_UNAVAILABLE);
  }

Есть ли лучший способ сделать это, так как я считаю, что он поражает БД при каждом вызове конечной точки и, следовательно, дорого способ сделать.

Ответы [ 3 ]

0 голосов
/ 08 февраля 2020

Источник данных обычно проверяет соединения для вас и выдает исключение, если не может получить соединение, поэтому вы можете создать пользовательский обработчик ошибок для указанного типа исключения c, который выдается и использовать чтобы возвращать объект пользовательского ответа с 503.

Единственное предостережение в том, что исключение составляет SQLException, что может быть любым количеством проблем, не связанных с соединением. Ваш обработчик ошибок должен быть достаточно умен, чтобы понять, какие коды ошибок в SQLException действительно означают недоступность.

0 голосов
/ 08 февраля 2020

Если вы хотите использовать решение Spring Boot, я бы предложил Spring Cache https://spring.io/guides/gs/caching/

Добавить зависимость Maven <artifactId>spring-boot-starter-cache</artifactId>, включить кэширование в классе приложения SpringBoot с помощью @EnableCaching, затем определите, какие методы должны кэшировать результат.
Этот метод будет попадать в БД только во время первого вызова, все другие вызовы опираются на кэшированное значение.

@Cacheable("records")
public Record getByName(String name) {
  return getRecordRepository().findByName(name);
}

При использовании Spring нативный (в памяти) кеш, вам нужно в какой-то момент выселить объекты, чтобы убедиться, что вы не храните устаревшие данные (если только это не объект readOnly, который никогда не изменяется, вероятно, не очень распространенный вариант использования).

В вашем сценарии (если я правильно понимаю) у вас может быть поток, затем каждые х секунд проверяйте БД, и, если он исправен, вы можете удалить кэш с помощью специального метода:

@CacheEvict(allEntries = true, cacheNames = { "records"})
public void evictAllRecords() {
   // evict all records every 10 minutes
}
0 голосов
/ 06 февраля 2020

если вы ожидали большое количество запросов, вы можете рассмотреть отдельный поток (состояние работоспособности БД), который пингует БД каждые X секунд. Таким образом, входящие HTTP-запросы не должны попадать в БД, если вы знаете, что она недоступна.

Если ваш том невелик, однако, вероятно, лучше попытаться установить соединение и разобраться с ситуацией с недоступной БД, таким образом вам понадобится дополнительный поток, и запросы возобновят работу, как только БД снова станет доступной (в то время как с потоком у вас может быть небольшая задержка в зависимости от настраиваемого интервала).

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