Was sind die Verbindungslimits für Google Cloud SQL von App Engine und wie werden DB-Verbindungen am besten wiederverwendet?

Ich habe eine Google App Engine-App, die eine Google Cloud SQL-Instanz zum Speichern von Daten verwendet. Meine Instanz muss in der Lage sein, Hunderte von Clients gleichzeitig über erholsame Anrufe zu bedienen, die jeweils zu einer oder mehreren DB-Abfragen führen. Ich habe die Methoden, die DB-Zugriff benötigen, umbrochen und das Handle für die DB-Verbindung in os.environ gespeichert. Sehendiese SO Frage / Antwort für im Grunde, wie ich es mache.

Sobald jedoch ein paar hundert Clients eine Verbindung zu meiner App herstellen und Datenbankaufrufe auslösen, werden in den Fehlerprotokollen von Google App Engine folgende Fehler angezeigt (und meine App gibt natürlich 500 zurück):

<code>could not connect: ApplicationError: 1033 Instance has too many concurrent requests: 100 Traceback (most recent call last): File "/base/python27_run
</code>

Gibt es Tipps von erfahrenen Nutzern von Google App Engine und Google Cloud SQL? Danke im Voraus.

Hier ist der Code für den Decorator, den ich für Methoden verwende, die eine DB-Verbindung erfordern:

<code>def with_db_cursor(do_commit = False):
    """ Decorator for managing DB connection by wrapping around web calls.
    Stores connections and open connection count in the os.environ dictionary
    between calls.  Sets a cursor variable in the wrapped function. Optionally
    does a commit.  Closes the cursor when wrapped method returns, and closes
    the DB connection if there are no outstanding cursors.

    If the wrapped method has a keyword argument 'existing_cursor', whose value
    is non-False, this wrapper is bypassed, as it is assumed another cursor is
    already in force because of an alternate call stack.

    Based mostly on post by : Shay Erlichmen
    At: https://stackoverflow.com/a/10162674/379037
    """

    def method_wrap(method):
        def wrap(*args, **kwargs):
            if kwargs.get('existing_cursor', False):
                #Bypass everything if method called with existing open cursor
                vdbg('Shortcircuiting db wrapper due to exisiting_cursor')
                return  method(None, *args, **kwargs)

            conn = os.environ.get("__data_conn")

            # Recycling connection for the current request
            # For some reason threading.local() didn't work
            # and yes os.environ is supposed to be thread safe 
            if not conn:                    
                conn = _db_connect()
                os.environ["__data_conn"] = conn
                os.environ["__data_conn_ref"] = 1
                dbg('Opening first DB connection via wrapper.')
            else:
                os.environ["__data_conn_ref"] = (os.environ["__data_conn_ref"] + 1)
                vdbg('Reusing existing DB connection. Count using is now: {0}',
                    os.environ["__data_conn_ref"])        
            try:
                cursor = conn.cursor()
                try:
                    result = method(cursor, *args, **kwargs)
                    if do_commit or os.environ.get("__data_conn_commit"):
                        os.environ["__data_conn_commit"] = False
                        dbg('Wrapper executing DB commit.')
                        conn.commit()
                    return result                        
                finally:
                    cursor.close()                    
            finally:
                os.environ["__data_conn_ref"] = (os.environ["__data_conn_ref"] -
                        1)  
                vdbg('One less user of DB connection. Count using is now: {0}',
                    os.environ["__data_conn_ref"])
                if os.environ["__data_conn_ref"] == 0:
                    dbg("No more users of this DB connection. Closing.")
                    os.environ["__data_conn"] = None
                    db_close(conn)
        return wrap
    return method_wrap

def db_close(db_conn):
    if db_conn:
        try:
            db_conn.close()
        except:
            err('Unable to close the DB connection.', )
            raise
    else:
        err('Tried to close a non-connected DB handle.')
</code>

Antworten auf die Frage(2)

Ihre Antwort auf die Frage