ALB: 502 respuesta de puerta de enlace incorrecta

[vc_row el_class=”blog-info”][vc_column][vc_single_image source=”featured_image” img_size=”full” style=”vc_box_rounded”][vc_empty_space height=”40px”][vc_row_inner][vc_column_inner width=”1/6″][/vc_column_inner][vc_column_inner width=”2/3″][vc_column_text el_class=”font-weight-bold”]

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.

[/vc_column_text][vc_empty_space height=”40px”][/vc_column_inner][vc_column_inner width=”1/6″][/vc_column_inner][/vc_row_inner][vc_row_inner][vc_column_inner width=”1/6″][/vc_column_inner][vc_column_inner width=”2/3″][vc_column_text]


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.

ALB

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!


Referencias

[/vc_column_text][/vc_column_inner][vc_column_inner width=”1/6″][/vc_column_inner][/vc_row_inner][/vc_column][/vc_row][vc_row el_class=”social-info”][vc_column width=”1/6″][/vc_column][vc_column width=”2/3″][vc_row_inner][vc_column_inner width=”1/2″][vc_column_text][social_share_button themes=’theme1′][/vc_column_text][/vc_column_inner][vc_column_inner el_class=”youtube-inner-col” width=”1/2″][vc_column_text][likebtn theme=”youtube” lang=”auto” show_like_label=”0″ white_label=”1″ alignment=”right”][/vc_column_text][/vc_column_inner][/vc_row_inner][vc_row_inner el_class=”social-info-inner”][vc_column_inner width=”1/4″][vc_single_image image=”921″][/vc_column_inner][vc_column_inner width=”3/4″][vc_column_text]

Diego Pacheco

Ingeniero en Sitemas, MBA (Babson College). Desarrollador PHP/Java/JavaScript. Fundador & CEO de EpicStudio. Entusiasta de las tecnologías web (JavaScript, Vue, Laravel, AWS, Docker) Viajes, Negocios, Surf y Growth.[/vc_column_text][asvc_list_item icon_fontawesome=”fa fa-calendar-o” icon_size=”14px”]Programar una reunión[/asvc_list_item][/vc_column_inner][/vc_row_inner][/vc_column][vc_column width=”1/6″][/vc_column][/vc_row][vc_row][vc_column][vc_column_text]

Recent Post

[/vc_column_text][lvca_posts_carousel posts_query=”size:3|order_by:rand|post_type:post” image_linkable=”true” image_size=”full” taxonomy_chosen=”post_tag” display_title=”true” display_post_date=”true” display_summary=”true” autoplay_speed=”3000″ animation_speed=”300″ display_columns=”3″ scroll_columns=”3″ gutter=”3″ tablet_display_columns=”2″ tablet_scroll_columns=”2″ tablet_gutter=”3″ tablet_width=”800″ mobile_display_columns=”1″ mobile_scroll_columns=”1″ mobile_gutter=”3″ mobile_width=”480″][vc_empty_space height=”20px”][/vc_column][/vc_row]