Go Lambda 的 AWS ALB 总是 returns “502 Bad Gateway”
AWS ALB of a Go Lambda always returns "502 Bad Gateway"
我有一个使用 Go 语言实现的 AWS Lambda。 Lambda 由 ALB 触发。当我从外部调用 ALB 时,它总是 returns this:
<html>
<head><title>502 Bad Gateway</title></head>
<body bgcolor="white">
<center><h1>502 Bad Gateway</h1></center>
</body>
</html>
在 CloudWatch 中,我可以看到调用了 Lambda。在此 article 中,我读到 ALB 期望来自 Lambda 的非常具体的响应对象。我已经将其实现为一个结构。这是 Go Lambda 代码:
package main
import (
"context"
"encoding/json"
"fmt"
"github.com/aws/aws-lambda-go/lambda"
"log"
)
type Request struct {
HttpMethod string `json:"httpMethod"`
Path string `json:"path"`
QueryStringParameters map[string]string `json:"queryStringParameters"`
IsBase64Encoded bool `json:"isBase64Encoded"`
Body string `json:"body"`
Headers RequestHeaders `json:"headers"`
}
type RequestHeaders struct {
Accept string `json:"accept"`
AcceptLanguage string `json:"accept-language"`
ContentType string `json:"Content-Type"`
Cookie string `json:"cookie"`
Host string `json:"host"`
UserAgent string `json:"user-agent"`
XAmznTraceId string `json:"x-amzn-trace-id"`
XForwardedFor string `json:"x-forwarded-for"`
XForwardedPort string `json:"x-forwarded-port"`
XForwardedProto string `json:"x-forwarded-proto"`
}
type Response struct {
IsBase64Encoded bool `json:"isBase64Encoded"`
StatusCode int `json:"statusCode"`
StatusDescription string `json:"statusDescription"`
Headers *ResponseHeaders `json:"headers"`
Body string `json:"body"`
}
type ResponseHeaders struct {
ContentType string `json:"Content-Type"`
}
func HandleRequest(ctx context.Context, request Request) (string, error) {
fmt.Println("Hello " + request.Body)
responseHeaders := new(ResponseHeaders)
responseHeaders.ContentType = "application/json"
response := new(Response)
response.IsBase64Encoded = false
response.StatusCode = 200
response.StatusDescription = "200 OK"
response.Headers = responseHeaders
response.Body = "{\"hello\":\"world\"}"
json, err := json.Marshal(response)
if err != nil {
log.Fatal(err)
}
responseString := string(json)
log.Println(responseString)
return responseString, nil
}
func main() {
lambda.Start( HandleRequest )
}
在 Cloudwatch 中,我可以看到调用了 Lambda 并且这是它的字符串 returns:
{
"isBase64Encoded": false,
"statusCode": 200,
"statusDescription": "200 OK",
"headers": {
"Content-Type": "application/json"
},
"body": "{\"hello\":\"world\"}"
}
据我所知,它看起来像 article 中描述的响应规范。
来自 ALB 本身的日志如下所示:
http 2020-07-13T11:49:51.014327Z app/test-Lambda/3e92b31e6a921454 176.199.208.26:54486 - 0.006 0.021 -1 502 - 736 293 "POST http://test-lambda-999999999.eu-central-1.elb.amazonaws.com:80/ HTTP/1.1" "insomnia/7.1.1" - - arn:aws:elasticloadbalancing:eu-central-1:999999999:targetgroup/test-lambda-target/540454d9390da765 "Root=1-5f0c4a5e-ca4e4a43b6c48633dc4c5b3e" "-" "-" 0 2020-07-13T11:49:50.986000Z "forward" "-" "LambdaInvalidResponse" "-" "-"
我已经投入了几个小时进行调试,但我真的不知道为什么 ALB 总是 returns 502 错误。你能看到错误吗?我做错了什么?
通过注释中的调试解决:您需要 return 来自处理程序的实际 Response
结构,而不是包含 JSON 的字符串。 lambda
库自行处理将 return 值序列化为 JSON。
我有一个使用 Go 语言实现的 AWS Lambda。 Lambda 由 ALB 触发。当我从外部调用 ALB 时,它总是 returns this:
<html>
<head><title>502 Bad Gateway</title></head>
<body bgcolor="white">
<center><h1>502 Bad Gateway</h1></center>
</body>
</html>
在 CloudWatch 中,我可以看到调用了 Lambda。在此 article 中,我读到 ALB 期望来自 Lambda 的非常具体的响应对象。我已经将其实现为一个结构。这是 Go Lambda 代码:
package main
import (
"context"
"encoding/json"
"fmt"
"github.com/aws/aws-lambda-go/lambda"
"log"
)
type Request struct {
HttpMethod string `json:"httpMethod"`
Path string `json:"path"`
QueryStringParameters map[string]string `json:"queryStringParameters"`
IsBase64Encoded bool `json:"isBase64Encoded"`
Body string `json:"body"`
Headers RequestHeaders `json:"headers"`
}
type RequestHeaders struct {
Accept string `json:"accept"`
AcceptLanguage string `json:"accept-language"`
ContentType string `json:"Content-Type"`
Cookie string `json:"cookie"`
Host string `json:"host"`
UserAgent string `json:"user-agent"`
XAmznTraceId string `json:"x-amzn-trace-id"`
XForwardedFor string `json:"x-forwarded-for"`
XForwardedPort string `json:"x-forwarded-port"`
XForwardedProto string `json:"x-forwarded-proto"`
}
type Response struct {
IsBase64Encoded bool `json:"isBase64Encoded"`
StatusCode int `json:"statusCode"`
StatusDescription string `json:"statusDescription"`
Headers *ResponseHeaders `json:"headers"`
Body string `json:"body"`
}
type ResponseHeaders struct {
ContentType string `json:"Content-Type"`
}
func HandleRequest(ctx context.Context, request Request) (string, error) {
fmt.Println("Hello " + request.Body)
responseHeaders := new(ResponseHeaders)
responseHeaders.ContentType = "application/json"
response := new(Response)
response.IsBase64Encoded = false
response.StatusCode = 200
response.StatusDescription = "200 OK"
response.Headers = responseHeaders
response.Body = "{\"hello\":\"world\"}"
json, err := json.Marshal(response)
if err != nil {
log.Fatal(err)
}
responseString := string(json)
log.Println(responseString)
return responseString, nil
}
func main() {
lambda.Start( HandleRequest )
}
在 Cloudwatch 中,我可以看到调用了 Lambda 并且这是它的字符串 returns:
{
"isBase64Encoded": false,
"statusCode": 200,
"statusDescription": "200 OK",
"headers": {
"Content-Type": "application/json"
},
"body": "{\"hello\":\"world\"}"
}
据我所知,它看起来像 article 中描述的响应规范。
来自 ALB 本身的日志如下所示:
http 2020-07-13T11:49:51.014327Z app/test-Lambda/3e92b31e6a921454 176.199.208.26:54486 - 0.006 0.021 -1 502 - 736 293 "POST http://test-lambda-999999999.eu-central-1.elb.amazonaws.com:80/ HTTP/1.1" "insomnia/7.1.1" - - arn:aws:elasticloadbalancing:eu-central-1:999999999:targetgroup/test-lambda-target/540454d9390da765 "Root=1-5f0c4a5e-ca4e4a43b6c48633dc4c5b3e" "-" "-" 0 2020-07-13T11:49:50.986000Z "forward" "-" "LambdaInvalidResponse" "-" "-"
我已经投入了几个小时进行调试,但我真的不知道为什么 ALB 总是 returns 502 错误。你能看到错误吗?我做错了什么?
通过注释中的调试解决:您需要 return 来自处理程序的实际 Response
结构,而不是包含 JSON 的字符串。 lambda
库自行处理将 return 值序列化为 JSON。