Моя цель - быстро сделать сообщения на сервере с appengine (java). Я пытаюсь сделать это с помощью UrlFetchService.fetchAsync. Я основывал свой код после this blog post. Я был в состоянии сделать запрос, используя приведенный ниже код, но я получаю какое-то странное поведение:Async urlfetch Http post в App Engine using Future
private void futureRequests() {
URLFetchService fetcher = URLFetchServiceFactory.getURLFetchService();
URL url = new URL("https://someserver.com");
FetchOptions fetchOptions = FetchOptions.Builder.withDefaults();
fetchOptions.doNotValidateCertificate();
fetchOptions.setDeadline(60D);
ArrayList<Future<HTTPResponse>> asyncResponses = new ArrayList<Future<HTTPResponse>>();
for (int i = 0; i < postDatas.size(); i++) {
HTTPRequest request = new HTTPRequest(url, HTTPMethod.POST, fetchOptions);
request.setPayload(postDatas.get(i).getBytes(UTF8));
HTTPHeader header = new HTTPHeader("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
request.setHeader(header);
header = new HTTPHeader("Content-Length", Integer.toString(postDatas.get(i).getBytes().length));
request.setHeader(header);
header = new HTTPHeader("Authorization", "auth=" + authToken);
request.setHeader(header);
Future<HTTPResponse> responseFuture = fetcher.fetchAsync(request);
asyncResponses.add(responseFuture);
}
for (Future<HTTPResponse> future : asyncResponses) {
HTTPResponse response;
try {
response = future.get();
int responseCode = response.getResponseCode();
resp.getWriter().println("response: " + responseCode);
logger.warning("Response: " + responseCode);
} catch (Exception e) {
}
}
}
странное поведение является то, что я получаю повторяющиеся сообщения на сервере, и в соответствии с моей страницы Appstats я использую 10x- 20x больше urlFetches, чем то, что было добавлено с помощью кода выше. Ниже мой Appstats экран:
Есть еще UrlFetch вызовы, которые не могли поместиться на экране. Похоже, что запросы по-прежнему завершаются синхронно (обведенные кругом элементы), но есть много urlFetches, которые, похоже, продолжаются в одно и то же время. Мой вопрос: как я получаю все эти призывы к urlFetch, когда у меня было только 14 Future? Может ли сервер давать ошибку или 503 и повторить попытку urlFetch до тех пор, пока она не пройдет? И как я могу получить 2 сообщения для каждого запроса?
Я понимаю, что я мог бы использовать очередь задач для выполнения запроса asyc, однако я имею дело с относительно небольшим количеством запросов (20-100), а время холодного запуска наращивания другого экземпляра, вероятно, сделало бы это не хороший вариант для моей ситуации. Может ли кто-нибудь объяснить это поведение или иметь опыт с этим?
Ну, очевидный ответ, что вы делаете больше URLFetches, чем вы думаете. Вы регистрируете количество фьючерсов, которые вы создаете где-то? Вы просматривали следы для каждого RPC, чтобы узнать, откуда он? Кроме того, они не синхронны - есть только ограничение на количество выдающихся запросов одновременно. –
Вы получаете переадресацию? За ними следуют дефолты. ИМО единственное объяснение заключается в том, что у вас есть цикл перенаправления. –
@NickJohnson выглядит, как очевидный ответ был правильным. Я действительно отправлял больше просьбы, чем думал. Одна неуместная фигурная скобка заставила futureRequest() называться внутри цикла вместо внешней ... простой коррекции, теперь она работает как чемпион и значительно сокращает время, необходимое для завершения процесса. Благодарю. – Patrick