Ausführungsumgebung von Cloud Functions-Funktionen
Cloud Run Functions-Funktionen werden in einer vollständig verwalteten, serverlosen Umgebung ausgeführt, in der Google sich um die Verwaltung der Infrastruktur, Betriebssysteme und Laufzeitumgebungen kümmert. Jede Cloud Functions-Funktion wird in ihrem eigenen isolierten, sicheren Ausführungskontext bereitgestellt und automatisch skaliert. Ihr Lebenszyklus ist von dem anderer Funktionen unabhängig.
Laufzeiten
Cloud Run Functions unterstützt mehrere Sprachlaufzeiten. Jede enthält eine Standardreihe von Systempaketen sowie die Tools und Bibliotheken, die für diese Sprache benötigt werden. Sie benötigen den Laufzeit-ID-Wert, wenn Sie Funktionen über die Befehlszeile oder über Terraform bereitstellen.
Sicherheits- und Wartungsupdates werden für alle Ausführungsumgebungen der 1. und 2. Generation bereitgestellt. Diese Updates werden automatisch oder manuell angewendet, je nach Umgebung und Ihrer Konfiguration. Weitere Informationen zu Updates der Ausführungsumgebung finden Sie unter Cloud Run Functions-Funktionen schützen.
Node.js
Laufzeit | Generierung | Umgebung | Laufzeit-ID | Laufzeit-Image |
---|---|---|---|---|
Node.js 22 | 2. Generation | Ubuntu 22.04 | nodejs22 | us-central1-docker.pkg.dev/serverless-runtimes/google-22-full/runtimes/nodejs22 |
Node.js 20 | 1. Generation, 2. Generation | Ubuntu 22.04 | nodejs20 | us-central1-docker.pkg.dev/serverless-runtimes/google-22-full/runtimes/nodejs20 |
Node.js 18 | 1. Generation, 2. Generation | Ubuntu 22.04 | nodejs18 | us-central1-docker.pkg.dev/serverless-runtimes/google-22-full/runtimes/nodejs18 |
Node.js 16 | 1. Generation, 2. Generation | Ubuntu 18.04 | nodejs16 | us-central1-docker.pkg.dev/serverless-runtimes/google-18-full/runtimes/nodejs16 |
Node.js 14 | 1. Generation, 2. Generation | Ubuntu 18.04 | nodejs14 | us-central1-docker.pkg.dev/serverless-runtimes/google-18-full/runtimes/nodejs14 |
Node.js 12 | 1. Generation, 2. Generation | Ubuntu 18.04 | nodejs12 | us-central1-docker.pkg.dev/serverless-runtimes/google-18-full/runtimes/nodejs12 |
Node.js 10 | 1. Generation, 2. Generation | Ubuntu 18.04 | nodejs10 | us-central1-docker.pkg.dev/serverless-runtimes/google-18-full/runtimes/nodejs10 |
Node.js 8 | 1. Generation, 2. Generation | Ubuntu 18.04 | nodejs8 | Außer Betrieb genommen |
Node.js 6 | 1. Generation, 2. Generation | Ubuntu 18.04 | nodejs6 | Außer Betrieb genommen |
Python
Laufzeit | Generierung | Umgebung | Laufzeit-ID | Laufzeit-Image |
---|---|---|---|---|
Python 3.12 | 1. Generation, 2. Generation | Ubuntu 22.04 | python312 | us-central1-docker.pkg.dev/serverless-runtimes/google-22-full/runtimes/python312 |
Python 3.11 | 1. Generation, 2. Generation | Ubuntu 22.04 | python311 | us-central1-docker.pkg.dev/serverless-runtimes/google-22-full/runtimes/python311 |
Python 3.10 | 1. Generation, 2. Generation | Ubuntu 22.04 | python310 | us-central1-docker.pkg.dev/serverless-runtimes/google-22-full/runtimes/python310 |
Python 3.9 | 1. Generation, 2. Generation | Ubuntu 18.04 | python39 | us-central1-docker.pkg.dev/serverless-runtimes/google-18-full/runtimes/python39 |
Python 3.8 | 1. Generation, 2. Generation | Ubuntu 18.04 | python38 | us-central1-docker.pkg.dev/serverless-runtimes/google-18-full/runtimes/python38 |
Python 3.7 | 1. Generation | Ubuntu 18.04 | python37 | us-central1-docker.pkg.dev/serverless-runtimes/google-18-full/runtimes/python37 |
Go
Java
Laufzeit | Generierung | Umgebung | Laufzeit-ID | Laufzeit-Image |
---|---|---|---|---|
Java 21 | 2. Generation | Ubuntu 22.04 | java21 | us-central1-docker.pkg.dev/serverless-runtimes/google-22-full/runtimes/java21 |
Java 17 | 1. Generation, 2. Generation | Ubuntu 22.04 | java17 | us-central1-docker.pkg.dev/serverless-runtimes/google-22-full/runtimes/java17 |
Java 11 | 1. Generation, 2. Generation | Ubuntu 18.04 | java11 | us-central1-docker.pkg.dev/serverless-runtimes/google-18-full/runtimes/java11 |
Ruby
Laufzeit | Generierung | Umgebung | Laufzeit-ID | Laufzeit-Image |
---|---|---|---|---|
Ruby 3.3 | 1. Generation, 2. Generation | Ubuntu 22.04 | ruby33 | us-central1-docker.pkg.dev/serverless-runtimes/google-22-full/runtimes/ruby32 |
Ruby 3.2 | 1. Generation, 2. Generation | Ubuntu 22.04 | ruby32 | us-central1-docker.pkg.dev/serverless-runtimes/google-22-full/runtimes/ruby32 |
Ruby 3.0 | 1. Generation, 2. Generation | Ubuntu 18.04 | ruby30 | us-central1-docker.pkg.dev/serverless-runtimes/google-18-full/runtimes/ruby30 |
Ruby 2.7 | 1. Generation, 2. Generation | Ubuntu 18.04 | ruby27 | us-central1-docker.pkg.dev/serverless-runtimes/google-18-full/runtimes/ruby27 |
Ruby 2.6 | 1. Generation, 2. Generation | Ubuntu 18.04 | ruby26 | us-central1-docker.pkg.dev/serverless-runtimes/google-18-full/runtimes/ruby26 |
PHP
Laufzeit | Umgebung | Generierung | Laufzeit-ID | Laufzeit-Image |
---|---|---|---|---|
PHP 8.3 | 2. Generation | Ubuntu 22.04 | php83 | us-central1-docker.pkg.dev/serverless-runtimes/google-22-full/runtimes/php83 |
PHP 8.2 | 1. Generation, 2. Generation | Ubuntu 22.04 | php82 | us-central1-docker.pkg.dev/serverless-runtimes/google-22-full/runtimes/php82 |
PHP 8.1 | 1. Generation, 2. Generation | Ubuntu 18.04 | php81 | us-central1-docker.pkg.dev/serverless-runtimes/google-18-full/runtimes/php81 |
PHP 7.4 | 1. Generation, 2. Generation | Ubuntu 18.04 | php74 | us-central1-docker.pkg.dev/serverless-runtimes/google-18-full/runtimes/php74 |
.NET Core
Laufzeit | Generierung | Umgebung | Laufzeit-ID | Laufzeit-Image |
---|---|---|---|---|
.NET Core 8 | 2. Generation | Ubuntu 22.04 | dotnet8 | us-central1-docker.pkg.dev/serverless-runtimes/google-22-full/runtimes/dotnet8 |
.NET Core 6 | 1. Generation, 2. Generation | Ubuntu 22.04 | dotnet6 | us-central1-docker.pkg.dev/serverless-runtimes/google-22-full/runtimes/dotnet6 |
.NET Core 3 | 1. Generation, 2. Generation | Ubuntu 18.04 | dotnet3 | us-central1-docker.pkg.dev/serverless-runtimes/google-18-full/runtimes/dotnet3 |
Verhalten von Autoscaling
Cloud Run Functions ist eine serverlose Umgebung. Sie müssen sich bei der Codeausführung also nicht um die darunterliegende Infrastruktur wie Server oder virtuelle Maschinen kümmern. Nach der Bereitstellung werden die Funktionen automatisch verwaltet und skaliert.
Cloud Run Functions verarbeitet eingehende Anfragen, indem diese den Instanzen Ihrer Funktion zugewiesen werden. Abhängig von der Anzahl der Anfragen sowie der Anzahl der vorhandenen Funktionsinstanzen kann Cloud Run Functions eine Anfrage einer vorhandenen Instanz zuweisen oder eine neue erstellen.
Wenn das Volumen der eingehenden Anfragen die Anzahl der vorhandenen Instanzen überschreitet, kann Cloud Run Functions mehrere neue Instanzen zur Verarbeitung von Anfragen starten. Dieses automatische Skalierungsverhalten ermöglicht es Cloud Run Functions, viele Anfragen parallel zu verarbeiten, wobei jede eine andere Instanz Ihrer Funktion verwendet.
In einigen Fällen kann eine unbegrenzte Skalierung unerwünscht sein. Zur Behebung dieses Problems können Sie in Cloud Run Functions eine maximale Anzahl von Instanzen konfigurieren, die zu einer bestimmten Zeit für eine bestimmte Funktion koexistieren können.
Zustandslosigkeit
Wenn Sie die automatische Verwaltung und Skalierung der Funktionen aktivieren möchten, müssen sie zustandslos sein. Ein Funktionsaufruf darf nicht auf dem Speicherzustand basieren, der durch einen vorherigen Aufruf festgelegt wurde. Aufrufe können von verschiedenen Funktionsinstanzen verarbeitet werden, die nicht die gleichen globalen Variablen, Speicher, Dateisysteme oder andere Zustände haben.
Wenn Sie den Status für Funktionsaufrufe freigeben müssen, sollte die Funktion einen Dienst wie Memorystore, Datastore, Firestore oder Cloud Storage verwenden, um Daten zu speichern. Weitere Informationen zu Datenbank- und Speicheroptionen von Google Cloud finden Sie unter Google Cloud-Datenbanken und Google Cloud-Speicherprodukte.
Gleichzeitigkeit
Cloud Run-Funktionen (2. Generation)
Cloud Run Functions (2. Generation) unterstützt die Verarbeitung mehrerer gleichzeitiger Anfragen auf einer einzelnen Funktionsinstanz. Dies kann hilfreich sein, um Kaltstarts zu verhindern, da eine bereits vorbereitete Instanz mehrere Anfragen gleichzeitig verarbeiten kann, wodurch die Gesamtlatenz verringert wird. Weitere Informationen finden Sie unter Nebenläufigkeit.
Cloud Run Functions (1. Generation)
In Cloud Run Functions (1. Generation) wird von jeder Instanz einer Funktion jeweils nur eine gleichzeitige Anfrage verarbeitet. Das bedeutet, dass keine zweite Anfrage an dieselbe Instanz weitergeleitet werden kann, während Ihr Code eine Anfrage verarbeitet. Die ursprüngliche Anfrage kann also die gesamte von Ihnen zugewiesene Anzahl von Ressourcen (Arbeitsspeicher und CPU) nutzen.
Da gleichzeitige Anfragen in Cloud Run Functions (1. Generation) von verschiedenen Funktionsinstanzen verarbeitet werden, teilen diese keine Variablen oder lokalen Arbeitsspeicher. Weitere Informationen finden Sie unter Zustandslosigkeit und Lebensdauer von Funktionsinstanzen.
Kaltstarts
Eine neue Funktionsinstanz wird in zwei Fällen gestartet:
Wenn Sie die Funktion bereitstellen
Wenn die Funktion als Reaktion auf eine gestiegene Arbeitslast oder als Ersatz für eine andere Instanz automatisch erstellt wird.
Beim Starten einer neuen Funktionsinstanz werden die Laufzeit und der Code geladen. Anfragen, die den Start einer Funktionsinstanz (Kaltstart) enthalten, können langsamer sein als Anfragen, die an vorhandene Funktionsinstanzen weitergeleitet werden. Wenn Ihre Funktion eine konstante Workload verarbeitet, ist die Anzahl der Kaltstarts normalerweise vernachlässigbar, es sei denn, sie stürzt häufig ab und die Funktionsumgebung muss neu gestartet werden.
Wenn Ihr Funktionscode eine nicht abgefangene Ausnahme auslöst oder den aktuellen Prozess zum Abstürzen bringt, kann die Funktionsinstanz neu gestartet werden. Das kann zu Kaltstarts und damit einer höheren Latenz führen. Daher empfehlen wir, Ausnahmen abzufangen und andernfalls die Beendigung des aktuellen Prozesses zu vermeiden. Unter Fehler melden erfahren Sie, wie Sie Fehler in Cloud Run Functions verarbeiten und melden.
Wenn Ihre Funktion latenzempfindlich ist, sollten Sie eine Mindestzahl von Instanzen festlegen, um Kaltstarts zu vermeiden.
Lebensdauer einer Funktionsinstanz
Funktionsinstanzen sind in der Regel ausfallsicher und werden von nachfolgenden Funktionsaufrufen wiederverwendet, es sei denn, die Anzahl der Instanzen wird verkleinert, da der laufende Traffic fehlt oder die Funktion abstürzt. Das bedeutet, wenn eine Funktionsausführung endet, kann dieselbe Funktionsinstanz einen weiteren Funktionsaufruf verarbeiten.
Funktionsbereich oder globaler Bereich
Beim Aufrufen einer einzelnen Funktion wird nur der als Einstiegspunkt deklarierte Funktionsteil ausgeführt. Der globale Geltungsbereich des Funktionsquellcodes wird nur bei Kaltstarts und nicht bei Instanzen ausgeführt, die bereits initialisiert wurden.
Node.js
Python
Go
Java
Ruby
Sie können globale Variablen als Leistungsoptimierung verwenden. Sie dürfen sich jedoch bei vorherigen Funktionsaufrufen nicht auf den im globalen Bereich festgelegten Status verlassen. Weitere Informationen finden Sie unter Zustandslosigkeit.
Sie können davon ausgehen, dass für jede Funktionsinstanz der globale Geltungsbereich genau einmal ausgeführt wurde, bevor Ihr Funktionscode aufgerufen wird. Sie dürfen jedoch nicht von der Gesamtzahl oder dem Zeitpunkt der Ausführungen im globalen Bereich abhängig sein, da diese je nach Autoscaling-Aktivität variieren können.
Zeitlicher Ablauf der Funktionsausführung
Eine Funktion hat nur für die Dauer der Funktionsausführung Zugriff auf die zugewiesenen Ressourcen (Speicher und CPU). Code, der außerhalb des Ausführungszeitraums ausgeführt wird, wird nicht garantiert ausgeführt und kann jederzeit angehalten werden. Daher sollten Sie das Ende der Ausführung der Funktion immer korrekt signalisieren und vermeiden, dass Code darüber hinaus ausgeführt wird. Weitere Informationen finden Sie unter HTTP-Funktionen, Hintergrundfunktionen und CloudEvent-Funktionen.
Die Funktionsausführung unterliegt auch der Zeitüberschreitung der Funktion. Weitere Informationen finden Sie unter Funktionszeitlimit.
Berücksichtigen Sie bei der Initialisierung Ihrer Anwendung den zeitlichen Ablauf der Ausführung. Hintergrundaufgaben sollten während der Initialisierung nicht im globalen Bereich erstellt werden, da sie außerhalb der Dauer einer Anfrage ausgeführt werden.
Ausführungsgarantien
Eine Funktion wird normalerweise einmal für jedes eingehende Ereignis aufgerufen. Cloud Run Functions kann den einmaligen Aufruf aufgrund von Unterschieden in den Fehlerszenarien aber nicht in allen Fällen garantieren.
Die maximale oder minimale Häufigkeit, mit der eine Funktion für ein einzelnes Ereignis aufgerufen werden kann, hängt von ihrem Typ ab:
HTTP-Funktionen werden höchstens einmal aufgerufen. Das liegt daran, dass HTTP-Aufrufe synchron erfolgen. Jeder Fehler, der während des Funktionsaufrufs auftritt, wird ohne einen erneuten Versuch zurückgegeben. Es wird erwartet, dass der Aufrufer der HTTP-Funktion die Fehler behandelt und bei Bedarf den Aufruf wiederholt.
Ereignisgesteuerte Funktionen werden mindestens einmal aufgerufen. Das liegt an der asynchronen Behandlung von Ereignissen, bei denen kein Aufrufer auf die Antwort wartet. In seltenen Fällen kann es vorkommen, dass das System eine ereignisgesteuerte Funktion mehr als einmal aufruft, um die Zustellung des Ereignisses sicherzustellen. Wenn ein ereignisbasierter Funktionsaufruf mit einem Fehler fehlschlägt, wird die Funktion nur dann wieder aufgerufen, wenn für diese Funktion Wiederholungsversuche bei Fehlern aktiviert sind.
Damit sich die Funktion bei wiederholten Ausführungsversuchen korrekt verhält, sollten Sie sie idempotent machen, indem Sie sie so implementieren, dass die gewünschten Ergebnisse (und Nebeneffekte) auch dann erzeugt werden, wenn ein Ereignis mehrmals bereitgestellt wird. Für HTTP-Funktionen bedeutet das, dass der gewünschte Wert geliefert wird, selbst wenn der Aufrufer die Aufrufe an den HTTP-Funktionsendpunkt wiederholt. Weitere Informationen dazu, wie Sie Ihre Funktion idempotent machen, finden Sie unter Ereignisgesteuerte Funktionen wiederholen.
Speicher- und Dateisystem
Jeder Funktion ist eine bestimmte Menge an Arbeitsspeicher zugewiesen. Sie können die Speichermenge während der Bereitstellung konfigurieren. Weitere Informationen finden Sie unter Speicherlimits.
Die Funktionsausführungsumgebung enthält ein speicherinternes Dateisystem, das die mit Ihrer Funktion bereitgestellten Quelldateien und Verzeichnisse enthält (siehe Quellcode strukturieren). Das Verzeichnis mit den Quelldateien ist schreibgeschützt, der Rest des Dateisystems ist jedoch beschreibbar (außer für Dateien, die vom Betriebssystem verwendet werden). Die Verwendung des Dateisystems wird auf die Speichernutzung einer Funktion angerechnet.
Ihre Funktion kann mithilfe von Standardmethoden in jeder Programmiersprache mit dem Dateisystem interagieren.
Netzwerk
Die Funktion kann über Standardmethoden in jeder Programmiersprache auf das öffentliche Internet zugreifen, sei es über integrierte Bibliotheken, die von den Laufzeitbibliotheken oder Drittanbieterbibliotheken angeboten werden, die Sie als Abhängigkeiten hinzufügen.
Versuchen Sie, Netzwerkverbindungen in mehreren Funktionsaufrufen wiederzuverwenden, wie unter Netzwerke optimieren beschrieben. Eine Verbindung, die 10 Minuten lang nicht verwendet wurde, wird vom System möglicherweise geschlossen. Weitere Versuche, eine geschlossene Verbindung zu verwenden, führen zu einem Fehler "Verbindung zurückgesetzt". Ihr Code sollte daher entweder eine Bibliothek verwenden, die geschlossene Verbindungen verarbeiten kann, oder diese explizit behandeln, wenn Netzwerkkonstrukte auf niedriger Ebene verwendet werden.
Funktionsisolation
Jede bereitgestellte Funktion ist von allen anderen Funktionen isoliert, selbst wenn diese von derselben Quelldatei stammen. Sie teilen weder Arbeitsspeicher, globale Variablen, Dateisysteme noch andere Zustände.
Zur Freigabe von Daten für alle bereitgestellten Funktionen können Sie Dienste wie Memorystore, Datastore, Firestore oder Cloud Storage verwenden. Alternativ können Sie mit den entsprechenden Triggern eine Funktion aus einer anderen aufrufen und die erforderlichen Daten weitergeben. Führen Sie zum Beispiel eine HTTP-Anfrage an den Endpunkt einer HTTP-Funktion aus oder veröffentlichen Sie eine Nachricht an ein Pub- / Sub-Thema, um eine Pub/Sub-Funktion auszulösen.