为了账号安全,请及时绑定邮箱和手机立即绑定

每次使用应用引擎中的数据存储都会超时

每次使用应用引擎中的数据存储都会超时

Go
慕姐8265434 2022-01-17 16:37:56
我第一次使用谷歌云环境,特别是谷歌应用引擎和数据存储,当我在本地运行时一切正常。我通过按照文档设置环境变量 GOOGLE_APPLICATION_CREDENTIALS 对数据存储进行身份验证。但是一旦我部署到应用程序引擎,请求总是超时,似乎 GetAll 方法永远不会返回。以下是我的应用程序的代码:package appimport (    "fmt"    "net/http"    "time"    "golang.org/x/net/context"    "google.golang.org/appengine"    "google.golang.org/cloud/datastore")type User struct {    FirstName string    LastName string    Email string    Created time.Time    id      int64}func init() {    http.HandleFunc("/", handler)}func handler(w http.ResponseWriter, r *http.Request) {    var err error    var dbClient *datastore.Client    var ctx context.Context    ctx = appengine.NewContext(r)    dbClient, err = datastore.NewClient(ctx, "app-id")//this has the real app id, not sure if this is meant to be secret    if err != nil {        fmt.Fprintf(w, "Could not create datastore client: %+v", err)        return    }    defer dbClient.Close()    var users []*User    query := datastore.NewQuery("User").Filter("Email=", "jcarm010@fiu.edu")    keys, err := dbClient.GetAll(ctx, query, &users)    if err != nil {        fmt.Fprintf(w, "Could not query users: %+v", err)        return    }    for i, key := range keys {        users[i].id = key.ID()        fmt.Fprintf(w, "%+v\n",users[i])    }    fmt.Fprintf(w, "done!!!")}App Engine 日志中的错误有以下两行:This request caused a new process to be started for your application, and thus caused your application code to be loaded for the first time. This request may thus take longer and use more CPU than a typical request for your application.Process terminated because the request deadline was exceeded. (Error code 123)顺便说一句,这在我的本地快速完成,并且我的数据存储中只有一条记录。关于为什么会发生这种情况或如何调试它的任何猜测?谢谢
查看完整描述

2 回答

?
吃鸡游戏

TA贡献1829条经验 获得超7个赞

这些datastore包使用gRPC连接到数据存储服务。您不能直接在 App Engine 上使用它,因为您不能直接建立 TCP 连接。


您需要使用socketsAPI 为您建立 TCP 连接:


import "google.golang.org/appengine/socket" // et al


ctx := appengine.NewContext(r)

ctx, cancel := context.WithTimeout(ctx, 5*time.Second)

defer cancel()


dialer := func(addr string, timeout time.Duration) (net.Conn, error) {

    return socket.DialTimeout(ctx, "tcp", addr, timeout)

}


client, err := datastore.NewClient(ctx, "app-id", cloud.WithGRPCDialOption(grpc.WithDialer(dialer)))

您也可以dialer在调试时直接调用,以确保它能够按预期访问 datastore.googleapis.com:443:


conn, err := dialer("datastore.googleapis.com:443", 5*time.Second)

if err != nil {

    log.Errorf(ctx, "Dial: %v", err)

    http.Error(w, "Dial failed: "+err.Error(), http.StatusInternalServerError)

    return

}

fmt.Fprintf(w, "Addr: %v\n", conn.RemoteAddr())

conn.Close()


查看完整回答
反对 回复 2022-01-17
?
慕村9548890

TA贡献1884条经验 获得超4个赞

我的问题的解决方案是切换数据存储库

从: "google.golang.org/cloud/datastore"

到: "google.golang.org/appengine/datastore"

appengine/datastore 似乎使用了不同的协议,因此您不必使用 GOOGLE_APPLICATION_CREDENTIALS 环境变量进行身份验证。在本地使用时,它将为不同的应用程序引擎服务使用开发服务器,在部署时使用云资源。


查看完整回答
反对 回复 2022-01-17
  • 2 回答
  • 0 关注
  • 112 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信