When you debug a function on your computer, you can use s proxied
commands to invoke on-premises functions and cloud services. This mechanism is called cloud-terminal joint debugging. The cloud-terminal joint debugging feature helps improve development efficiency. This topic describes the basic principles of cloud-terminal joint debugging and uses examples to describe how to implement cloud-terminal joint debugging and breakpoint debugging. ApsaraDB RDS for MySQL and Apsara File Storage NAS (NAS) are used in the examples.
Usage notes
The cloud-terminal joint debugging feature supports only the x86_64 architecture and does not support the ARM64 architecture.
Principles
In the serverless field, debugging has always been a pain point for developers. Some cloud vendors have provided tools to solve this problem. However, these tools focus on simulating on-premises execution environments and parameters but cannot connect on-premises environments and online environments. Serverless Devs provides the cloud-terminal joint debugging feature, which enables the connection between on-premises and online environments.

ServiceConfig
parameter information in the s.yaml file to create a helper function. The parameter information in the s.yaml file includes the configurations of virtual private clouds (VPCs) and NAS file storage. This way, the helper function (C) has identical service and network configurations as the debugging function. When the channel of cloud-terminal joint debugging is established, you can perform the following operations:
- Access the resources of Alibaba Cloud public cloud from the container environment in which on-premises functions are invoked. For example, you can access the following environments:
- VPC endpoints, such as the VPC endpoints of NAS, ApsaraDB RDS, or Message Queue for Apache Kafka
- Internal networks, such as the internal endpoint of Object Storage Service (OSS)
- Implement inbound traffic, such as the information about the context and event parameters. The inbound traffic represents the actual traffic from cloud services.
You can directly use an SDK or a trigger to invoke the helper function (C). For example, you can use an SDK to run the invocation commands of cloud-terminal joint debugging. The request traffic is returned to the on-premises debugging instance (A). This instance is the container environment in which on-premises functions are executed. In this case, the inbound traffic is the actual traffic from the cloud.
- You must attach the code to an on-premises environment (A), which is the container environment in which on-premise functions are executed.
- You can specify the port mapping between the integrated development environment (IDE) and the container environment by using the
--debug-port
parameter.
Sample code
Sample code | s.yaml example |
---|---|
|
|
Prerequisites
- Install Serverless Devs and Docker
- Configure Serverless Devs
- Optional: Grant permissions on Tunnel Service to a RAM user.
{ "Statement": [ { "Effect": "Allow", "Action": "tns:*", "Resource": "*" } ], "Version": "1" }
If the RAM user has permissions on Tunnel Service, skip this operation. For more information about how to authorize a RAM user by using an Alibaba Cloud account, see Grant permissions to a RAM user by using an Alibaba Cloud account.
- Optional: Download a tool for breakpoint debugging.
- Install Visual Studio Code (VS Code) if you want to use VS Code to perform breakpoint debugging.
- Install the following tools if you use IntelliJ IDEA to perform breakpoint debugging for a Java function:
Procedure
- In the project directory, select one of the following commands based on your business requirements to prepare the helper resources and on-premises environment that are required for cloud-terminal joint debugging.
- If only one project is contained in the s.yaml file, you do not need to specify a project for testing when you run the following command.
s proxied setup
- If multiple projects are contained in the s.yaml file, you must specify the project for testing when you run the following command:
s <projectName> proxied setup
Sample output:[2021-10-08T15:55:16.653] [INFO ] [S-CLI] - Start ... Session created, session id: S-d847ae28-767f-4532-a2f2-307ee2b99c5f. ...... [2021-10-08T15:55:24.580] [INFO ] [FC-DEPLOY] - Checking Trigger httpTrigger exists [2021-10-08T15:55:24.807] [INFO ] [FC-DEPLOY] - Checking Trigger httpTrigger exists Make service SESSION-S-d847a success.// The helper service is deployed. Make function SESSION-S-d847a/http-trigger-py36 success.// The helper function is deployed. Make trigger SESSION-S-d847a/http-trigger-py36/httpTrigger success.// The helper trigger is deployed. ...... There is auto config in the service: SESSION-S-d847a Helper function is set to 1promise and 0elasticity.// The Function Compute (C) container is started. Proxy container is running.// The code container in the on-premises environment (A) is started. Session established! // The session is established. [2021-10-08T15:56:13.251] [INFO ] [FC-PROXIED-INVOKE] - Pulling image registry.cn-beijing.aliyuncs.com/aliyunfc/runtime-python3.6:1.9.19, you can also use 'docker pull registry.cn-beijing.aliyuncs.com/aliyunfc/runtime-python3.6:1.9.19' to pull image by yourself. 1.9.19: Pulling from aliyunfc/runtime-python3.6 ...... Digest: sha256:6a4da97962dba5f6cb00c5e8e83024c4758ec358e5bf884efff897b9826d9454 Status: Downloaded newer image for registry.cn-beijing.aliyuncs.com/aliyunfc/runtime-python3.6:1.9.19 [2021-10-08T15:56:15.694] [INFO ] [FC-PROXIED-INVOKE] - Checking Server in function container is up. exists FunctionCompute python3 runtime inited. FC Invoke End RequestId: unknown_request_id, Error: Unhandled function error [2021-10-08T15:56:16.831] [INFO ] [FC-PROXIED-INVOKE] - Server in function container is up!// The execution environment of Function Compute in the on-premises environment (A) is started. End of method: proxied
Note After the command that you select is executed, the project is blocked and pending to be invoked. The execution environment is an HTTP server. - If only one project is contained in the s.yaml file, you do not need to specify a project for testing when you run the following command.
- Invoke the function.
- HTTP function
- If your function is an anonymous HTTP trigger function, you can use cURL or Postman to invoke the domain name that is temporally generated to implement on-premises debugging. cURL is used in this example.
curl -v http://http-trigger-py36.SESSION-S-d847a.188077086902****.cn-hangzhou.fc.devsapp.net
- If authType of the HTTP trigger is function, perform the following steps to implement debugging of the HTTP function:
- Start a new terminal.
- Run commands to switch to the project directory.
- Run the following command to invoke the function:
s proxied invoke -e '{"body":123,"method":"GET","headers":{"key":"value"},"queries":{"key":"value"},"path":"string"}'
- If your function is an anonymous HTTP trigger function, you can use cURL or Postman to invoke the domain name that is temporally generated to implement on-premises debugging. cURL is used in this example.
- Event function
- Event functions with triggers
This example uses an OSS trigger to describe how to invoke a function in an on-premises environment.
- Confirm the trigger that you want to use to trigger function execution. The trigger can be an OSS trigger or CDN event trigger.
- Log on to the Function Compute console.
- Find the helper function and create a trigger for the function. For more information about how to create an OSS trigger in this example, see Step 1: Create an OSS trigger.
- Log on to the OSS console and trigger the event. For example, you can upload or download files to trigger the execution of the function in the on-premises execution environment.
- Event functions without triggers
Perform the following steps to invoke an event function that is not equipped with a trigger:
- Start a new terminal.
- Run commands to switch to the project directory.
- Run the following command to invoke the function:
s proxied invoke -e '{"key":"value"}'
Important If your event function is equipped with a trigger, you can also use this method to invoke this function in the on-premises environment.
- Event functions with triggers
- HTTP function
- Run the following command to clean the resources and the on-premises environment that are required for cloud-terminal joint debugging.
s proxied cleanup
Sample output:Stop container succeed. Unset helper function provision and on-demand config done. [2021-10-08T16:41:19.960] [INFO ] [FC-DEPLOY] - Using region: cn-hangzhou [2021-10-08T16:41:19.988] [INFO ] [FC-DEPLOY] - Using access alias: default [2021-10-08T16:41:19.989] [INFO ] [FC-DEPLOY] - Using accessKeyID: LTAI4G4cwJkK4Rza6xd9**** [2021-10-08T16:41:19.993] [INFO ] [FC-DEPLOY] - Using accessKeySecret: eCc0GxSpzfq1DVspnqqd6nmYNN**** [2021-10-08T16:41:20.104] [INFO ] [FC-DEPLOY] - Checking Service SESSION-S-a9143 exists [2021-10-08T16:41:20.397] [INFO ] [FC-DEPLOY] - Service: SESSION-S-a9143 already exists online. [2021-10-08T16:41:20.400] [INFO ] [FC-DEPLOY] - Checking Function http-trigger-py36 exists [2021-10-08T16:41:20.583] [INFO ] [FC-DEPLOY] - Function: http-trigger-py36 already exists online. [2021-10-08T16:41:20.586] [INFO ] [FC-DEPLOY] - Checking Trigger httpTrigger exists [2021-10-08T16:41:20.820] [INFO ] [FC-DEPLOY] - Trigger: httpTrigger already exists online. Using fc deploy type: sdk, If you want to deploy with pulumi, you can [s cli fc-default set deploy-type pulumi] to switch. Delete trigger SESSION-S-a9143/http-trigger-py36/httpTrigger success. [TriggerNotFound], DELETE /services/SESSION-S-a9143/functions/http-trigger-py36/triggers/httpTrigger failed with 404. requestid: 9de742e1-d8f6-4db0-a4bd-02b10542147e, message: trigger 'httpTrigger' does not exist in service 'SESSION-S-a9143' and function 'http-trigger-py36'. Delete function SESSION-S-a9143/http-trigger-py36 success. Delete service SESSION-S-a9143 success. Delete session: S-a9143b1a-88ff-48bd-bd79-2f3755397fe2 done. Stop container succeed. End of method: proxied
Note After the cleaning is complete, the blocking between the helper resources and the on-premises environment is removed.
Implement breakpoint debugging
The following section uses Python 3 as an example to describe how to implement breakpoint debugging during cloud-terminal joint debugging:
- Run the following command in the project directory to prepare the helper resources and on-premises environment that is required for cloud-terminal joint debugging.
s proxied setup --config vscode --debug-port 3000
Sample command output:
[2021-10-08T15:55:16.653] [INFO ] [S-CLI] - Start ... Session created, session id: S-d847ae28-767f-4532-a2f2-307ee2b99c5f. [2021-10-08T15:55:18.395] [INFO ] [FC-PROXIED-INVOKE] - Deploying helper function... [2021-10-08T15:55:18.397] [INFO ] [FC-PROXIED-INVOKE] - Creating cleaner service... [2021-10-08T15:55:22.021] [INFO ] [FC-DEPLOY] - Using region: cn-hangzhou [2021-10-08T15:55:22.022] [INFO ] [FC-DEPLOY] - Using access alias: default [2021-10-08T15:55:22.022] [INFO ] [FC-DEPLOY] - Using accessKeyID: LTAI4G4cwJkK4Rza6xd9**** [2021-10-08T15:55:22.022] [INFO ] [FC-DEPLOY] - Using accessKeySecret: eCc0GxSpzfq1DVspnqqd6nmYNN**** Using fc deploy type: sdk, If you want to deploy with pulumi, you can [s cli fc-default set deploy-type pulumi] to switch. [2021-10-08T15:55:22.971] [INFO ] [FC-DEPLOY] - Checking Service SESSION-S-d847a exists [2021-10-08T15:55:23.293] [INFO ] [FC-DEPLOY] - Setting role: AliyunFCDefaultRole [2021-10-08T15:55:23.886] [INFO ] [RAM] - Checking Role AliyunFCDefaultRole exists [2021-10-08T15:55:24.099] [INFO ] [RAM] - Updating role: AliyunFCDefaultRole [2021-10-08T15:55:24.191] [INFO ] [RAM] - Checking Plicy AliyunFCDefaultRolePolicy exists [2021-10-08T15:55:24.300] [INFO ] [FC-DEPLOY] - Checking Function http-trigger-py36 exists [2021-10-08T15:55:24.577] [WARN ] [FC-DEPLOY] - Image registry.cn-hangzhou.aliyuncs.com/aliyunfc/ts-remote:v0.1.1 dose not exist locally. Maybe you need to run 's build' first if it dose not exist remotely. [2021-10-08T15:55:24.580] [INFO ] [FC-DEPLOY] - Checking Trigger httpTrigger exists [2021-10-08T15:55:24.807] [INFO ] [FC-DEPLOY] - Checking Trigger httpTrigger exists Make service SESSION-S-d847a success.// The helper service is deployed. Make function SESSION-S-d847a/http-trigger-py36 success.// The helper function is deployed. Make trigger SESSION-S-d847a/http-trigger-py36/httpTrigger success.// The helper trigger is deployed. [2021-10-08T15:55:26.129] [INFO ] [FC-DEPLOY] - Checking Service SESSION-S-d847a exists [2021-10-08T15:55:26.568] [INFO ] [FC-DEPLOY] - Checking Function http-trigger-py36 exists [2021-10-08T15:55:26.922] [INFO ] [FC-DEPLOY] - Checking Trigger httpTrigger exists [2021-10-08T15:55:27.542] [INFO ] [FC-DEPLOY] - Using customDomain: auto: fc will try to generate related custom domain resources automatically End of request Deployed. End of request [2021-10-08T15:55:35.499] [INFO ] [FC-DEPLOY] - Generated auto custom domain: http-trigger-py36.session-s-d847a.188077086902****.cn-hangzhou.fc.devsapp.net [2021-10-08T15:55:35.499] [INFO ] [FC-DEPLOY] - Creating custom domain: http-trigger-py36.session-s-d847a.188077086902****.cn-hangzhou.fc.devsapp.net [2021-10-08T15:55:35.679] [INFO ] [FC-DOMAIN] - Creating custom domain: http-trigger-py36.session-s-d847a.188077086902****.cn-hangzhou.fc.devsapp.net There is auto config in the service: SESSION-S-d847a Helper function is set to 1promise and 0elasticity.// The Function Compute (C) container is started. Proxy container is running.// The code container in the on-premises environment (A) is started. Session established! // The session is established. [2021-10-08T15:56:13.251] [INFO ] [FC-PROXIED-INVOKE] - Pulling image registry.cn-beijing.aliyuncs.com/aliyunfc/runtime-python3.6:1.9.19, you can also use 'docker pull registry.cn-beijing.aliyuncs.com/aliyunfc/runtime-python3.6:1.9.19' to pull image by yourself. 1.9.19: Pulling from aliyunfc/runtime-python3.6 ...... Digest: sha256:6a4da97962dba5f6cb00c5e8e83024c4758ec358e5bf884efff897b9826d9454 Status: Downloaded newer image for registry.cn-beijing.aliyuncs.com/aliyunfc/runtime-python3.6:1.9.19 [2021-10-08T15:56:15.694] [INFO ] [FC-PROXIED-INVOKE] - Checking Server in function container is up. exists FunctionCompute python3 runtime inited. FC Invoke End RequestId: unknown_request_id, Error: Unhandled function error [2021-10-08T15:56:16.831] [INFO ] [FC-PROXIED-INVOKE] - Server in function container is up!// The execution environment of Function Compute in the on-premises environment (A) is started. End of method: proxied
After the command is executed, the project is blocked and pending to be invoked. If you directly run the invocation command, the function is invoked in an on-premises environment. If breakpoint debugging is required, add a breakpoint (①) to the code of a function in the sidebar of the VS Code editor, and then click the debugging icon (②).
- Start a new terminal and run the following command to invoke the function.
s proxied invoke
After you run the debugging command, go back to the VS Code interface. Breakpoint debugging is started for the function.
- Run the following command to clean the helper resources, sessions, and on-premises debugging container:
s proxied clean
The following sample Java 8 code describes how to use IntelliJ IDEA to implement breakpoint debugging:
- Run the following command in the project directory to install dependencies:
s build --use-docker
Sample command output:
[2021-10-09T15:28:39.391] [INFO ] [S-CLI] - Start ... [2021-10-09T15:28:40.520] [INFO ] [FC-BUILD] - Build artifact start... [2021-10-09T15:28:40.548] [INFO ] [FC-BUILD] - Use docker for building. [2021-10-09T15:28:40.867] [INFO ] [FC-BUILD] - Build function using image: registry.cn-beijing.aliyuncs.com/aliyunfc/runtime-java8:build-1.9.21 [2021-10-09T15:28:41.411] [INFO ] [FC-BUILD] - begin pulling image registry.cn-beijing.aliyuncs.com/aliyunfc/runtime-java8:build-1.9.21, you can also use docker pull registry.cn-beijing.aliyuncs.com/aliyunfc/runtime-java8:build-1.9.21 to pull image by yourself. build-1.9.21: Pulling from aliyunfc/runtime-java8 ...... Digest: sha256:35eb46f6235729dbcb1fa48f4ce4ae7b213b967a0f1b9c625e464dbba58af22d Status: Downloaded newer image for registry.cn-beijing.aliyuncs.com/aliyunfc/runtime-java8:build-1.9.21 [2021-10-09T15:30:52.690] [INFO ] [FC-BUILD] - Build artifact successfully. Tips for next step ====================== * Invoke Event Function: s local invoke * Invoke Http Function: s local start * Deploy Resources: s deploy End of method: build
- Run the following command to prepare helper resources and the on-premises environment that are required for cloud-terminal joint debugging.
s proxied setup --debug-port 3000
After the command is executed, the project is blocked and pending to be invoked. If you directly run the invocation command, the function is invoked in the on-premises environment. If you require breakpoint debugging, you must configure IntelliJ IDEA when you perform breakpoint debugging for the first time.
- Open IntelliJ IDEA, and then open the corresponding project directory. In the top navigation bar of IntelliJ IDEA, choose Run > Debug Configurations.
- In the Run/Debug Configurations dialog box, click the plus icon and select Remote to configure the parameters:
- Name: the name of the custom debugger.
- Port: the port number. Set the value to 3000. If you set
--debug-port
to another port number for cloud-terminal joint debugging, set Port to the same port number as that of --debug-port.
- Click ok. The IntelliJ IDEA configuration is complete.
- Add a breakpoint for the code of a function in the sidebar of the IDEA editor (①) and click the debug icon (②).
- Start a new terminal and run the following command to invoke the function.
s proxied invoke
After you run the debugging command, go back to the IntelliJ IDEA interface. Breakpoint debugging is started for the function.
- Run the following command to clean the helper resources, sessions, and on-premises debugging container:
s proxied clean