Este conteúdo foi traduzido por máquina para sua conveniência e a Huawei Cloud não pode garantir que o conteúdo foi traduzido com precisão. Para exibir o conteúdo original, use o link no canto superior direito para mudar para a página em inglês.
Computação
Elastic Cloud Server
Bare Metal Server
Auto Scaling
Image Management Service
Dedicated Host
FunctionGraph
Cloud Phone Host
Huawei Cloud EulerOS
Redes
Virtual Private Cloud
Elastic IP
Elastic Load Balance
NAT Gateway
Direct Connect
Virtual Private Network
VPC Endpoint
Cloud Connect
Enterprise Router
Enterprise Switch
Global Accelerator
Gerenciamento e governança
Cloud Eye
Identity and Access Management
Cloud Trace Service
Resource Formation Service
Tag Management Service
Log Tank Service
Config
Resource Access Manager
Simple Message Notification
Application Performance Management
Application Operations Management
Organizations
Optimization Advisor
Cloud Operations Center
Resource Governance Center
Migração
Server Migration Service
Object Storage Migration Service
Cloud Data Migration
Migration Center
Cloud Ecosystem
KooGallery
Partner Center
User Support
My Account
Billing Center
Cost Center
Resource Center
Enterprise Management
Service Tickets
HUAWEI CLOUD (International) FAQs
ICP Filing
Support Plans
My Credentials
Customer Operation Capabilities
Partner Support Plans
Professional Services
Análises
MapReduce Service
Data Lake Insight
CloudTable Service
Cloud Search Service
Data Lake Visualization
Data Ingestion Service
GaussDB(DWS)
DataArts Studio
IoT
IoT Device Access
Outros
Product Pricing Details
System Permissions
Console Quick Start
Common FAQs
Instructions for Associating with a HUAWEI CLOUD Partner
Message Center
Segurança e conformidade
Security Technologies and Applications
Web Application Firewall
Host Security Service
Cloud Firewall
SecMaster
Anti-DDoS Service
Data Encryption Workshop
Database Security Service
Cloud Bastion Host
Data Security Center
Cloud Certificate Manager
Situation Awareness
Managed Threat Detection
Blockchain
Blockchain Service
Serviços de mídia
Media Processing Center
Video On Demand
Live
SparkRTC
Armazenamento
Object Storage Service
Elastic Volume Service
Cloud Backup and Recovery
Cloud Server Backup Service
Storage Disaster Recovery Service
Scalable File Service
Volume Backup Service
Data Express Service
Dedicated Distributed Storage Service
Containers
Cloud Container Engine
SoftWare Repository for Container
Application Service Mesh
Ubiquitous Cloud Native Service
Cloud Container Instance
Bancos de dados
Relational Database Service
Document Database Service
Data Admin Service
Data Replication Service
GeminiDB
GaussDB
Distributed Database Middleware
Database and Application Migration UGO
TaurusDB
Middleware
Distributed Cache Service
API Gateway
Distributed Message Service for Kafka
Distributed Message Service for RabbitMQ
Distributed Message Service for RocketMQ
Cloud Service Engine
EventGrid
Dedicated Cloud
Dedicated Computing Cluster
Aplicações de negócios
ROMA Connect
Message & SMS
Domain Name Service
Edge Data Center Management
Meeting
AI
Face Recognition Service
Graph Engine Service
Content Moderation
Image Recognition
Data Lake Factory
Optical Character Recognition
ModelArts
ImageSearch
Conversational Bot Service
Speech Interaction Service
Huawei HiLens
Developer Tools
SDK Developer Guide
API Request Signing Guide
Terraform
Koo Command Line Interface
Distribuição de conteúdo e computação de borda
Content Delivery Network
Intelligent EdgeFabric
CloudPond
Soluções
SAP Cloud
High Performance Computing
Serviços para desenvolvedore
ServiceStage
CodeArts
CodeArts PerfTest
CodeArts Req
CodeArts Pipeline
CodeArts Build
CodeArts Deploy
CodeArts Artifact
CodeArts TestPlan
CodeArts Check
Cloud Application Engine
MacroVerse aPaaS
KooPhone
KooDrive

Tempo de execução personalizado

Atualizado em 2022-11-16 GMT+08:00

Cenários

Um tempo de execução executa o código de uma função, lê o nome do manipulador de uma variável de ambiente e lê eventos de invocação das API de tempo de execução do FunctionGraph. O tempo de execução passa os dados do evento para o manipulador da função e retorna a resposta do manipulador para FunctionGraph.

O FunctionGraph oferece suporte a tempos de execução personalizados. Você pode usar um arquivo executável chamado bootstrap para incluir um runtime no pacote de implantação da função. O tempo de execução executa o método manipulador da função quando a função é invocada.

Seu tempo de execução é executado no ambiente de execução do FunctionGraph. Pode ser um script shell ou um arquivo executável binário compilado no Linux.

Após a programação, basta empacotar seu código em um arquivo ZIP (Java, Node.js, Python e Go) ou arquivo JAR (Java) e fazer o upload do arquivo para FunctionGraph para execução. Ao criar um arquivo ZIP, coloque o arquivo do manipulador sob o diretório root para garantir que seu código possa ser executado normalmente após ser descompactado.

Se você editar código em Go, compacte o arquivo compilado e verifique se o nome do arquivo de biblioteca dinâmica é consistente com o nome do plug-in do manipulador. Por exemplo, se o nome do arquivo de biblioteca dinâmica for testplugin.so, defina o nome do manipulador como testplugin.Handler.

Bootstrap do arquivo de tempo de execução

Se houver um arquivo chamado bootstrap no pacote de implantação da função, o FunctionGraph executará esse arquivo. Se o arquivo bootstrap não for encontrado ou não for executável, sua função retornará um erro quando for invocada.

O código de tempo de execução é responsável por concluir as tarefas de inicialização. Ele processa eventos de invocação em um loop até que seja encerrado.

As tarefas de inicialização são executadas uma vez para cada instância da função para preparar o ambiente para manipulação de invocações.

As API de tempo de execução

O FunctionGraph fornece as API de tempo de execução HTTP para receber eventos de chamada de função e retornar dados de resposta no ambiente de execução.

  • Próxima invocação

    Método – Get

    Caminho – http://$RUNTIME_API_ADDR/v1/runtime/invocation/request

    Essa API é usada para recuperar um evento de invocação. O corpo da resposta contém os dados do evento. A tabela a seguir descreve dados adicionais sobre a invocação contida no cabeçalho da resposta.

    Tabela 1 Informações de cabeçalho de resposta

    Parâmetro

    Descrição

    X-Cff-Request-Id

    Solicitar ID.

    X-CFF-Access-Key

    AK da conta. Uma agência deve ser configurada para a função se essa variável for usada.

    X-CFF-Auth-Token

    Token da conta. Uma agência deve ser configurada para a função se essa variável for usada.

    X-CFF-Invoke-Type

    Tipo de invocação da função.

    X-CFF-Secret-Key

    SK da conta. Uma agência deve ser configurada para a função se essa variável for usada.

    X-CFF-Security-Token

    Token de segurança da conta. Uma agência deve ser configurada para a função se essa variável for usada.

  • Resposta de invocação

    Método – POST

    Caminho – http://$RUNTIME_API_ADDR/v1/runtime/invocation/response/$REQUEST_ID

    Essa API é usada para enviar uma resposta de invocação bem-sucedida para a FunctionGraph. Depois que o tempo de execução invoca o manipulador da função, ele publica a resposta da função no caminho de resposta da invocação.

  • Erro de invocação

    Método – POST

    Caminho – http://$RUNTIME_API_ADDR/v1/runtime/invocation/error/$REQUEST_ID

    $REQUEST_ID é o valor da variável X-Cff-Request-Id no cabeçalho de uma resposta de recuperação de evento. Para obter mais informações, consulte Tabela 1.

    $RUNTIME_API_ADDR é uma variável de ambiente do sistema. Para obter mais informações, consulte Tabela 2.

    Essa API é usada para enviar uma resposta de invocação de erro para a FunctionGraph. Depois que o tempo de execução invoca o manipulador da função, ele publica a resposta da função no caminho de resposta da invocação.

Variáveis de ambiente de tempo de execução

Você pode usar variáveis de ambiente personalizadas e de tempo de execução no código de função. A tabela a seguir lista as variáveis de ambiente de tempo de execução usadas no ambiente de execução do FunctionGraph.

Tabela 2 Variáveis de ambiente

Chave

Descrição

RUNTIME_PROJECT_ID

ID do projeto

RUNTIME_FUNC_NAME

Nome da função

RUNTIME_FUNC_VERSION

Versão da função

RUNTIME_PACKAGE

Aplicativo ao qual a função pertence

RUNTIME_HANDLER

Manipulador de funções

RUNTIME_TIMEOUT

Duração do timeout da função

RUNTIME_USERDATA

Valor passado por uma variável de ambiente

RUNTIME_CPU

Número de núcleos de CPU alocados

RUNTIME_MEMORY

Memória alocada

RUNTIME_CODE_ROOT

Diretório que armazena o código da função

RUNTIME_API_ADDR

Endereço IP do host e porta de uma API de tempo de execução personalizada

O valor de uma variável de ambiente personalizada pode ser recuperado da mesma forma que o valor de uma variável de ambiente FunctionGraph.

Exemplo

Este exemplo contém um arquivo chamado bootstrap. O arquivo é implementado em Bash.

O tempo de execução carrega o script de função do pacote de implantação usando duas variáveis.

O arquivo bootstrap é o seguinte:

#!/bin/sh

set -o pipefail

#Processing requests loop
while true
do
 
HEADERS="$(mktemp)"
  # Get an event
  EVENT_DATA=$(curl
-sS -LD "$HEADERS" -X GET
"http://$RUNTIME_API_ADDR/v1/runtime/invocation/request")
  # Get request id
from response header
  REQUEST_ID=$(grep
-Fi x-cff-request-id "$HEADERS" | tr -d '[:space:]' | cut -d: -f2)
  if [ -z
"$REQUEST_ID" ]; then
    continue
  fi
  # Process request
data
 
RESPONSE="Echoing request: '$EVENT_DATA'"
  # Put response
  curl -X POST
"http://$RUNTIME_API_ADDR/v1/runtime/invocation/response/$REQUEST_ID"
-d "$RESPONSE"
done

Após carregar o script, o runtime processa eventos de invocação em um loop até que ele seja encerrado. Ele usa a API para recuperar eventos de invocação do FunctionGraph e envia as respostas para FunctionGraph.

Para obter a ID da solicitação, o runtime salva o cabeçalho da resposta da API em um arquivo temporário e lê a ID da solicitação no campo do cabeçalho x-cff-request-id. O tempo de execução processa os dados do evento recuperados e envia uma resposta de volta para FunctionGraph.

A seguir, um exemplo de código-fonte em Go. Ele pode ser executado somente após a compilação.

package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "io"
    "io/ioutil"
    "log"
    "net"
    "net/http"
    "os"
    "strings"
    "time"
)

var (
    getRequestUrl           = os.ExpandEnv("http://${RUNTIME_API_ADDR}/v1/runtime/invocation/request")
    putResponseUrl          = os.ExpandEnv("http://${RUNTIME_API_ADDR}/v1/runtime/invocation/response/{REQUEST_ID}")
    putErrorResponseUrl     = os.ExpandEnv("http://${RUNTIME_API_ADDR}/v1/runtime/invocation/error/{REQUEST_ID}")
    requestIdInvalidError   = fmt.Errorf("request id invalid")
    noRequestAvailableError = fmt.Errorf("no request available")
    putResponseFailedError  = fmt.Errorf("put response failed")
    functionPackage         = os.Getenv("RUNTIME_PACKAGE")
    functionName            = os.Getenv("RUNTIME_FUNC_NAME")
    functionVersion         = os.Getenv("RUNTIME_FUNC_VERSION")

    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("X-CFF-Request-Id")
    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, "{REQUEST_ID}", requestId, -1)
    } else {
        url = strings.Replace(putErrorResponseUrl, "{REQUEST_ID}", requestId, -1)
    }

    resp, err := client.Post(strings.Replace(url, "{REQUEST_ID}", 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
}

Tabela 3 descreve as variáveis de ambiente usadas no código anterior.

Tabela 3 Variáveis de ambiente

Variável de ambiente

Descrição

RUNTIME_FUNC_NAME

Nome da função

RUNTIME_FUNC_VERSION

Versão da função

RUNTIME_PACKAGE

Aplicativo ao qual a função pertence

Usamos cookies para aprimorar nosso site e sua experiência. Ao continuar a navegar em nosso site, você aceita nossa política de cookies. Saiba mais

Feedback

Feedback

Feedback

0/500

Conteúdo selecionado

Envie o conteúdo selecionado com o feedback