Что произойдет, если приложение вызовет более 10 асинхронных выборок URL в Google App Engine? - PullRequest
11 голосов
/ 04 сентября 2010

Чтение Google App Engine документация об асинхронном извлечении URL:

Приложение может иметь до 10 одновременных асинхронных вызовов извлечения URL

Что произойдет, если приложение вызывает более 10 асинхронных выборок за раз?
Возникает ли в Google App Engine исключение или просто ставится в очередь оставшиеся вызовы, ожидающие их обслуживания?

Ответы [ 4 ]

9 голосов
/ 06 сентября 2010

Умм, Swizzec неверен.Достаточно легко проверить:

rpc = []
for i in range(1,20):
    rpc.append(urlfetch.createrpc())
    urlfetch.make_fetch_call(rpc[-1],"/3007907/chto-proizoidet-esli-prilozhenie-vyzovet-bolee-10-asinhronnyh-vyborok-url-v-google-app-engine")

for r in rpc:
    response = r.get_result().status_code

Это не возвращает никаких исключений.На самом деле, это работает просто отлично!Обратите внимание, что ваши результаты могут отличаться для неоплачиваемых приложений.

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

GAE не может знать, что ваш обработчик запросов выдаст блокирующую выборку URL, поэтому соединение 500он видит, что он не связан с тем, что на самом деле делает его приложение (кстати, это упрощение, если среднее время ответа на запрос> 1000 мс, а вероятность увеличения 500).

6 голосов
/ 04 июля 2014

Это старый вопрос, но я считаю, что принятый ответ является неправильным или устаревшим и может сбить людей с толку. Прошло уже несколько месяцев, как я на самом деле тестировал это, но, по моему опыту, Swizec совершенно прав, что GAE не будет ставить в очередь, а скорее будет отказывать большинству асинхронных выборок URL, превышающих ограничение в 10 одновременных запросов на запрос.

См. https://developers.google.com/appengine/docs/python/urlfetch/#Python_Making_requests и https://groups.google.com/forum/#!topic/google-appengine/EoYTmnDvg8U для описания ограничения.

Дэвид Андерхилл (David Underhill) разработал диспетчер получения URL-адреса для Python , который ставит в очередь асинхронные выборки URL-адресов, превышающие ограничение в коде приложения.

Я реализовал нечто подобное для Java, которая синхронно блокирует (из-за отсутствия функции обратного вызова или ListenableFutures) дополнительные запросы:

/**
 * A URLFetchService wrapper that ensures that only 10 simultaneous asynchronous fetch requests are scheduled. If the
 * limit is reached, the fetchAsync operations will block until another request completes.
 */
public class BlockingURLFetchService implements URLFetchService {
    private final static int MAX_SIMULTANEOUS_ASYNC_REQUESTS = 10;

    private final URLFetchService urlFetchService = URLFetchServiceFactory.getURLFetchService();
    private final Queue<Future<HTTPResponse>> activeFetches = new LinkedList<>();

    @Override
    public HTTPResponse fetch(URL url) throws IOException {
        return urlFetchService.fetch(url);
    }

    @Override
    public HTTPResponse fetch(HTTPRequest request) throws IOException {
        return urlFetchService.fetch(request);
    }

    @Override
    public Future<HTTPResponse> fetchAsync(URL url) {
        block();

        Future<HTTPResponse> future = urlFetchService.fetchAsync(url);
        activeFetches.add(future);
        return future;
    }

    @Override
    public Future<HTTPResponse> fetchAsync(HTTPRequest request) {
        block();

        Future<HTTPResponse> future = urlFetchService.fetchAsync(request);
        activeFetches.add(future);
        return future;
    }

    private void block() {
        while (activeFetches.size() >= MAX_SIMULTANEOUS_ASYNC_REQUESTS) {
            // Max. simultaneous async requests reached; wait for one to complete
            Iterator<Future<HTTPResponse>> it = activeFetches.iterator();
            while (it.hasNext()) {
                if (it.next().isDone()) {
                    it.remove();
                    break;
                }
            }
        }
    }
}
5 голосов
/ 04 сентября 2010

500 ошибок начинают происходить.Тихо.

Вы узнаете об этом, только когда просматриваете свой журнал по всем запросам (не отображаются как ошибки).В нем просто говорится: «Запрос был прерван, потому что вы достигли лимита одновременных запросов».

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

1 голос
/ 09 октября 2010

Посмотрите, ответит ли это на ваш вопрос:

http://groups.google.com/group/google-appengine/browse_thread/thread/1286139a70ef83c5?fwc=1

...