如果应用程序在Google App Engine上调用10个以上的异步URL Fetch,会发生什么?

时间:2010-09-03 22:01:27

标签: google-app-engine asynchronous urlfetch

在异步网址抓取中阅读Google App Engine documentation

  

该应用最多可同时拥有10个   异步URL提取调用

如果应用程序一次调用10次异步提取,会发生什么情况? Google App Engine是否会引发异常,或者只是将剩余呼叫排队等待为其提供服务?

4 个答案:

答案 0 :(得分:9)

嗯,Swizzec不对。很容易测试:

rpc = []
for i in range(1,20):
    rpc.append(urlfetch.createrpc())
    urlfetch.make_fetch_call(rpc[-1],"http://stackoverflow.com/questions/3639855/what-happens-if-i-call-more-than-10-asynchronous-url-fetch")

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

这不会返回任何例外情况。事实上,这很好用!请注意,对于不可结算的应用程序,您的结果可能会有所不同。

Swizec报告的是一个不同的问题,与您的应用程序INTO最大同时连接有关。对于可计费的应用程序,这里没有实际限制,它只是扩展(根据1000毫秒规则)。

GAE无法知道您的请求处理程序将发出阻止URL提取,因此他看到的连接500与他的应用程序实际正在做的事情无关(如果您的平均请求响应时间是,则这是过于简单化的btw > 1000毫秒你可能会增加500倍。

答案 1 :(得分:6)

这是一个老问题,但我相信接受的答案是错误的或过时的,可能会让人感到困惑。我实际测试了几个月,但根据我的经验,Swizec非常正确,GAE不会排队,而是大多数异步URL提取超过每个请求大约10个同时限制的限制。

有关限制的说明,请参阅https://developers.google.com/appengine/docs/python/urlfetch/#Python_Making_requestshttps://groups.google.com/forum/#!topic/google-appengine/EoYTmnDvg8U

David Underhill提出了一个URL Fetch Manager for 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;
                }
            }
        }
    }
}

答案 2 :(得分:5)

500错误开始发生。静默。

只有在所有请求下查看日志时才会发现这些内容(不要列为错误)。它只是说“请求已中止,因为您达到了同时的请求限制”。

因此,当您进行大量异步调用时,请确保您可以处理其中一些调用。

答案 3 :(得分:1)