【问题标题】:What does a production ready Google Cloud Function look like? [closed]生产就绪的 Google Cloud Function 是什么样的? [关闭]
【发布时间】:2023-04-05 16:14:01
【问题描述】:

我刚刚开始使用 Google Cloud Functions 进行整个无服务器操作,所有示例基本上都是“Helloworld”。

package function

import (
    "net/http"
)

func F(w http.ResponseWriter, r *http.Request) {
    w.Write([]byte("Hello, World!\n"))
}

生产就绪功能是什么样的?

【问题讨论】:

  • 这取决于它做什么(或它应该做什么)。这个问题太笼统了。
  • 我同意这个问题太宽泛了。但是通过查看答案,其中有一些其他开发人员可能也在寻找的重要信息。 @KelseyHightower:有没有办法可以将问题表述为更具体的问题? IE。生产就绪的云功能比您在答案中分享的内容要多得多,但它可能是“我可以从云功能登录到堆栈驱动程序吗?”的完美答案。
  • 这个问题是 GopherCon 2018 主题演讲的一部分 - Going Serverless youtube.com/watch?v=laz6ghZv-ZU

标签: go google-cloud-platform google-cloud-functions serverless faas


【解决方案1】:

鉴于提供商会为您处理诸如扩展之类的事情,我要做的第一件事就是关注可观察性。你不知道你不知道什么。我喜欢添加自己的跟踪和结构化日志记录;记录到标准输出在许多方面都存在不足。

package function

import (
    "context"
    "fmt"
    "net/http"
    "os"
    "sync"

    "cloud.google.com/go/logging"
    "contrib.go.opencensus.io/exporter/stackdriver"
    "contrib.go.opencensus.io/exporter/stackdriver/propagation"
    "go.opencensus.io/trace"
    "google.golang.org/genproto/googleapis/api/monitoredres"
)

var (
    logger *logging.Logger
    once   sync.Once
)

// configFunc sets the global configuration; it's overridden in tests.
var configFunc = defaultConfigFunc

func F(w http.ResponseWriter, r *http.Request) {
    once.Do(func() {
        if err := configFunc(); err != nil {
           panic(err)
        }
    })

    defer logger.Flush()

    ctx := r.Context()
    var span *trace.Span

    httpFormat := &propagation.HTTPFormat{}
    sc, ok := httpFormat.SpanContextFromRequest(r)
    if ok {
        ctx, span = trace.StartSpanWithRemoteParent(ctx, "helloworld", sc,
            trace.WithSampler(trace.AlwaysSample()),
            trace.WithSpanKind(trace.SpanKindServer),
        )
        defer span.End()
    }

    logger.Log(logging.Entry{
        Payload:  "Handling new HTTP request",
        Severity: logging.Info,
    })

    w.Write([]byte("Hello, World!\n"))
}

func defaultConfigFunc() error {
    var err error

    projectId := os.Getenv("GCP_PROJECT")
    if projectId == "" {
            return fmt.Errorf("GCP_PROJECT environment variable unset or missing")
    }

    functionName := os.Getenv("FUNCTION_NAME")
    if functionName == "" {
            return fmt.Errorf("FUNCTION_NAME environment variable unset or missing")
    }

    region := os.Getenv("FUNCTION_REGION")
    if region == "" {
        return fmt.Errorf("FUNCTION_REGION environment variable unset or missing")
    }

    stackdriverExporter, err := stackdriver.NewExporter(stackdriver.Options{ProjectID: projectId})
    if err != nil {
        return err
    }

    trace.RegisterExporter(stackdriverExporter)
    trace.ApplyConfig(trace.Config{DefaultSampler: trace.AlwaysSample()})

    client, err := logging.NewClient(context.Background(), projectId)
    if err != nil {
        return err
    }

    monitoredResource := monitoredres.MonitoredResource{
        Type: "cloud_function",
        Labels: map[string]string{
            "function_name": functionName,
            "region":        region,
        },
    }

    commonResource := logging.CommonResource(&monitoredResource)
    logger = client.Logger(functionName, commonResource)

    return nil
}

另外,请确保您提供了所有依赖项,您确实希望您的构建是可重现的。这些天我正在使用 Go 1.11,以下对我有用:

$ mkdir helloworld
$ cd helloworld
$ vim function.go
$ echo "module github.com/kelseyhightower/helloworld" > go.mod
$ go mod vendor  

【讨论】:

猜你喜欢
  • 2023-04-07
  • 1970-01-01
  • 2019-06-11
  • 1970-01-01
  • 2018-09-16
  • 1970-01-01
  • 2021-06-16
  • 2010-11-12
  • 1970-01-01
相关资源
最近更新 更多