All Products
Search
Document Center

Function Compute:Function instance lifecycle

Last Updated:Jan 23, 2024

Function Compute provides hooks based on lifecycles of instances. Hooks can be used to address pain points such as metric data delay or loss when you migrate traditional applications to serverless architectures. This topic describes runtime extensions of Function Compute, how to configure PreFreeze and PreStop hooks, and how to query the logs of hooks.

Background information

Pain points of migrating traditional applications to serverless architectures

The billing interval for traditional long-running virtual machines or managed container services often starts when an instance is started and ends when the instance is stopped. You are charged even when no requests are executed within the billing interval. The billing granularity of Function Compute is one millisecond. Instances are billed only during the execution of requests. The instances are frozen in time periods where no requests are executed. This way, unnecessary costs incurred by idle instances that use the fully event-driven billing model can be avoided. However, the freeze mechanism shatters the hypotheses about the long-running processes in traditional architectures and makes it difficult to migrate applications. Function Compute runs in a special environment. The system cannot track and report data as expected in scenarios where there is no cold start, such as scenarios in which distributed Managed Service for OpenTelemetry libraries or third-party application performance management (APM) solutions are used.

The following pain points hinder the smooth migration of traditional applications to a serverless architecture:

  • Data of asynchronous background metrics is delayed or lost. If the data fails to be sent during the execution of a request, the data may be delayed until the time point when the next request is sent, or the data points are discarded.

  • The latency is increased if metric data is synchronously sent. If a method similar to Flush is called after each request is completed, the latencies of requests are increased and excessive workloads are generated on backend servers.

  • To support graceful shutdown of function instances, applications need to close connections, stop processes, and report status when instances are stopped. Developers do not know when instances are released in Function Compute. In addition, no webhook is provided to send notifications about release events of function instances.

image

Programming model extensions

Function Compute provides runtime extensions to address the preceding pain points. The extensions extend the existing programming model for HTTP servers by adding the PreFreeze and PreStop hooks to the existing HTTP server model. This way, extension developers can use HTTP handlers to monitor lifecycle events of function instances.

image
  • PreFreeze

    Each time Function Compute decides to freeze the current function instance, Function Compute sends an HTTP GET request to the /pre-freeze path. Extension developers implement the logic to ensure that specified operations are performed before the instance is frozen. For example, the instance waits until metrics are sent. The duration to execute the PreFreeze hook is not included in the duration to call the InvokeFunction operation.

    image
  • PreStop

    Each time Function Compute decides to stop the current function instance, Function Compute sends an HTTP GET request to the /pre-stop path. Extension developers implement the logic to ensure that the specified operations, such as database connection closing or status reporting or update, are completed before the instance is released.

    image

Prerequisites

A function is created. For more information, see Create a function.

Limits

  • The input parameters of the PreFreeze and PreStop hooks do not include the event parameter.

  • The PreFreeze and PreStop hooks do not return values. The logic that is appended to the PreFreeze hook or the PreStop hook to return values does not take effect.

  • You can configure PreStop hooks in all runtimes. However, you cannot configure the PreFreeze hook in Python, PHP, or C# runtimes.

  • If you use a Java runtime, you must update fc-java-core to version 1.4.0 or later. Otherwise, you cannot use the PreFreeze hook or the PreStop hook. For more information, see HTTP handler.

  • If your custom container runtime is in non-web server mode, the PreFreeze and PreStop hooks that you configured do not take effect.

  • When a function returns responses, Function Compute freezes the function instance. You cannot assume that all asynchronous processes, threads, and coroutines are executed when the invocation returns. You cannot also assume that the logs that are asynchronously written are refreshed.

Configure PreFreeze and PreStop hooks

Note

The billing for PreFreeze or PreStop calls is the same as that for InvokeFunction calls. For more information, see Billing overview.

Configure hooks in the Function Compute console

When you use the Function Compute console to create a function, you cannot configure the PreFreeze and PreStop hooks. You can configure the PreFreeze hook and PreStop hook when you update the function.

  1. Log on to the Function Compute console. In the left-side navigation pane, click Services & Functions.

  2. In the top navigation bar, select a region. On the Services page, click the desired service.

  3. On the Functions page, find the function that you modify and click Configure in the Actions column.
  4. In the Instance Lifecycle Hook section of the Modify Function Settings page, configure the hooks and timeout periods, and then click Save.

    配置生命周期函数

    Note

    You must configure a hook and timeout period for each extension function. The format of the hook is [File name].[Extension function name]. For example, if you set the PreStop hook to index.preStopHandler when you create a function in a Python runtime, the file name is index.py and the name of the PreStop function is preStopHandler.

  5. After you configure the extension function, implement the function in the code that you want to execute.

    1. Click the Code tab. In the code editor, enter the code of the extension function.

      For example, if you set the PreStop hook to index.preStopHandler, you must implement the preStopHandler function. For more information about how to implement lifecycle hooks in different runtimes of Function Compute, see Lifecycle hooks for function instances.

      Note

      The online IDE is supported by PHP, Python, Node.js, and custom runtimes but not supported by runtimes of compiled languages such as Java, Go, .NET, or custom container runtimes.

    2. Click Deploy in the upper part of the code editor, and then click Test Function.

Configure hooks by using Serverless Devs

The following sample code of s.yaml can be used to configure the PreFreeze and PreStop by using Serverless Devs:

  codeUri: './code.zip'
  ......
  instanceLifecycleConfig:
    preFreeze:
      handler: index.PreFreeze
      timeout: 60
    preStop:
      handler: index.PreStop
      timeout: 60

To disable an extension function, leave the Handler parameter of the extension function empty. Otherwise, the function is not updated by default. For example, to disable the PreFreeze hook, you can deploy and update the function based on the following configuration. In this case, the Timeout parameter of the PreFreeze hook is invalid.

  codeUri: './code.zip'
  ......
  instanceLifecycleConfig:
    preFreeze:
      handler: ""
      timeout: 60
    preStop:
      handler: index.PreStop
      timeout: 60

For more information about how to implement lifecycle hooks in different runtimes of Function Compute, see Lifecycle hooks for function instances.

Configure hooks by using SDKs

You can use SDKs to deploy and update extensions. This section describes how to obtain the SDK sample code for configuring the PreStop and PreFreeze hooks when you create a function.

  1. On the CreateFunction page, click Debug to go to the OpenAPI portal.

  2. On the Parameters tab, configure Request Parameters based on the basic information of the function.

    You can configure the PreStop and PreFreeze hooks in instanceLifecycleConfig.

    image.png

  3. After you configure the parameters, click the SDK Sample Code tab to obtain the SDK sample code in the corresponding programming language.

For more information about how to implement lifecycle hooks in different runtimes of Function Compute, see Lifecycle hooks for function instances.

Lifecycle hooks for function instances

The following table describes how to implement lifecycle hooks in different runtimes of Function Compute.

Environment Information

Method to implement lifecycle hooks

Reference

Node.js

Use Node.js to implement lifecycle hooks for function instances.

Lifecycle hooks for function instances

Python

Use Python to implement lifecycle hooks for function instances.

Lifecycle hooks for function instances

PHP

Use PHP to implement lifecycle hooks for function instances.

Lifecycle hooks for function instances

Java

Use Java to implement lifecycle hooks for function instances.

Lifecycle hooks for function instances

C#

Use C# to implement lifecycle hooks for function instances.

Lifecycle hooks for function instances

Go

Use Go to implement lifecycle hooks for function instances.

Lifecycle hooks for function instances

Custom Runtime

Use a custom runtime to implement lifecycle hooks for function instances.

Lifecycle hooks for function instances

Custom Container

Use a Custom Container runtime for which web server mode is enabled to implement lifecycle hooks for function instances.

Lifecycle hooks for function instances

Query logs related to hooks

After you configure an instance lifecycle hook and execute the code of the hook, you can query the logs of the hook.

  1. Log on to the Function Compute console. In the left-side navigation pane, click Services & Functions.

  2. In the top navigation bar, select a region. On the Services page, click the desired service.

  3. On the Functions page, click the function that you want to manage and click the Logs tab.

  4. On the Request List tab, find the request that you want to query, copy the Instance ID, and then click SLS Logs.

    You can use the copied instance ID to query the start and end logs of all lifecycle hooks. You can also use the instance ID together with a hook keyword to query the start and end logs of a specified hook, such as c-62833f38-20f1629801fa4bd***** and PreStop.db_lifecycle_log

    You can also query request logs based on request IDs in the Start logs and the End logs. If a user log does not contain a request ID, you can click the db_lifecycle_log_context icon to obtain the context log.

Billing rules

You are not charged for the number of requests sent to the HTTP hooks. The extensions are also applicable to scenarios in which multiple concurrent requests are executed on a single instance. If multiple invocation requests are concurrently executed on the same instance, after all the requests are executed, the PreFreeze hook is called before the instance is frozen.

In the example shown in the following figure, the specification of the function is 1 GB. Assume that the period from t1 when PreFreeze starts to t6 when Request 2 is completed is 1s. The execution time of the instance is calculated based on the following formula: t6 - t1. The consumed resource is calculated based on the following formula: 1s × 1 GB = 1 CU. For more information about billing, see Billing overview.

image