2010-09-03 6 views
11

die Google App Engine documentation auf asynchrone URL Lesen Fetch:Was passiert, wenn eine Anwendung mehr als 10 asynchrone URL-Aufrufe bei Google App Engine aufruft?

Die App kann bis zu 10 gleichzeitige asynchrone URL haben Fetch Anrufe

Was eine Anwendung passiert, wenn mehr als 10 async Anrufe holen auf eine Zeit?
Wird von Google App Engine eine Ausnahme ausgelöst oder werden die verbleibenden Anrufe einfach in die Warteschlange gestellt, um sie zu bedienen?

Antwort

9

Umm, Swizzec ist falsch. Einfach zu testen:

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 

Dies gibt keine Ausnahmen zurück. In der Tat funktioniert das gut! Beachten Sie, dass Ihre Ergebnisse für nicht abrechenbare Anwendungen variieren können.

Was Swizec meldet, ist ein anderes Problem, bezogen auf maximale gleichzeitige Verbindungen in Ihre Anwendung. Für abrechenbare Apps gibt es hier übrigens keine praktische Grenze, sie skaliert nur aus (vorbehaltlich der 1000ms-Regel).

GAE hat keine Möglichkeit zu wissen, dass Ihr Anforderungshandler eine blockierende URL abruft, so dass die Verbindung 500, die er sieht, nicht in Zusammenhang steht, was seine App tatsächlich tut (das ist eine Übervereinfachung übrigens, wenn Ihre durchschnittliche Anfrage Antwortzeit Ist> 1000ms erhöht sich Ihre Wahrscheinlichkeit von 500's).

+1

Nach meiner Erfahrung ist Swizec nicht falsch. Siehe meine Antwort unten. –

5

500 Fehler beginnen zu passieren. Schweigend.

Sie erfahren dies nur, wenn Sie Ihr Protokoll unter allen Anfragen betrachten (werden nicht als Fehler aufgelistet). Es heißt einfach "Die Anfrage wurde abgebrochen, weil Sie Ihr Limit für gleichzeitige Anfragen erreicht haben".

Also, wenn Sie viele asynchrone Anrufe machen, stellen Sie sicher, dass Sie einige davon ausräumen können.

+0

Wohlgemerkt das gleiche für alle und alle Anfragen geschieht. Wie Essen durch eine Aufgabenliste oder so. Anscheinend, wenn deine Antworten sehr, sehr schnell sind (unter 100ms, denke ich), ist Google bereit, viel zu ertragen und wird diesen Fehler nicht werfen. –

+0

uh .. das passiert nicht mit meiner Anwendung (ich sehe keine 500 Fehler).Ich bin auf Grenzfall mit 11-13 Anrufen obwohl. – systempuntoout

6

Dies ist eine alte Frage, aber ich glaube, die akzeptierte Antwort falsch oder veraltet ist und die Menschen verwirren. Es ist ein paar Monate her, dass ich das getestet habe, aber nach meiner Erfahrung hat Swizec recht, dass GAE die meisten asynchronen URL-Abfragen, die die Grenze von etwa 10 simultanen URLs pro Anfrage überschreiten, nicht einreiht, sondern versagt.

Eine Beschreibung des Grenzwerts finden Sie unter https://developers.google.com/appengine/docs/python/urlfetch/#Python_Making_requests und https://groups.google.com/forum/#!topic/google-appengine/EoYTmnDvg8U.

David Underhill hat eine URL Fetch Manager for Python entwickelt, die asynchrone URL-Aufrufe in die Warteschlange stellt, die den Grenzwert im Anwendungscode überschreiten.

Ich habe etwas ähnliches für Java implementiert, die synchron Blöcke (aufgrund des Fehlens einer Callback-Funktion oder ListenableFutures) weitere Anfragen:

/** 
* 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; 
       } 
      } 
     } 
    } 
} 
Verwandte Themen