阿里云 Serverless Computing + 关注
手机版

Guidelines for Function Compute Development - Use Fun Local for Local Running and Debugging

  1. 云栖社区>
  2. 阿里云 Serverless Computing>
  3. 博客>
  4. 正文

Guidelines for Function Compute Development - Use Fun Local for Local Running and Debugging

tanhe123 发布时间:2019-01-11 16:36:11 浏览171 评论0

摘要: Preface The following key concepts are involved in this document: Function Compute: an event-driven service that allows you to focus on writing and .

Preface

The following key concepts are involved in this document:

Function Compute: an event-driven service that allows you to focus on writing and uploading codes, without the need to manage infrastructures such as servers.Function Compute provides computing resources, allowing you to run codes flexibly. You just need to pay for the resources consumed for code running.For more information about Function Compute, see.

Fun: a tool that supports serverless application deployment. It helps you easily arrange resources such as Function Compute, API Gateway, and Log Service.You can use Fun to develop, build, and deploy applications by describing resources in the resource configuration file (template.yml).For more information about Fun, see.

With a significantly improved deployment experience, Fun V2.0 provides more functions to help you easily and smoothly deploy resources to the cloud.However, Fun V2.0's local development experience still has much room for improvement.To this end, we have launched Fun Local.

Fun Local: a subcommand of Fun. It can be used directly by running the fun local command if your Fun version is V2.6.0 or later.Fun Local supports local stimulation for the running of functions in Function Compute and provides a single-step debugging function. It aims to fill the gap between Function Compute and traditional tools in terms of the application development experience and provide a new way to troubleshoot issues in Function Compute.

As a part of the Guidelines for Function Compute Development document series, this document describes how to use Fun Local, while the other documents describe the significant boost to function compute development efficiency provided by Fun Local.

Fun Local syntax

Run the fun local invoke -h command to view help information for fun local invoke:

$ fun local invoke -h
  Usage: invoke [options] <[service/]function>

  Run your serverless application locally for quick development & testing.

  Options:

    -d, --debug-port <port>  used for local debugging
    -c, --config <ide>       print out ide debug configuration. Options are VSCode
    -e, --event <path>       event file containing event data passed to the function
    -h, --help               output usage information

Run a function locally

The syntax for running a function is as follows:

fun local invoke [options] <[service/]function>

where, options and service can be omitted.
In terms of call methods, the fun local invoke command can call a function by function name or service name/function name, that is:

fun local inovke function
fun local inovke service/function

For example, to run a function named php72, run the following command:

fun local invoke php72

The call result is as follows.

For another example, to run a function named nodejs8, run the following command:

fun local invoke nodejs8

The call result is as follows.

If the template.yml file contains multiple services and these services contain functions with the same name, Fun runs the first matching function if the functions are called by function name.

For exact match, use service name/function name.

For example, to call php72 under localdemo, run the following command:

fun local invoke localdemo/php72

In this example, the same result as fun local invoke php72 is returned.

The following is a demo showing how to run a nodejs8 function:

Run a Java function locally

Unlike interpreted languages, a Java language must be compiled before it is run as a function.For this demo, go to the java8 directory and run the following command:

mvn package

The following log is displayed:

[INFO] skip non existing resourceDirectory /Users/tan/code/fun/examples/local/java8/src/test/resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ demo ---
[INFO] No sources to compile
[INFO]
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ demo ---
[INFO] No tests to run.
[INFO]
[INFO] --- maven-dependency-plugin:2.8:copy-dependencies (copy-dependencies) @ demo ---
[INFO] fc-java-core-1.0.0.jar already exists in destination.
[INFO]
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ demo ---
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.223 s
[INFO] Finished at: 2018-11-22T10:45:14+08:00
[INFO] Final Memory: 15M/309M
[INFO] ------------------------------------------------------------------------

This command generates the demo-1.0-SNAPSHOT.jar file in the java8/target directory.

Because the CodeUri we configured in the template.yml file is java8/target/demo-1.0-SNAPSHOT.jar, no modification is required. Directly run the following command:

fun local invoke java8

The result is as follows.

The following is a demo showing how to run a java8 function:

Local debugging

The fun local invoke function provides the -d, --debug-port option, , which supports local single-step function debugging.This document only describes how to configure the debugging procedure, but does not discuss the debugging techniques. For more information, see.

Note: All debugging techniques involved in Fun Local comply with the general debugging protocols of different languages. Regardless of the language, developers who use the remote debugging method can select Fun Local for debugging, even if they do not like VS Code.

Debug a nodejs or python function locally

The debugging methods are basically the same for functions of the nodejs6, nodejs8, python2.7, python3, and java8 types.Here, we use nodejs8 as an example.

As demonstrated, we can use the fun local invoke nodejs8 command to run a function named nodejs8. To debug the nodejs8 function, use the -d parameter and specify a debugging port.

For example, to run the function in debugging mode on port 3000, run the following command:

fun local invoke -d 3000 nodejs8

In addition, we recommend using the --config parameter to output the IDE configuration information used for debugging:

fun local invoke -d 3000 --config VSCode nodejs8

The result is as follows:

skip pulling images ...
you can paste these config to .vscode/launch.json, and then attach to your running function
///////////////// config begin /////////////////
{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "fc/localdemo/nodejs8",
            "type": "node",
            "request": "attach",
            "address": "localhost",
            "port": 3000,
            "localRoot": "/Users/tan/code/fun/examples/local/nodejs8",
            "remoteRoot": "/code",
            "protocol": "inspect",
            "stopOnEntry": false
        }
    ]
}
///////////////// config end /////////////////
Debugger listening on ws://0.0.0.0:3000/b65c288b-bd6a-4791-849b-b03e0d16b0ce
For help see https://nodejs.org/en/docs/inspector

The program gets stuck here.It can continue running only when IDE is connected.Next, we will explain VS Code configuration and debugging.

VS Code only needs to be configured the first time it is used for function debugging.

VS Code configuration

  1. Create a vscode launch.json file

    ![](https://tan-blog.oss-cn-hangzhou.aliyuncs.com/img/20181116202330.png)
    
  2. Copy the content between config begin and config end in the logs and paste it in the launch.json file.

    ![](https://tan-blog.oss-cn-hangzhou.aliyuncs.com/img/20181118174828.png)
    
  3. After the preceding configuration, the configured function is listed as an option of Debug.

    ![](https://tan-blog.oss-cn-hangzhou.aliyuncs.com/img/20181118204006.png)
    

Now, VS Code has been configured.For more information about VS Code configuration, see the official documentation.

VS Code debugging

After VS Code is configured, click the sidebar of the VS Code editor to set a breakpoint, and then click the Start Debugging icon.

The following is a demo showing how to locally perform single-step debugging on a nodejs8 function:

Debug a Java function locally

The debugging procedure for a Java function is similar to that of a nodejs or python function.Next, this document will discuss IDEs, such as IDEA and Eclipse, separately because they are preferred by Java programmers.

Use VS Code to debug Java functions

To use VS Code for Java function debugging, install two plugins, Language Support for Java(TM) by Red Hat and Debugger for Java.We can easily install the plugins from the VS Code plugin market. For more information, see.

The following is a demo showing how to use VS Code to debug a Java function:

Use IDEA to debug Java functions

IDEA configuration

The remote debugging configuration for IDEA is easy. On the menu bar, choose Run > Edit Configurations...:

Click the Add New Configuration button and then click Remote.

Set Name to any value and Port to 3000.

The following is a demo showing how to configure IDEA remote debugging:

Use IDEA to start debugging

Run the Java function in debugging mode:

fun local invoke -d 3000 java8

As we can see, the function gets stuck here. Establish an IDEA connection and start debugging.Choose Run > Debug... from the menu bar or click the Debug button on the toolbar to start debugging.

The following is a demo showing how to use IDEA for remote debugging:

Debug a php function locally

The debugging procedure for a php function is slightly different from that of other types of functions.

Like other types of functions, a php function is run by the fun local invoke php72 command.The -d parameter is used to start the php function in debugging mode, which is similar to other types of functions:

fun local invoke -d 3000 --config VSCode php72

However, the php function runs to the end, instead of getting stuck and waiting for a connection from VS Code.

skip pulling images ...
you can paste these config to .vscode/launch.json, and then attach to your running function
///////////////// config begin /////////////////
{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "fc/localdemo/php72",
            "type": "php",
            "request": "launch",
            "port": 3000,
            "stopOnEntry": false,
            "pathMappings": {
                "/code": "/Users/tan/code/fun/examples/local/php7.2"
            },
            "ignore": [
                "/var/fc/runtime/**"
            ]
        }
    ]
}
///////////////// config end /////////////////
FunctionCompute php7.2 runtime inited.
FC Invoke Start RequestId: 6e8f7ed7-653d-4a6a-94cc-1ef0d028e4b4
FC Invoke End RequestId: 6e8f7ed7-653d-4a6a-94cc-1ef0d028e4b4
hello world


RequestId: 6e8f7ed7-653d-4a6a-94cc-1ef0d028e4b4          Billed Duration: 48 ms          Memory Size: 1998 MB        Max Memory Used: 58 MB

This is because VS Code must be started first for a php program.

The VS Code startup procedure for php functions is the same as that for other types of functions: copy the VS Code configuration in the preceding logs and paste it in the launch.json file, and then click the Start Debugging button.

On the terminal, restart the php function in debugging mode to start debugging:

fun local invoke -d 3000 php72

Event source

Function Compute provides a wide range of triggers, including OSS trigger, Log Service trigger, and CDN events trigger.When running or debugging a function locally, we need to construct a trigger event to fully simulate the online environment.

A trigger event can be readable JSON configurations or non-readable binary data.Here, we use a JSON configuration as an example and assume that the content of the trigger event is as follows:

{
    "testKey": "testValue"
}

The event content can be passed to the function in any of the following three ways:

  1. Pipeline: echo '{"testKey": "testValue"}' | fun local invoke nodejs8
  2. File: Write the JSON content to a file with any file name, such as event.json.Then, use the -e parameter to specify the file name: fun local invoke -e event.json nodejs8 .
  3. Redirect: fun local invoke nodejs8 < event.json, fun local invoke nodejs8 <<< '{"testKey": "testValue"}', or other commands.For more information, see the documentation.

Environment variables

The EnvironmentVariables configured in the template.yml file are consistent with those in the online environment. They can be obtained from the code when the function is running.For more information, see.

When running a function locally, in addition to the environment variables configured by EnvironmentVariables, Fun also provides an additional environment variable local=true to indicate that the function is running locally.

With this environment variable, you can see whether the function is running locally or online, which facilitates special logic processing.

Initializer

The Initializer attribute configured in the template.yml file is consistent with that in the online environment. The method specified by Initializer runs first when the function is running. For more information about Initializer, see.

Credentials

You can access other Alibaba Cloud services with the Access Key information in credentials.When Fun Local runs a function locally, it seeks the Access Key information based on the same policy as Fun Deploy.

For more information about the credentials of Function Compute, see.

The following is an example of OSS client configuration with the credentials provided by the function, depending on the local or online environments:

local = bool(os.getenv('local', ""))
if (local):
    print 'thank you for running function in local!!!!!!'
    auth = oss2.Auth(creds.access_key_id,
                     creds.access_key_secret)
else:
    auth = oss2.StsAuth(creds.access_key_id,
                        creds.access_key_secret,
                        creds.security_token)

Appendix

Code

The demo code in this document is hosted on GitHub.The project directory structure is as follows:

.
├── java8
│   ├── pom.xml
│   ├── src
│   │   └── main
│   │       └── java
│   │           └── example
│   │               └── App.java
│   └── target
│       └── demo-1.0-SNAPSHOT.jar
├── nodejs6
│   └── index.js
├── nodejs8
│   └── index.js
├── php7.2
│   └── index.php
├── python2.7
│   └── index.py
├── python3
│   └── index.py
└── template.yml

The template.yml file defines the Function Compute model, including a service named localdemo. In the service, six functions are defined: nodejs6, nodejs8, php72, python27, python3, and java8.The code directories of these functions are defined by CodeUri in the template. They are respectively located in the directories of nodejs6, nodejs8, php7.2, python2.7, python3, and java8.

Note

This article was translated from 《开发函数计算的正确姿势 —— 使用 Fun Local 本地运行与调试》.

References

  1. Fun Repo
  2. Fun specs
  3. Fun examples
  4. Fun V2.0
【云栖快讯】云栖专辑 | 阿里开发者们的第19个感悟:Simple is better.  详情请点击

网友评论