Я и моя команда застряли в очень глупом случае HttpClientErrorException, позвольте мне сначала дать обзор моего сценария работы.
У меня есть стек микросервисов со следующими вещами:
- Mysql - база данных
- keycloak - управление пользователями
- Eureka - discovery
- Zuul - обратный прокси
- Zipkin и Sleuth-трассировщики
- Microservice Hotel - все, что связано с Hotel Entity (запись отелей, CRUD для отелей и учетных записей пользователей, связанных с ними).
- Microservice Room - все о номерах
- Microservice Цена - все оцены
- Микросервисный планировщик - микросервис, который отслеживает обновления данных и синхронизирует их с другой системой (третьей стороной).
В планировщике я использую Spring Scheduler с cron
@Scheduled(cron = "0 0/5 * * * ?")
public void prepareDataForSync() {...
Целью кода в prepareDataForSync является получение данных о каждом отеле, проверка текущего состояния и, если вычтены какие-либо изменения, передача их третьему лицу.Теперь возникает настоящая проблема:
Я звоню в службу отдыха, чтобы получить список отелей от моего планировщика:
@Scheduled(cron = "0 0/5 * * * ?")
public void prepareDataForSync() {
Set<Long> unChangeableAllc = new HashSet<Long>();
List<MessageCenter> messages = new ArrayList<MessageCenter>();
String hotelURL = "http://hoteldata/hotel/allActive";
try {//loop over hotel data and process further...
Все эти службы работают в среде докера, причем каждая служба имеет свой собственныйКонтейнер и общение через докерскую сеть.
Теперь, когда я запускаю сервисы, включая Hotel и Scheduler, все работает отлично в течение нескольких часов, но затем я получаю следующее исключение в своих журналах, и сервис больше не синхронизируется с третьей стороной.
org.springframework.web.client.HttpClientErrorException: 400 null
at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:63)
at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:700)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:653)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:613)
at org.springframework.web.client.RestTemplate.getForEntity(RestTemplate.java:312)
at com.channelmanager.allocationservices.controllers.RoomAllocationsController.prepareDataForSync(RoomAllocationsController.java:1159)
at sun.reflect.GeneratedMethodAccessor257.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:65)
at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
at org.springframework.scheduling.concurrent.ReschedulingRunnable.run(ReschedulingRunnable.java:81)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
В строке 1159 у меня есть только сервисный звонок:
ResponseEntity<String> hotelResponse = restTemplate.getForEntity(hotelURL, String.class);
Я проверил журналы в соответствующем гостиничном сервисе, в журналах отображается запрос на обслуживание, и данные были собраны и записаны.в поток ответов, но, как показывает исключение, я никогда не получал никакого ответа и получал это исключение.
Журналы из гостиничного сервиса:
2018-12-31 06:06:00 [http-nio-9501-exec-5] DEBUG o.s.web.servlet.DispatcherServlet - DispatcherServlet with name 'dispatcherServlet' processing GET request for [/public/hotel]
2018-12-31 06:06:00 [http-nio-9501-exec-5] DEBUG o.s.w.s.m.m.a.RequestMappingHandlerMapping - Looking up handler method for path /public/hotel
2018-12-31 06:06:00 [http-nio-9501-exec-5] DEBUG o.s.w.s.m.m.a.RequestMappingHandlerMapping - Returning handler method [public org.springframework.http.ResponseEntity<java.util.List<com.channelmanager.hoteldata.models.Hotel>> com.channelmanager.hoteldata.controllers.HotelUserPublicController.getAllHotel()]
2018-12-31 06:06:00 [http-nio-9501-exec-5] DEBUG o.s.web.servlet.DispatcherServlet - Last-Modified value for [/public/hotel] is: -1
2018-12-31 06:06:00 [http-nio-9501-exec-5] DEBUG o.s.w.s.m.m.a.HttpEntityMethodProcessor - Written [[Hotel [id=1, name=testhotel, createdBy=cmadmin, modifiedOn=2018-04-27T13:54:43, createdOn=2018-04-27T13:54:43, enabled=true, ...]]] as "application/json" using [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter@a50d709]
2018-12-31 06:06:00 [http-nio-9501-exec-5] DEBUG o.s.web.servlet.DispatcherServlet - Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapter completed request handling
2018-12-31 06:06:00 [http-nio-9501-exec-5] DEBUG o.s.web.servlet.DispatcherServlet - Successfully completed request
Если я перезапущу службу планировщика, она снова начнет работать, но через несколько часов у меня снова возникнет та же проблема.В качестве обходного пути в настоящее время я настроил cron на сервере для перезапуска службы каждые 2 часа, но это действительно плохой обходной путь, я не могу полагаться на это в производственной среде и мне нужно найти причину проблемы.
Я гуглил и пытался ответить на любой вопрос, основанный на HttpClientErrorException, но для меня ничего не имело смысла.
Пожалуйста, дайте мне знать, если от меня требуется дополнительная информация.
РЕДАКТИРОВАТЬ:
Вывод статистики Docker:
0b7d20c5a566 schedular 0.12% 1.365GiB / 31.41GiB 4.34% 0B / 0B 3.27MB / 0B 64
TOP Выход внутри контейнера