Вы должны опубликовать свои журналы для ошибки, без этого мы можем только догадываться, что такое точная ошибка. Как Forwarding error
, о котором сообщает ZuulExcetption
, является общей ошибкой.
Посмотрите на эту ссылку для метода RibbonRoutingFilter.forward(), который фактически сообщает об этой ошибке. Я добавляю код здесь для резервного копирования.
private HttpResponse forward(RestClient restClient, String service, Verb verb, String uri, Boolean retryable,
MultiValueMap<String, String> headers, MultiValueMap<String, String> params,
InputStream requestEntity) throws Exception {
Map<String, Object> info = this.helper.debug(verb.verb(), uri, headers, params,
requestEntity);
RibbonCommand command = new RibbonCommand(service, restClient, verb, uri, retryable,
headers, params, requestEntity);
try {
HttpResponse response = command.execute();
this.helper.appendDebug(info, response.getStatus(),
revertHeaders(response.getHeaders()));
return response;
}
catch (HystrixRuntimeException ex) {
info.put("status", "500");
if (ex.getFallbackException() != null
&& ex.getFallbackException().getCause() != null
&& ex.getFallbackException().getCause() instanceof ClientException) {
ClientException cause = (ClientException) ex.getFallbackException()
.getCause();
throw new ZuulException(cause, "Forwarding error", 500, cause
.getErrorType().toString());
}
throw new ZuulException(ex, "Forwarding error", 500, ex.getFailureType()
.toString());
}
}
Как вы можете видеть, что единственное реальное место, где может быть сгенерирована ошибка в command.execute()
, где команда является экземпляром HystrixCommand
. Вот ссылка на execute() method в HystrixCommand
.
Ниже приведен код для резервного копирования.
public R execute() {
try {
return queue().get();
} catch (Exception e) {
throw decomposeException(e);
}
}
Здесь queue()
является Future instance
Наиболее распространенная ошибка, которая может произойти с будущего является исключением тайм-аут. Поскольку здесь Future
экземпляр queue()
не связан никаким значением тайм-аута, он может продолжать ожидание.
Однако в большинстве случаев API, который использует Future
, имеет поток, контролирующий время, которое они принимают, и прерывает его через определенный промежуток времени. То же самое делается Ribbon
.
Если у вас действительно проблема с таймаутом, то простым решением является увеличение Ribbon timeout value с использованием следующих свойств.
ribbon.ReadTimeout=10000
//or
<client-name>.ribbon.ReadTimeout=10000
тайм-аут главно может произойти, если сервер Tomcat, который проходит службу, которая проксируется по Zuul имеет слишком большую нагрузку. Весь пул потоков исчерпан, что приводит к следующим запросам, которые должны ждать долгое время.
Возможно, это может быть уменьшено путем изменения количества потоков, которые имеет ваш сервисный tomcat, используя следующее свойство.
server.tomcat.max-threads=0
По умолчанию он установлен в 0, что оставляет его по умолчанию встроенного сервера. В случае с tomcat это 200. См. Ссылку maxThreads property in tomcat.
Примечание. Чтобы увеличить размер пула потоков, мы должны убедиться, что машина имеет такую возможность для предоставления ресурсов, если бы многие потоки выполнялись одновременно.
Как насчет дополнительной информации? Какие части весеннего облака вы используете (зависимости)? Какие версии? Какова ваша конфигурация? – spencergibb
Я использую приложение Eureka, Zuul и Spring Boot. Запрос отправляется на сервер Zuul и перенаправляет запрос в приложение. –
У меня была аналогичная проблема, когда я использовал ANGEL, я переключился на BRIXTON, который каким-то образом решил решить проблему. Вы можете попробовать это, если используете ANGEL. –