函数编程简单示例#
本节通过一些示例介绍如何使用有状态函数、无状态函数开发应用,您可以基于这些示例作为基础工程快速上手。
Note
运行示例需先安装 openYuanrong SDK、命令行工具 yr,并已在主机上部署 openYuanrong。
无状态函数示例工程#
准备示例工程
新建一个工作目录
python-stateless-function,包含文件结构如下。其中,example.py 为应用代码。python-stateless-function └── example.pyexample.py 文件内容
import yr # Define stateless function @yr.invoke def say_hello(name): return 'hello, ' + name # Init only once yr.init() # Asynchronously invoke stateless functions in parallel results_ref = [say_hello.invoke('yuanrong') for i in range(3)] print(yr.get(results_ref)) # Release environmental resources yr.finalize()
运行程序
在
python-stateless-function目录下运行程序,输出如下:python example.py # ['hello, yuanrong', 'hello, yuanrong', 'hello, yuanrong']
Note
示例运行依赖 make、g++ 及 cmake。
准备示例工程
新建一个工作目录
cpp-stateless-function,包含文件结构如下。其中,build 目录用于存放编译构建中生成的文件,CMakeLists.txt 为 CMake 构建系统使用的配置文件,example.cpp 为应用代码。cpp-stateless-function ├── build ├── CMakeLists.txt └── src └── example.cpp
example.cpp 文件内容
#include <iostream> #include "yr/yr.h" // Define stateless function std::string SayHello(std::string name) { return "hello, " + name; } YR_INVOKE(SayHello) int main(int argc, char *argv[]) { // Init only once YR::Init(YR::Config{}, argc, argv); // Asynchronously invoke stateless functions in parallel std::vector<YR::ObjectRef<std::string>> results_ref; for (int i = 0; i < 3; i++) { auto result_ref = YR::Function(SayHello).Invoke(std::string("yuanrong")); results_ref.emplace_back(result_ref); } for (auto result : YR::Get(results_ref)) { std::cout << *result << std::endl; } // Release environmental resources YR::Finalize(); return 0; }
CMakeLists.txt 文件内容,须对应修改 YR_INSTALL_PATH 为您的 openYuanrong 安装路径
cmake_minimum_required(VERSION 3.16.1) # 指定项目名称,例如:cpp-stateless-function project(cpp-stateless-function LANGUAGES C CXX) set(CMAKE_CXX_STANDARD 17) # 指定编译生成文件路径在 build 目录下 set(SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) set(BINARY_DIR ${SOURCE_DIR}/build) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${BINARY_DIR}) set(CMAKE_CXX_FLAGS "-pthread") set(BUILD_SHARED_LIBS ON) # 替换 YR_INSTALL_PATH 的值为 openYuanrong 安装路径,可通过 yr version 命令查看 set(YR_INSTALL_PATH "/usr/local/lib/python3.9/site-packages/yr/inner") link_directories(${YR_INSTALL_PATH}/runtime/sdk/cpp/lib) include_directories( ${YR_INSTALL_PATH}/runtime/sdk/cpp/include ) # 生成可执行文件 example,修改 example.cpp 为您对应的源码文件 add_executable(example src/example.cpp) target_link_libraries(example yr-api) # 生成动态库文件 example-dll,修改 example.cpp 为您对应的源码文件 add_library(example-dll SHARED src/example.cpp) target_link_libraries(example-dll yr-api)
编译构建
在
cpp-stateless-function/build目录下,执行如下命令构建应用:cmake .. make成功构建将在该目录下生成 driver 程序
example和包含无状态函数定义的动态库libexample-dll.so。Note
无状态函数可能在 openYuanrong 集群的任意节点执行。因此,运行 driver 程序前,需要在其他节点相同路径下拷贝一份
libexample-dll.so文件。运行程序
在
cpp-stateless-function/build目录下运行程序,输出如下:./example --codePath=$(pwd) # hello, yuanrong # hello, yuanrong # hello, yuanrong
Note
示例运行依赖 java 8 和 maven。
准备示例工程
新建一个工作目录
java-stateless-function,包含文件结构如下。其中,pom.xml 为 maven 配置文件,Greeter.java 和 Main.java 为应用代码。java-stateless-function ├── pom.xml └── src └── main └── java └── com └── yuanrong └── example ├── Greeter.java └── Main.java
pom.xml 文件内容,请参考安装 Java SDK 并配置依赖 yr-api-sdk
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.yuanrong.example</groupId> <artifactId>example</artifactId> <version>1.0.0</version> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties> <dependencies> <dependency> <!-- 修改版本号为您实际使用版本 --> <groupId>com.yuanrong</groupId> <artifactId>yr-api-sdk</artifactId> <version>1.0.0</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> <executions> <execution> <phase>package</phase> <goals> <goal>single</goal> </goals> </execution> </executions> <configuration> <archive> <manifest> <mainClass>com.yuanrong.example.Main</mainClass> </manifest> </archive> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> <appendAssemblyId>false</appendAssemblyId> </configuration> </plugin> </plugins> </build> </project>
Greeter.java 文件内容
package com.yuanrong.example; public class Greeter { // Define stateless function public static String sayHello(String name) { return "hello, " + name; } }
Main.java 文件内容
package com.yuanrong.example; import com.yuanrong.Config; import com.yuanrong.api.YR; import com.yuanrong.runtime.client.ObjectRef; import com.yuanrong.exception.YRException; import java.util.HashMap; import java.util.ArrayList; import java.util.List; public class Main { public static void main(String[] args) throws YRException { // Init only once YR.init(new Config()); // Asynchronously invoke stateless functions in parallel List<ObjectRef> resultsRef = new ArrayList<>(); for (int i = 0; i < 3; i++) { ObjectRef resultRef = YR.function(Greeter::sayHello).invoke("yuanrong"); resultsRef.add(resultRef); } for (ObjectRef resultRef : resultsRef) { System.out.println(YR.get(resultRef, 30)); } // Release environmental resources YR.Finalize(); } }
编译构建
在
java-stateless-function目录下,执行如下命令构建应用:mvn clean package
成功构建将在
java-stateless-function/target目录下生成 jar 包example-1.0.0.jar。Note
无状态函数可能在 openYuanrong 集群的任意节点执行。因此,运行程序前,需要在其他节点相同路径下拷贝一份
example-1.0.0.jar文件。运行程序
在
java-stateless-function目录下运行程序,输出如下:java -Dyr.codePath=$(pwd)/target -cp target/example-1.0.0.jar com.yuanrong.example.Main # hello, yuanrong # hello, yuanrong # hello, yuanrong
有状态函数示例工程#
准备示例工程
新建一个工作目录
python-stateful-function,包含文件结构如下。其中,example.py 为应用代码。python-stateful-function └── example.pyexample.py 文件内容
# example.py import yr # Define stateful function @yr.instance class Object: def __init__(self): self.value = 0 def save(self, value): self.value = value def get(self): return self.value # Init only once yr.init() # Create three stateful function instances objs = [Object.invoke() for i in range(3)] # Asynchronously invoke stateful functions in parallel [obj.save.invoke(9) for obj in objs] results_ref = [obj.get.invoke() for obj in objs] print(yr.get(results_ref)) # Destroy stateful function instance [obj.terminate() for obj in objs] # Release environmental resources yr.finalize()
运行程序
在
python-stateful-function目录下运行程序,输出如下:python example.py # [9, 9, 9]
Note
示例运行依赖 make、g++ 及 cmake。
准备示例工程
新建一个工作目录
cpp-stateful-function,包含文件结构如下。其中,build 目录用于存放编译构建中生成的文件,CMakeLists.txt 为 CMake 构建系统使用的配置文件,example.cpp 为应用代码。cpp-stateless-function ├── build ├── CMakeLists.txt └── src └── example.cpp
example.cpp 文件内容
#include <iostream> #include "yr/yr.h" // Define stateful function class Object { public: Object() {} Object(int value) { this->value = value; } static Object *FactoryCreate(int value) { return new Object(value); } void Save(int value) { this->value = value; } int Get() { return value; } YR_STATE(value); private: int value; }; YR_INVOKE(Object::FactoryCreate, &Object::Save, &Object::Get); int main(int argc, char *argv[]) { // Init only once YR::Init(YR::Config{}, argc, argv); // Create three stateful function instances std::vector<YR::NamedInstance<Object>> objects; for (int i = 0; i < 3; i++) { auto obj = YR::Instance(Object::FactoryCreate).Invoke(0); objects.emplace_back(obj); } // Asynchronously invoke stateful functions in parallel std::vector<YR::ObjectRef<int>> results_ref; for (auto obj : objects) { obj.Function(&Object::Save).Invoke(9); auto result_ref = obj.Function(&Object::Get).Invoke(); results_ref.emplace_back(result_ref); } for (auto result : YR::Get(results_ref)) { std::cout << *result << std::endl; } // Destroy stateful function instance for (auto obj : objects) { obj.Terminate(); } // Release environmental resources YR::Finalize(); return 0; }
CMakeLists.txt 文件内容,须对应修改 YR_INSTALL_PATH 为您的 openYuanrong 安装路径
cmake_minimum_required(VERSION 3.16.1) # 指定项目名称,例如:cpp-stateful-function project(cpp-stateful-function LANGUAGES C CXX) set(CMAKE_CXX_STANDARD 17) # 指定编译生成文件路径在 build 目录下 set(SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) set(BINARY_DIR ${SOURCE_DIR}/build) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${BINARY_DIR}) set(CMAKE_CXX_FLAGS "-pthread") set(BUILD_SHARED_LIBS ON) # 替换 YR_INSTALL_PATH 的值为 openYuanrong 安装路径,可通过 yr version 命令查看 set(YR_INSTALL_PATH "/usr/local/lib/python3.9/site-packages/yr/inner") link_directories(${YR_INSTALL_PATH}/runtime/sdk/cpp/lib) include_directories( ${YR_INSTALL_PATH}/runtime/sdk/cpp/include ) # 生成可执行文件 example,修改 example.cpp 为您对应的源码文件 add_executable(example src/example.cpp) target_link_libraries(example yr-api) # 生成动态库文件 example-dll,修改 example.cpp 为您对应的源码文件 add_library(example-dll SHARED src/example.cpp) target_link_libraries(example-dll yr-api)
编译构建
在
cpp-stateful-function/build目录下,执行如下命令构建应用:cmake .. make成功构建将在该目录下生成 driver 程序
example和包含有状态函数定义的动态库libexample-dll.so。Note
有状态函数可能在 openYuanrong 集群的任意节点执行。因此,运行 driver 程序前,需要在其他节点相同路径下拷贝一份
libexample-dll.so文件。运行程序
在
cpp-stateful-function/build目录下运行程序,输出如下:./example --codePath=$(pwd) # 9 # 9 # 9
Note
示例运行依赖 java 8 和 maven。
准备示例工程
新建一个工作目录
java-stateful-function,包含文件结构如下。其中,pom.xml 为 maven 配置文件,Object.java 和 Main.java 为应用代码。java-stateless-function ├── pom.xml └── src └── main └── java └── com └── yuanrong └── example ├── Object.java └── Main.java
pom.xml 文件内容,请参考安装 Java SDK 并配置依赖 yr-api-sdk
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.yuanrong.example</groupId> <artifactId>example</artifactId> <version>1.0.0</version> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties> <dependencies> <dependency> <!-- 修改版本号为您实际使用版本 --> <groupId>com.yuanrong</groupId> <artifactId>yr-api-sdk</artifactId> <version>1.0.0</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> <executions> <execution> <phase>package</phase> <goals> <goal>single</goal> </goals> </execution> </executions> <configuration> <archive> <manifest> <mainClass>com.yuanrong.example.Main</mainClass> </manifest> </archive> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> <appendAssemblyId>false</appendAssemblyId> </configuration> </plugin> </plugins> </build> </project>
Object.java 文件内容
package com.yuanrong.example; // Define stateful function public class Object { private int value = 0; public Object(int value) { this.value = value; } public void save(int value) { this.value = value; } public int get() { return this.value; } }
Main.java 文件内容
package com.yuanrong.example; import com.yuanrong.Config; import com.yuanrong.api.YR; import com.yuanrong.runtime.client.ObjectRef; import com.yuanrong.call.InstanceHandler; import com.yuanrong.exception.YRException; import java.util.HashMap; import java.util.ArrayList; import java.util.List; public class Main { public static void main(String[] args) throws YRException { // Init only once YR.init(new Config()); // Create three stateful function instances List<InstanceHandler> objects = new ArrayList<>(); for (int i = 0; i < 3; i++) { InstanceHandler obj = YR.instance(Object::new).invoke(0); objects.add(obj); } // Asynchronously invoke stateful functions in parallel List<ObjectRef> resultsRef = new ArrayList<>(); for (InstanceHandler obj : objects) { obj.function(Object::save).invoke(9); ObjectRef resultRef = obj.function(Object::get).invoke(); resultsRef.add(resultRef); } for (ObjectRef resultRef : resultsRef) { System.out.println(YR.get(resultRef, 30)); } // Destroy stateful function instance for (InstanceHandler obj : objects) { obj.terminate(); } // Release environmental resources YR.Finalize(); } }
编译构建
在
java-stateful-function目录下,执行如下命令构建应用:mvn clean package
成功构建将在
java-stateful-function/target目录下生成 jar 包example-1.0.0.jar。Note
无状态函数可能在 openYuanrong 集群的任意节点执行。因此,运行程序前,需要在其他节点相同路径下拷贝一份
example-1.0.0.jar文件。运行程序
在
java-stateful-function目录下运行程序,输出如下:java -Dyr.codePath=$(pwd)/target -cp target/example-1.0.0.jar com.yuanrong.example.Main # 9 # 9 # 9
函数服务示例工程#
参考配置支持函数服务确保您部署的 openYuanrong 集群支持运行函数服务。在所有节点创建相同的代码包目录,例如 /opt/mycode/service,用于存放构建生成的可执行函数代码。
准备示例代码
新建如下内容的文件
demo.py,拷贝文件到所有节点的代码包目录下。import datetime # 函数执行入口,每次请求都会执行,其中event参数为JSON格式 def handler(event, context): print("received request,event content:", event) response = "" try: name = event.get("name") # 获取配置的环境变量,环境变量在注册和更新函数时设置 show_date = context.getUserData("show_date") if show_date is not None: response = "hello " + name + ",today is " + datetime.date.today().strftime('%Y-%m-%d') else: response = "hello " + name except Exception as e: print(e) response = "please enter your name,for example:{'name':'yuanrong'}" return response # 函数初始化入口,函数实例启动时执行一次 def init(context): print("function instance initialization completed") # 函数退出入口,函数实例被销毁时执行一次 def pre_stop(): print("function instance is being destroyed")
函数注册及调用
使用 curl 工具注册函数,参数含义详见 API 说明:
# 替换 /opt/mycode/service 为您的代码包目录 META_SERVICE_ENDPOINT=<meta service 组件的服务端点,默认为:http://{主节点 IP}:31182> curl -H "Content-type: application/json" -X POST -i ${META_SERVICE_ENDPOINT}/serverless/v1/functions -d '{"name":"0@myService@python-demo","runtime":"python3.9","handler":"demo.handler","environment":{"show_date":"true"},"extendedHandler":{"initializer":"demo.init","pre_stop":"demo.pre_stop"},"extendedTimeout":{"initializer":30,"pre_stop":10},"kind":"faas","cpu":600,"memory":512,"timeout":60,"storageType":"local","codePath":"/opt/mycode/service"}'
结果返回格式如下,记录
functionVersionUrn字段的值用于调用,这里对应sn:cn:yrk:12345678901234561234567890123456:function:0@myService@python-demo:latest。{"code":0,"message":"SUCCESS","function":{"id":"sn:cn:yrk:12345678901234561234567890123456:function:0@myService@python-demo:latest","createTime":"2025-05-29 07:09:34.154 UTC","updateTime":"","functionUrn":"sn:cn:yrk:12345678901234561234567890123456:function:0@myService@python-demo","name":"0@myService@python-demo","tenantId":"12345678901234561234567890123456","businessId":"yrk","productId":"","reversedConcurrency":0,"description":"","tag":null,"functionVersionUrn":"sn:cn:yrk:12345678901234561234567890123456:function:0@myService@python-demo:latest","revisionId":"20250529070934154","codeSize":0,"codeSha256":"","bucketId":"","objectId":"","handler":"demo.handler","layers":null,"cpu":600,"memory":512,"runtime":"python3.9","timeout":60,"versionNumber":"latest","versionDesc":"latest","environment":{"show_date":"true"},"customResources":null,"statefulFlag":0,"lastModified":"","Published":"2025-05-29 07:09:34.154 UTC","minInstance":0,"maxInstance":100,"concurrentNum":100,"funcLayer":[],"status":"","instanceNum":0,"device":{},"created":""}}
使用 curl 工具调用函数,参数含义详见 API 说明:
FRONTEND_ENDPOINT=<frontend 组件的终端节点,默认为:http://{主节点 ip}:8888`> FUNCTION_VERSION_URN=<前一步骤记录的 functionVersionUrn> curl -H "Content-type: application/json" -X POST -i ${FRONTEND_ENDPOINT}/serverless/v1/functions/${FUNCTION_VERSION_URN}/invocations -d '{"name":"yuanrong"}'
结果输出:
HTTP/1.1 200 OK Content-Type: application/json X-Billing-Duration: this is billing duration TODO X-Inner-Code: 0 X-Invoke-Summary: X-Log-Result: dGhpcyBpcyB1c2VyIGxvZyBUT0RP Date: Tue, 20 May 2025 02:03:09 GMT Content-Length: 36 "hello yuanrong,today is 2025-05-20"
准备示例工程
新建一个工作目录
service-cpp-demo,包含文件结构如下。其中,build 目录用于存放编译构建中生成的文件。CMakeLists.txt 为 CMake 构建系统使用的配置文件。demo.cpp 为函数代码文件,我们使用了开源 nlohmann/json 库解析 JSON。service-cpp-demo ├── build ├── demo.cpp └── CMakeLists.txt
demo.cpp 文件内容
#include <string> #include <cstdlib> #include <ctime> #include <nlohmann/json.hpp> #include "Runtime.h" #include "Function.h" #include "yr/yr.h" // 函数执行入口,每次请求都会执行,其中event参数要求为JSON格式,返回类型可自定义 std::string HandleRequest(const std::string &event, Function::Context &context) { std::cout << "received request,event content:" << event << std::endl; std::string response = ""; try { nlohmann::json jsonData = nlohmann::json::parse(event); // 读取 JSON 数据并输出 std::string name = jsonData["name"]; response += "hello "; response += name; std::string showDate = context.GetUserData("show_date"); if (showDate != "") { time_t now = time(0); tm *ltm = localtime(&now); std::stringstream timeStr; timeStr << ltm->tm_year + 1900 << "-"; timeStr << ltm->tm_mon + 1 << "-"; timeStr << ltm->tm_mday; response += ",today is "; response += timeStr.str(); } } catch (const std::exception& e) { std::cout << "JSON parsing error:" << e.what() << std::endl; response = "please enter your name,for example:{'name':'yuanrong'}"; } return response; } // 函数初始化入口,函数实例启动时执行一次 void Initializer(Function::Context &context) { std::cout << "function instance initialization completed" << std::endl; return; } // 函数退出入口,函数实例被销毁时执行一次 void PreStop(Function::Context &context) { std::cout << "function instance is being destroyed" << std::endl; return; } int main(int argc, char *argv[]) { Function::Runtime rt; rt.RegisterHandler(HandleRequest); rt.RegisterInitializerFunction(Initializer); rt.RegisterPreStopFunction(PreStop); rt.Start(argc, argv); return 0; }
CMakeLists.txt 文件内容,须对应修改 YR_INSTALL_PATH 为您的openYuanrong安装路径
cmake_minimum_required(VERSION 3.16.1) project(demo CXX) set(CMAKE_CXX_STANDARD 17) set(SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) set(BINARY_DIR ${SOURCE_DIR}/build) # 替换 YR_INSTALL_PATH 的值为openYuanrong安装路径,可通过 yr version 命令查看 set(YR_INSTALL_PATH "/usr/local/lib/python3.9/site-packages/yr/inner") link_directories(${YR_INSTALL_PATH}/runtime/sdk/cpp/lib) include_directories( ${YR_INSTALL_PATH}/runtime/sdk/cpp/include/faas ${YR_INSTALL_PATH}/runtime/sdk/cpp/include ) add_executable(demo demo.cpp) target_link_libraries(demo functionsdk) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${BINARY_DIR})
编译构建
下载 nlohmann/json 例如 json-3.12.0.tar.gz 版本到所有openYuanrong节点,依次执行如下命令安装。
tar -zxvf json-3.12.0.tar.gz cd json-3.12.0 mkdir build cd build cmake .. make make install
在
service-cpp-demo/build目录下,执行如下命令构建函数:cmake .. make成功构建将在该目录下生成二进制文件
demo,拷贝文件到所有节点的代码包目录下。函数注册及调用
使用 curl 工具注册函数,参数含义详见 API 说明:
# 替换 /opt/mycode/service 为您的代码包目录 META_SERVICE_ENDPOINT=<meta service 组件的服务端点,默认为:http://{主节点 ip}:31182> curl -H "Content-type: application/json" -X POST -i ${META_SERVICE_ENDPOINT}/serverless/v1/functions -d '{"name":"0@myService@cpp-demo","runtime":"posix-custom-runtime","handler":"demo","environment":{"show_date":"true"},"kind":"faas","cpu":600,"memory":512,"timeout":60,"storageType":"local","codePath":"/opt/mycode/service"}'
结果返回格式如下,记录
functionVersionUrn字段的值用于调用,这里对应sn:cn:yrk:12345678901234561234567890123456:function:0@myService@cpp-demo:latest{"code":0,"message":"SUCCESS","function":{"id":"sn:cn:yrk:12345678901234561234567890123456:function:0@myService@cpp-demo:latest","createTime":"2025-05-20 03:43:19.117 UTC","updateTime":"","functionUrn":"sn:cn:yrk:12345678901234561234567890123456:function:0@myService@cpp-demo","name":"0@myService@cpp-demo","tenantId":"12345678901234561234567890123456","businessId":"yrk","productId":"","reversedConcurrency":0,"description":"","tag":null,"functionVersionUrn":"sn:cn:yrk:12345678901234561234567890123456:function:0@myService@cpp-demo:latest","revisionId":"20250520034319117","codeSize":0,"codeSha256":"","bucketId":"","objectId":"","handler":"demo","layers":null,"cpu":600,"memory":512,"runtime":"posix-custom-runtime","timeout":60,"versionNumber":"latest","versionDesc":"latest","environment":{"show_date":"true"},"customResources":null,"statefulFlag":0,"lastModified":"","Published":"2025-05-20 03:43:19.117 UTC","minInstance":0,"maxInstance":100,"concurrentNum":100,"funcLayer":[],"status":"","instanceNum":0,"device":{},"created":""}}
使用 curl 工具调用函数,参数含义详见 API 说明:
FRONTEND_ENDPOINT=<frontend 组件的终端节点,默认为:http://{主节点 ip}:8888> FUNCTION_VERSION_URN=<前一步骤记录的 functionVersionUrn> curl -H "Content-type: application/json" -X POST -i ${FRONTEND_ENDPOINT}/serverless/v1/functions/${FUNCTION_VERSION_URN}/invocations -d '{"name":"yuanrong"}'
结果输出:
HTTP/1.1 200 OK Content-Type: application/json X-Billing-Duration: this is billing duration TODO X-Inner-Code: 0 X-Invoke-Summary: X-Log-Result: this is user log TODO Date: Tue, 20 May 2025 03:43:57 GMT Content-Length: 35 "hello yuanrong,today is 2025-5-20"
准备示例工程
新建一个工作目录
service-java-demo,包含文件结构如下。其中,pom.xml 为 maven 配置文件,引入 openYuanrong SDK 等依赖。zip_file.xml 为打包配置。Demo.java 为函数代码文件。service-java-demo ├── pom.xml └── src └── main ├── assembly │ └── zip_file.xml └── java └── com └── yuanrong └── demo └── Demo.java
Demo.java 文件内容
package com.yuanrong.demo; import com.services.runtime.Context; import com.google.gson.JsonObject; import java.time.LocalDate; public class Demo { // 函数执行入口,每次请求都会执行,其中intput参数及函数返回类型可自定义 public String handler(JsonObject event, Context context) { System.out.println("received request,event content:" + event); String response = ""; try { String name = event.get("name").getAsString(); // 获取配置的环境变量,环境变量在注册和更新函数时设置 String showDate = context.getUserData("show_date"); if (showDate != null) { response = "hello " + name + ",today is " + LocalDate.now(); } else { response = "hello " + name; } } catch(Exception e) { e.printStackTrace(); response = "please enter your name,for example:{'name':'yuanrong'}"; } return response; } // 函数初始化入口,函数实例启动时执行一次 public void initializer(Context context) { System.out.println("function instance initialization completed"); } }
pom.xml 文件内容,请参考安装 Java SDK 并配置依赖 faas-function-sdk
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.yuanrong.demo</groupId> <artifactId>demo</artifactId> <version>1.0.0</version> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> <maven.build.timestamp.format>yyyyMMddHHmmss</maven.build.timestamp.format> <package.finalName>demo</package.finalName> <package.outputDirectory>target</package.outputDirectory> </properties> <dependencies> <dependency> <!-- 修改版本号为您实际使用版本 --> <groupId>com.yuanrong</groupId> <artifactId>faas-function-sdk</artifactId> <version>1.0.0</version> </dependency> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.9.0</version> </dependency> </dependencies> <build> <plugins> <!-- 配置如下打包方式 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> <version>2.2</version> <configuration> <archive> <manifest> <addDefaultImplementationEntries>true</addDefaultImplementationEntries> </manifest> </archive> <appendAssemblyId>false</appendAssemblyId> </configuration> <executions> <execution> <id>auto-deploy</id> <phase>package</phase> <goals> <goal>single</goal> </goals> <configuration> <descriptors> <descriptor>src/main/assembly/zip_file.xml</descriptor> </descriptors> <finalName>${package.finalName}</finalName> <outputDirectory>${package.outputDirectory}</outputDirectory> <archiverConfig> <directoryMode>0700</directoryMode> <fileMode>0600</fileMode> <defaultDirectoryMode>0700</defaultDirectoryMode> </archiverConfig> </configuration> </execution> </executions> </plugin> </plugins> </build> </project>
zip_file.xml 文件内容
<?xml version="1.0" encoding="UTF-8"?> <assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"> <id>auto-deploy</id> <baseDirectory/> <formats> <format>zip</format> </formats> <fileSets> <fileSet> <directory>src/main/resources/</directory> <outputDirectory>config</outputDirectory> <includes> <include>**</include> </includes> <fileMode>0600</fileMode> <directoryMode>0700</directoryMode> </fileSet> </fileSets> <dependencySets> <dependencySet> <outputDirectory>lib</outputDirectory> <scope>runtime</scope> </dependencySet> </dependencySets> </assembly>
编译构建
在
service-java-demo目录下,执行如下命令构建:mvn clean package
成功构建将在
service-java-demo/target目录下生成压缩包demo.zip,拷贝文件到所有节点的代码包目录下并使用命令unzip demo.zip解压。函数注册及调用
使用 curl 工具注册函数,参数含义详见 API 说明:
# 替换 /opt/mycode/service 为您的代码包目录 META_SERVICE_ENDPOINT=<meta service 组件的服务端点,默认为:http://{主节点 ip}:31182> curl -H "Content-type: application/json" -X POST -i ${META_SERVICE_ENDPOINT}/serverless/v1/functions -d '{"name":"0@myService@java-demo","runtime":"java8","handler":"com.yuanrong.demo.Demo::handler","environment":{"show_date":"true"},"extendedHandler":{"initializer":"com.yuanrong.demo.Demo::initializer"},"extendedTimeout":{"initializer":30},"kind":"faas","cpu":600,"memory":512,"timeout":60,"storageType":"local","codePath":"/opt/mycode/service"}'
结果返回格式如下,记录
functionVersionUrn字段的值用于调用,这里对应sn:cn:yrk:12345678901234561234567890123456:function:0@myService@java-demo:latest{"code":0,"message":"SUCCESS","function":{"id":"sn:cn:yrk:12345678901234561234567890123456:function:0@myService@java-demo:latest","createTime":"2025-05-20 06:26:42.396 UTC","updateTime":"","functionUrn":"sn:cn:yrk:12345678901234561234567890123456:function:0@myService@java-demo","name":"0@myService@java-demo","tenantId":"12345678901234561234567890123456","businessId":"yrk","productId":"","reversedConcurrency":0,"description":"","tag":null,"functionVersionUrn":"sn:cn:yrk:12345678901234561234567890123456:function:0@myService@java-demo:latest","revisionId":"20250520062642396","codeSize":0,"codeSha256":"","bucketId":"","objectId":"","handler":"com.yuanrong.demo.Demo::handler","layers":null,"cpu":600,"memory":512,"runtime":"java8","timeout":60,"versionNumber":"latest","versionDesc":"latest","environment":{"show_date":"true"},"customResources":null,"statefulFlag":0,"lastModified":"","Published":"2025-05-20 06:26:42.396 UTC","minInstance":0,"maxInstance":100,"concurrentNum":100,"funcLayer":[],"status":"","instanceNum":0,"device":{},"created":""}}
使用 curl 工具调用函数,参数含义详见 API 说明:
FRONTEND_ENDPOINT=<frontend 组件的终端节点,默认为:http://{主节点 ip}:8888> FUNCTION_VERSION_URN=<前一步骤记录的 functionVersionUrn> curl -H "Content-type: application/json" -X POST -i ${FRONTEND_ENDPOINT}/serverless/v1/functions/${FUNCTION_VERSION_URN}/invocations -d '{"name":"yuanrong"}'
结果输出:
HTTP/1.1 200 OK Content-Type: application/json X-Billing-Duration: this is billing duration TODO X-Inner-Code: 0 X-Invoke-Summary: X-Log-Result: dGhpcyBpcyB1c2VyIGxvZyBUT0RP Date: Tue, 20 May 2025 06:27:49 GMT Content-Length: 36 "hello yuanrong,today is 2025-05-20"