502 respuesta de puerta de enlace incorrecta de AWS ALB con Lambda y Golang
Como sabemos, AWS API Gateway es costoso, por lo que utilizo ALB en lugar de API Gateway. Generalmente, usé apex / gateway para hacer el servicio, pero parece que ya no se mantiene, así que cambio el gateway a aws-lambda-go-api-proxy y hago un servicio simple como el código de abajo.
package main import ( "context" "net/http" "github.com/aws/aws-lambda-go/events" "github.com/aws/aws-lambda-go/lambda" ginadapter "github.com/awslabs/aws-lambda-go-api-proxy/gin" "github.com/gin-gonic/gin" ) var ginLambda *ginadapter.GinLambda func main() { r := gin.Default() r.GET("/ping", func(c *gin.Context) { c.String(http.StatusOK, "pong") }) ginLambda = ginadapter.New(r) lambda.Start(Handler) } func Handler(ctx context.Context, request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) { return ginLambda.ProxyWithContext(ctx, request) }
Después de subir el servicio a Lambda, lo pruebo en la consola web, ¡funciona! A continuación, configuro ALB y el grupo objetivo, y registro la función Lambda en el grupo objetivo.
Todo está listo, envié una solicitud a ALB y obtuve la respuesta 502 Bad Gateway. No tengo idea de lo que sucedió, todo parece estar bien y la configuración también, Así que queda mantener la calma y revisar el registro primero; revisé el registro en CloudWatch y, por sorpresa, el servicio estaba funcionando bien.
START RequestId: 5ec24c73-bc46-4b1e-909b-e899960bc86a Version: $LATEST [GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached. [GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production. - using env: export GIN_MODE=release - using code: gin.SetMode(gin.ReleaseMode) [GIN-debug] GET /ping --> main.main.func1 (3 handlers) [GIN] 2021/11/09 - 02:31:31 | 200 | 5.306µs | | GET "/ping" END RequestId: 5ec24c73-bc46-4b1e-909b-e899960bc86a REPORT RequestId: 5ec24c73-bc46-4b1e-909b-e899960bc86a Duration: 4.27 ms Billed Duration: 5 ms Memory Size: 512 MB Max Memory Used: 39 MB Init Duration: 141.70 ms
Es extraño, ¿verdad? Entonces, habilité la verificación de salud en ALB y después de eso, encontré que la verificación de salud devolvía el error.
Mmm, ¿el formato de respuesta no es válido? Veamos la respuesta.
{
"statusCode": 200,
"statusDescription": "200 OK",
"isBase64Encoded": False,
"headers": {
"Content-Type": "text/html"
},
"body": "<h1>Hello from Lambda!</h1>"
}
{
"statusCode": 404,
"headers": null,
"multiValueHeaders": {
"Content-Type": [
"text/plain"
]
},
"body": "404 page not found"
}
Como vemos, la respuesta de ALB son los encabezados, pero los encabezados del proxy son nulos, y a continuación se muestra la resolución el problema.
package main import ( "context" "net/http" "strings" "github.com/aws/aws-lambda-go/events" "github.com/aws/aws-lambda-go/lambda" ginadapter "github.com/awslabs/aws-lambda-go-api-proxy/gin" "github.com/gin-gonic/gin" ) var ginLambda *ginadapter.GinLambda func main() { r := gin.Default() r.GET("/ping", func(c *gin.Context) { c.String(http.StatusOK, "pong") }) ginLambda = ginadapter.New(r) lambda.Start(Handler) } func Handler(ctx context.Context, request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) { response, err := ginLambda.ProxyWithContext(ctx, request) headers := make(map[string]string) for key, value := range response.MultiValueHeaders { headers[key] = strings.Join(value, ",") } response.Headers = headers return response, err }
Cree el código y súbalo de nuevo, funciona.
Si este artículo es útil, por favor, regáleme una 👍🏼 y compártalo con sus colegas.
¡Gracias!