GCP云函数在从命令行部署时返回404错误。

huangapple go评论81阅读模式
英文:

gcp cloud function returns 404 when deployed from command line

问题

如果我在控制台部署示例 hello world,URL/触发器是有效的。如果我从命令行部署,代码和云函数控制台中的属性看起来是完全相同的,但是URL返回404错误。我找不出差异/问题所在。

如果使用以下命令行方式部署 hello world 示例,部署的触发器/URL将显示"404 页面未找到"。

gcloud functions deploy hellogo --entry-point=HelloWorld --trigger-http --region=us-central1 --memory=128MB --runtime=go116 --allow-unauthenticated

以下是示例代码:

// Package p contains an HTTP Cloud Function.
package p

import (
	"encoding/json"
	"fmt"
	"html"
	"io"
	"log"
	"net/http"
)

// HelloWorld prints the JSON encoded "message" field in the body
// of the request or "Hello, World!" if there isn't one.
func HelloWorld(w http.ResponseWriter, r *http.Request) {
	var d struct {
		Message string `json:"message"`
	}

	if err := json.NewDecoder(r.Body).Decode(&d); err != nil {
		switch err {
		case io.EOF:
			fmt.Fprint(w, "Hello World!")
			return
		default:
			log.Printf("json.NewDecoder: %v", err)
			http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
			return
		}
	}

	if d.Message == "" {
		fmt.Fprint(w, "Hello World!")
		return
	}
	fmt.Fprint(w, html.EscapeString(d.Message))
}

希望这些信息对你有帮助。

英文:

If I deploy the example hello world within the console, the url/trigger works. If I deploy from command line it looks to be exact same code / attributes in cloud functions console, but the url is 404. I can't spot the difference/issue.

The deployed trigger/url shows - "404 page not found" for the below hello world example if deployed this way from command line.

gcloud functions deploy hellogo --entry-point=HelloWorld --trigger-http --region=us-central1 --memory=128MB --runtime=go116 --allow-unauthenticated

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-html -->

// Package p contains an HTTP Cloud Function.
package p

import (
	&quot;encoding/json&quot;
	&quot;fmt&quot;
	&quot;html&quot;
	&quot;io&quot;
	&quot;log&quot;
	&quot;net/http&quot;
)

// HelloWorld prints the JSON encoded &quot;message&quot; field in the body
// of the request or &quot;Hello, World!&quot; if there isn&#39;t one.
func HelloWorld(w http.ResponseWriter, r *http.Request) {
	var d struct {
		Message string `json:&quot;message&quot;`
	}

	if err := json.NewDecoder(r.Body).Decode(&amp;d); err != nil {
		switch err {
		case io.EOF:
			fmt.Fprint(w, &quot;Hello World!&quot;)
			return
		default:
			log.Printf(&quot;json.NewDecoder: %v&quot;, err)
			http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
			return
		}
	}

	if d.Message == &quot;&quot; {
		fmt.Fprint(w, &quot;Hello World!&quot;)
		return
	}
	fmt.Fprint(w, html.EscapeString(d.Message))
}

<!-- end snippet -->

答案1

得分: 1

尝试重现您的错误,但在我的环境中无法复制。我使用了与您相同的命令,并且可以成功访问URL或通过HTTP触发器调用部署的Hello World云函数。

成功的curl输出如下:

GCP云函数在从命令行部署时返回404错误。

我建议您检查您尝试访问的URL,因为根据这个GCP文档:

如果您尝试调用不存在的函数,Cloud Functions会响应一个HTTP/2 302重定向,将您带到Google账户登录页面。这是不正确的。它应该响应一个HTTP/2 404错误响应代码。这个问题正在解决中。

解决方案是:

确保正确指定函数的名称。您可以使用gcloud functions call进行检查,它会返回一个正确的404错误,表示函数不存在。

您还可以参考这个完整的指南,使用Go运行时快速启动您的云函数创建和部署。

英文:

Tried to reproduce your error but couldn't replicate on my end. I've use the same command as yours and I can successfully access the url or call via HTTP trigger the deployed hello world cloud function.

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

gcloud functions deploy hellogo --entry-point=HelloWorld --trigger-http --region=us-central1 --memory=128MB --runtime=go116 --allow-unauthenticated

<!-- end snippet -->

Output of successful curl:

GCP云函数在从命令行部署时返回404错误。

I suggest you check the url you're trying to access since according to this GCP doc:

> If you attempt to invoke a function that does not exist, Cloud Functions responds with an HTTP/2 302 redirect which takes you to the Google account login page. This is incorrect. It should respond with an HTTP/2 404 error response code. The problem is being addressed.

The solution

> Make sure you specify the name of your function correctly. You can
> always check using gcloud functions call which returns the correct 404
> error for a missing function.

You can also refer to this complete guide to quickstart your CF creation and deployment using the Go runtime.

答案2

得分: 0

谢谢大家,我遇到的项目比这个函数还要复杂。在尝试在较大的项目中部署单个函数/文件后,我选择了这条路径。如果我简化为只有一个名为hello.gogo.mod的文件夹,确实可以通过命令行部署它:

gcloud functions deploy hellogo --entry-point=HelloWorld --trigger-http --region=us-central1 --memory=128MB --runtime=go116 --allow-unauthenticated

// go.mod

module github.com/nickfoden/hello

go 1.16

感谢快速回复和帮助。与其尝试在现有项目中创建一个具有较大go.sum、多个文件夹和现有服务器/ API的单个函数,我将从这里开始,使用一个单独的文件和一个云函数,并在此基础上构建,看看在什么时候/是否再次遇到问题。

英文:

Thanks all, my project where I got stuck has more code in it than just this function. I went down this path after trying to deploy a single function/file within larger project. If I simplify down to a folder with just a hello.go and go.mod indeed it works :-/ to deploy it from command line:

gcloud functions deploy hellogo --entry-point=HelloWorld --trigger-http --region=us-central1 --memory=128MB --runtime=go116 --allow-unauthenticated

// go.mod

module github.com/nickfoden/hello

go 1.16

Thank you for the fast replies and assistance. Rather than try to create a single function within existing project with larger go.sum, multiple folders, existing server/api etc. I am going to start from here having a single file with a cloud function and build on top of it and see at what point/if I get stuck again.

huangapple
  • 本文由 发表于 2022年2月12日 08:01:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/71087844.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定