Azure Functions y Container Apps para Go
Microsoft Azure aloja Go a través de dos rutas principales: Azure Functions con un proceso de manejador personalizado y Azure Container Apps (ACA) para imágenes OCI con reglas de escala.
Busca en todas las páginas de la documentación
Microsoft Azure aloja Go a través de dos rutas principales: Azure Functions con un proceso de manejador personalizado y Azure Container Apps (ACA) para imágenes OCI con reglas de escala.
Ambos aceptan los mismos patrones de binarios estáticos de Go que utilizas en AWS y GCP; las diferencias radican en los contratos de alojamiento y la configuración de la identidad.
Los manejadores personalizados de Functions permiten que Go posea un servidor HTTP en un puerto asignado por la plataforma, mientras que el host de Functions le reenvía los eventos del disparador.
Container Apps ejecuta tu imagen como Cloud Run con escalado a cero opcional y disparadores KEDA (HTTP, colas, cron).
Utiliza la identidad administrada y las referencias a Key Vault en lugar de cadenas de conexión en la configuración de la aplicación.
Tarjeta de receta de referencia rápida, lista para copiar y pegar.
// cmd/functions/main.go - esqueleto del manejador personalizado
http.HandleFunc("/api/HttpExample", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
_, _ = w.Write([]byte(`{"message":"hola desde go"}`))
})
port := os.Getenv("FUNCTIONS_CUSTOMHANDLER_PORT")
log.Fatal(http.ListenAndServe(":"+port, nil))# Esquema de implementación de Container Apps
az containerapp up --name go-api --source . --ingress external --target-port 8080Cuándo recurrir a esto:
package main
import (
"encoding/json"
"log/slog"
"net/http"
"os"
)
type response struct {
Message string `json:"message"`
}
func main() {
slog.SetDefault(slog.New(slog.NewJSONHandler(os.Stdout, nil)))
mux := http.NewServeMux()
mux.HandleFunc("POST /api/process", func(w http.ResponseWriter, r *http.Request) {
var payload map[string]any
if err := json.NewDecoder(r.Body).Decode(&payload); err != nil {
http.Error(w, "json malo", http.StatusBadRequest)
return
}
slog.Info("evento", "claves", len(payload))
w.Header().Set("Content-Type", "application/json")
_ = json.NewEncoder(w).Encode(response{Message: "procesado"})
})
mux.HandleFunc("GET /health", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusNoContent)
})
port := os.Getenv("FUNCTIONS_CUSTOMHANDLER_PORT")
if port == "" {
port = os.Getenv("PORT")
}
if port == "" {
port = "8080"
}
slog.Info("escuchando", "puerto", port)
if err := http.ListenAndServe(":"+port, mux); err != nil {
slog.Error("fallo al escuchar", "err", err)
os.Exit(1)
}
}Lo que esto demuestra:
FUNCTIONS_CUSTOMHANDLER_PORT para Functions, PORT para Container Apps.| Dimensión | Azure Functions (manejador personalizado) | Azure Container Apps |
|---|---|---|
| Unidad de implementación | Binario + configuración del host function.json | Imagen de contenedor |
| Disparadores | Catálogo de enlaces integrados | Escaladores KEDA (HTTP, SB, cron) |
| Escala | Planes de Consumo o Premium | Réplicas mín/máx, escalado a cero |
| Estilo Go | net/http en puerto personalizado | Igual que los patrones de Cloud Run |
| Identidad | Identidad administrada asignada por el sistema | Identidad administrada en la aplicación |
host.json y function.json{
"bindings": [{
"authLevel": "function",
"type": "httpTrigger",
"direction": "in",
"name": "req",
"methods": ["post"],
"route": "process"
}, {
"type": "http",
"direction": "out",
"name": "res"
}]
}Empareja cada disparador con una ruta que tu mux de Go implemente; las rutas no coincidentes devuelven un 404 desde tu proceso mientras que el host sigue facturando la invocación.
FUNCTIONS_CUSTOMHANDLER_PORT: El host de Functions asigna el puerto; codificar 8080 de forma fija falla localmente con func start. Solución: Siempre enlaza os.Getenv("FUNCTIONS_CUSTOMHANDLER_PORT").SIGTERM de ACA: Los mismos requisitos de apagado elegante que Cloud Run. Solución: signal.Notify + http.Server.Shutdown.0.0.0.0: Enlazar a 127.0.0.1 rompe las sondas de estado de entrada. Solución: Escuchar en 0.0.0.0 / : + puerto.| Alternativa | Usar Cuando | No Usar Cuando |
|---|---|---|
| Azure App Service | Aplicaciones web simples de Windows/Linux | Necesitas escalado de cola KEDA |
| AKS | Operadores de Kubernetes y CRDs | API Go única con operaciones mínimas |
| AWS Lambda / Cloud Run | Estándar multicloud | La identidad y la red de Azure son fijas |
| Solo Azure API Management | Políticas de puerta de enlace sin cómputo | Todavía necesitas un backend Go en alguna parte |
Los lenguajes de primera clase en proceso de Azure difieren según la generación del runtime.
Go en producción en Functions utiliza típicamente el modelo de manejador personalizado con tu propio servidor HTTP.
Sí, con escaladores KEDA basados en HTTP o eventos configurados para permitir cero réplicas.
Los arranques en frío se parecen a Cloud Run; mantén las imágenes ligeras.
Habilita OpenTelemetry o utiliza el SDK de Go de Application Insights; emite registros JSON a stdout para una correlación automática cuando se configure en el host.
ACA suele ser más simple para HTTP siempre disponible con middleware estándar.
Functions destaca cuando necesitas el catálogo de enlaces para disparadores de Temporizador/Cola/Blob junto con puntos de conexión HTTP pequeños.
A menudo sí; cambia el comando de implementación a az containerapp up o tareas de canalización y verifica la configuración del puerto y la comprobación de estado.
Versiones de Stack: Esta página se escribió para Go 1.26.x (predeterminado Green Tea GC,
go fix modernizers- verifica el parche en la compilación), chi (última versión - verifica en la compilación), gin (última versión - verifica en la compilación), echo (última versión - verifica en la compilación), google.golang.org/grpc (última versión - verifica en la compilación), sigs.k8s.io/controller-runtime (última versión - verifica en la compilación), kubebuilder (última versión - verifica en la compilación), tinygo (última versión - verifica los objetivos de placa en la compilación), wazero (última versión - verifica en la compilación) y golangci-lint (última versión - verifica el conjunto de linters en la compilación).
Revisado por Chris St. John·Última actualización: 16 jul 2026