支持的编程语言 运行时环境变量说明 下面是FunctionGraph执行环境中运行时相关的环境变量列表,除此之外,还有用户自定义的环境变量,都可以在函数代码中直接使用。 环境变量说明 键 值说明 RUNTIMEPROJECTID projectID RUNTIMEFUNCNAME 函数名称 RUNTIMEFUNCVERSION 函数的版本 RUNTIMEPACKAGE 函数组 RUNTIMEHANDLER 函数执行入口 RUNTIMETIMEOUT 函数超时时间 RUNTIMEUSERDATA 用户通过环境变量传入的值 RUNTIMECPU 分配的CPU数 RUNTIMEMEMORY 分配的内存 RUNTIMECODEROOT 包含函数代码的目录 RUNTIMEAPIADDR 自定义运行时API的主机和端口 用户定义的环境变量也同FunctionGraph环境变量一样,可通过环境变量获取方式直接获取用户定义环境变量。 示例说明 此示例包含1个文件(bootstrap文件),该文件都在Bash中实施。 运行时将从部署程序包加载函数脚本。它使用两个变量来查找脚本。 引导文件bootstrap内容如下: !/bin/sh set o pipefail Processing requests loop while true do HEADERS"$(mktemp)" Get an event EVENTDATA$(curl sS LD "$HEADERS" X GET " Get request id from response header REQUESTID$(grep Fi xcffrequestid "$HEADERS" tr d '[:space:]' cut d: f2) if [ z "$REQUESTID" ]; then continue fi Process request data RESPONSE"Echoing request: hello world!" Put response curl X POST " d "$RESPONSE" done 加载脚本后,运行时将在一个循环中处理事件。它使用运行时API从FunctionGraph检索调用事件,将事件传递到处理程序,并将响应发布回给FunctionGraph。 为了获取请求ID,运行时会将来自API响应的标头保存到临时文件,并从该文件读取xcffrequestid读取请求头的请求唯一标识。将获取到的事件数据做处理并响应发布返回FunctionGraph。 go源码示例,需要通过编译后才可执行。 package main import ( "bytes" "encoding/json" "fmt" "io" "io/ioutil" "log" "net" "net/http" "os" "strings" "time" ) var ( getRequestUrl os.ExpandEnv(" putResponseUrl os.ExpandEnv(" putErrorResponseUrl os.ExpandEnv(" requestIdInvalidError fmt.Errorf("request id invalid") noRequestAvailableError fmt.Errorf("no request available") putResponseFailedError fmt.Errorf("put response failed") functionPackage os.Getenv("RUNTIMEPACKAGE") functionName os.Getenv("RUNTIMEFUNCNAME") functionVersion os.Getenv("RUNTIMEFUNCVERSION") client http.Client{ Transport: &http.Transport{ DialContext: (&net.Dialer{ Timeout: 3 time.Second, }).DialContext, }, } ) func main() { // main loop for processing requests. for { requestId, header, payload, err : getRequest() if err ! nil { time.Sleep(50 time.Millisecond) continue } result, err : processRequestEvent(requestId, header, payload) err putResponse(requestId, result, err) if err ! nil { log.Printf("put response failed, err: %s.", err.Error()) } } } // event processing function func processRequestEvent(requestId string, header http.Header, evtBytes []byte) ([]byte, error) { log.Printf("processing request '%s'.", requestId) result : fmt.Sprintf("function: %s:%s:%s, request id: %s, headers: %+v, payload: %s", functionPackage, functionName, functionVersion, requestId, header, string(evtBytes)) var event FunctionEvent err : json.Unmarshal(evtBytes, &event) if err ! nil { return (&ErrorMessage{ErrorType: "invalid event", ErrorMessage: "invalid json formated event"}).toJsonBytes(), err } return (&APIGFormatResult{StatusCode: 200, Body: result}).toJsonBytes(), nil } func getRequest() (string, http.Header, []byte, error) { resp, err : client.Get(getRequestUrl) if err ! nil { log.Printf("get request error, err: %s.", err.Error()) return "", nil, nil, err } defer resp.Body.Close() // get request id from response header requestId : resp.Header.Get("XCFFRequestId") if requestId "" { log.Printf("request id not found.") return "", nil, nil, requestIdInvalidError } payload, err : ioutil.ReadAll(resp.Body) if err ! nil { log.Printf("read request body error, err: %s.", err.Error()) return "", nil, nil, err } if resp.StatusCode ! 200 { log.Printf("get request failed, status: %d, message: %s.", resp.StatusCode, string(payload)) return "", nil, nil, noRequestAvailableError } log.Printf("get request ok.") return requestId, resp.Header, payload, nil } func putResponse(requestId string, payload []byte, err error) error { var body io.Reader if payload ! nil && len(payload) > 0 { body bytes.NewBuffer(payload) } url : "" if err nil { url strings.Replace(putResponseUrl, "{REQUESTID}", requestId, 1) } else { url strings.Replace(putErrorResponseUrl, "{REQUESTID}", requestId, 1) } resp, err : client.Post(strings.Replace(url, "{REQUESTID}", requestId, 1), "", body) if err ! nil { log.Printf("put response error, err: %s.", err.Error()) return err } defer resp.Body.Close() responsePayload, err : ioutil.ReadAll(resp.Body) if err ! nil { log.Printf("read request body error, err: %s.", err.Error()) return err } if resp.StatusCode ! 200 { log.Printf("put response failed, status: %d, message: %s.", resp.StatusCode, string(responsePayload)) return putResponseFailedError } return nil } type FunctionEvent struct { Type string json:"type" Name string json:"name" } type APIGFormatResult struct { StatusCode int json:"statusCode" IsBase64Encoded bool json:"isBase64Encoded" Headers map[string]string json:"headers,omitempty" Body string json:"body,omitempty" } func (result APIGFormatResult) toJsonBytes() []byte { data, err : json.MarshalIndent(result, "", " ") if err ! nil { return nil } return data } type ErrorMessage struct { ErrorType string json:"errorType" ErrorMessage string json:"errorMessage" } func (errMsg ErrorMessage) toJsonBytes() []byte { data, err : json.MarshalIndent(errMsg, "", " ") if err ! nil { return nil } return data } 代码中的环境变量说明如下,请参见下表。 环境变量说明 环境变量 说明 RUNTIMEFUNCNAME 函数名称 RUNTIMEFUNCVERSION 函数版本 RUNTIMEPACKAGE 函数组