Les hooks de cycle de vie permettent d'exécuter une logique personnalisée à deux moments clés du cycle de vie d'une instance de fonction : après son démarrage (hook Initializer) et avant sa destruction (hook PreStop). Cette rubrique explique comment implémenter et configurer ces deux hooks pour les fonctions Java.
Utilisez les hooks de cycle de vie pour amortir les coûts d'initialisation élevés sur plusieurs invocations :
Initializer hook : Récupérez les identifiants de base de données depuis les variables d'environnement et ouvrez un pool de connexions une seule fois. Toutes les invocations suivantes sur la même instance réutilisent cette connexion, ce qui réduit la latence et les coûts.
PreStop hook : Fermez les connexions à la base de données ou videz l'état en mémoire avant le recyclage de l'instance afin d'éviter les fuites de ressources.
Pour les fonctions PHP, consultez Configurer les cycles de vie des instances.
Fonctionnement
Function Compute exécute chaque instance selon trois phases :
| Phase | Moment | Exécution |
|---|---|---|
| Init | Démarrage de l'instance, avant toute invocation | Hook Initializer (une fois) |
| Invoke | À chaque requête | Votre handler |
| Shutdown | Juste avant la destruction de l'instance | Hook PreStop |
Comportement du hook Initializer :
S'exécute exactement une fois durant le cycle de vie de l'instance, après le démarrage et avant la première invocation du handler.
En cas d'échec du hook Initializer, Function Compute le relance jusqu'à succès, puis exécute votre handler.
Rendez le hook idempotent pour gérer les nouvelles tentatives en toute sécurité. Par exemple, vérifiez si un pool de connexions existe déjà avant d'en créer un ; si le pool n'est pas null, ignorez l'initialisation. Cela évite les connexions dupliquées lors des nouvelles tentatives.
Comportement du hook PreStop :
S'exécute avant la destruction de l'instance.
Les instances étant mises en cache pendant un certain temps avant destruction, le hook PreStop ne s'exécute pas immédiatement après la dernière invocation.
Facturation
L'exécution des hooks de cycle de vie est facturée comme les invocations classiques. Les journaux d'exécution des hooks apparaissent dans Function Logs, Real-time Logs et Advanced Logs, mais pas dans la liste des requêtes d'invocation.
Implémenter les hooks
Hook Initializer
Implémentez l'interface FunctionInitializer ainsi que sa méthode initialize(Context context).
Définition de l'interface :
package com.aliyun.fc.runtime;
import java.io.IOException;
/**
* This is the interface for the initialization operation
*/
public interface FunctionInitializer {
/**
* The interface to handle a function compute initialize request
*
* @param context The function compute initialize environment context object.
* @throws IOException IOException during I/O handling
*/
void initialize(Context context) throws IOException;
}
Hook PreStop
Implémentez l'interface PreStopHandler ainsi que sa méthode preStop(Context context).
Définition de l'interface :
package com.aliyun.fc.runtime;
import java.io.IOException;
/**
* This is the interface for the preStop operation
*/
public interface PreStopHandler {
/**
* The interface to handle a function compute preStop request
*
* @param context The function compute preStop environment context object.
* @throws IOException IOException during I/O handling
*/
void preStop(Context context) throws IOException;
}
Exemple complet : StreamRequestHandler avec les deux hooks
package example;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import com.aliyun.fc.runtime.Context;
import com.aliyun.fc.runtime.StreamRequestHandler;
import com.aliyun.fc.runtime.FunctionInitializer;
import com.aliyun.fc.runtime.PreStopHandler;
public class App implements StreamRequestHandler, FunctionInitializer, PreStopHandler {
@Override
public void initialize(Context context) throws IOException {
context.getLogger().info("initialize start ...");
}
@Override
public void handleRequest(
InputStream inputStream, OutputStream outputStream, Context context) throws IOException {
context.getLogger().info("handlerRequest ...");
outputStream.write(new String("hello world\n").getBytes());
}
@Override
public void preStop(Context context) throws IOException {
context.getLogger().info("preStop start ...");
}
}
Remarque :InputStreamrenvoie les données par blocs. Ce n'est pas le cas deOutputStream.
Configurer les hooks de cycle de vie
Via la console Function Compute
Sur la page de détails de la fonction dans la console Function Compute, définissez les champs des hooks au format [Nom du package].[Nom de la classe]::[Nom de la méthode].

Pour la classe d'exemple ci-dessus :
Initializer Hook :
example.App::initializePreStop Hook :
example.App::preStop
Via Serverless Devs
Ajoutez instanceLifecycleConfig sous function dans s.yaml, avec les sous-clés initializer et preStop. Chaque sous-clé prend un handler et un timeout (en secondes).
# ------------------------------------
# Official manual: https://manual.serverless-devs.com/user-guide/aliyun/#fc3
# Tips: https://manual.serverless-devs.com/user-guide/tips/
# If you have any questions, join the DingTalk group 33947367 for technical support.
# ------------------------------------
edition: 3.0.0
name: hello-world-app
access: "default"
vars: # The global variables
region: "cn-hangzhou"
resources:
hello_world:
component: fc3
actions:
pre-${regex('deploy|local')}:
- run: mvn package -DskipTests
path: ./
props:
region: ${vars.region}
functionName: "start-java-1xqf"
description: 'hello world by serverless devs'
runtime: "java8"
code: ./target/HelloFCJava-1.0-SNAPSHOT-jar-with-dependencies.jar
handler: example.App::handleRequest
memorySize: 128
timeout: 10
instanceLifecycleConfig: # The extension function
initializer: # The Initializer hook
handler: example.App::initialize
timeout: 60
preStop: # The PreStop hook
handler: example.App::preStop # The function handler
timeout: 60 # The timeout period.
Pour la référence complète de la syntaxe YAML, consultez Commandes courantes de Serverless Devs.
Consulter les journaux des hooks de cycle de vie
Les journaux des hooks apparaissent avec les journaux d'invocation dans Function Logs, mais ne figurent pas dans la liste des requêtes d'invocation.
Connectez-vous à la console Function Compute. Dans le volet de navigation de gauche, cliquez sur Functions.
Dans la barre de navigation supérieure, sélectionnez une région. Sur la page Functions, cliquez sur la fonction à gérer.
Sur la page de détails de la fonction, cliquez sur l'onglet Test Function, puis sur Test Function, et enfin choisissez Logs > Function Logs.
Journaux Initializer :
2024-03-04 17:57:28 FC Initialize Start RequestId: 1-65e59b07-1520da26-bf73bbb91b69
2024-03-04 17:57:28 2024-03-04 09:57:28.192 1-65e59b07-1520da26-bf73bbb91b69 [info] initializer
2024-03-04 17:57:28 FC Initialize End RequestId: 1-65e59b07-1520da26-bf73bbb91b69
2024-03-04 17:57:28 FC Invoke Start RequestId: 1-65e59b07-1520da26-bf73bbb91b69
2024-03-04 17:57:28 FC Invoke End RequestId: 1-65e59b07-1520da26-bf73bbb91b69
Journaux PreStop — déclenchement du hook :
Les instances de fonction étant mises en cache pendant un certain temps avant destruction, les journaux PreStop n'apparaissent pas immédiatement. Pour déclencher PreStop immédiatement, mettez à jour la configuration ou le code de la fonction. Après la mise à jour, les journaux PreStop apparaissent dans Function Logs :
2024-03-04 18:33:26 FC PreStop Start RequestId: 93c93603-9fbe-4576-9458-193c8b213031
2024-03-04 18:33:26 2024-03-04 10:33:26.077 93c93603-9fbe-4576-9458-193c8b213031 [info] preStop
2024-03-04 18:33:26 FC PreStop End RequestId: 93c93603-9fbe-4576-9458-193c8b213031
Étapes suivantes
java11-mysql : Programme d'exemple utilisant un hook Initializer pour récupérer les configurations de base de données depuis les variables d'environnement et ouvrir une connexion MySQL, ainsi qu'un hook PreStop pour la fermer.