Implementando probes de liveness e readiness em um aplicativo Go com MongoDB

Maike William
Fretebras Tech
Published in
4 min readApr 1, 2024

Neste artigo, vamos mostrar como implementar probes de liveness e readiness em um aplicativo Go que utiliza o MongoDB como dependência para a probe de readiness. Vamos utilizar o Kubernetes para demonstrar como configurar e utilizar essas probes em um ambiente de contêiner.

Introdução

Quando executamos um aplicativo em um ambiente de contêiner, é crucial garantir que o aplicativo esteja sempre em um estado saudável e pronto para receber tráfego. Para isso, o Kubernetes oferece duas funcionalidades importantes: probes de liveness e readiness.

  • Probe de Liveness: A probe de liveness é utilizada para verificar se o aplicativo está em execução de forma saudável. Se o aplicativo falhar na verificação da probe de liveness, o Kubernetes reiniciará o contêiner do aplicativo para tentar recuperá-lo.
  • Probe de Readiness: A probe de readiness é utilizada para verificar se o aplicativo está pronto para receber tráfego. Se o aplicativo não estiver pronto, o Kubernetes não direcionará tráfego para o contêiner, evitando assim que os usuários sejam impactados por problemas de inicialização ou carregamento do aplicativo.

Neste artigo, vamos implementar essas probes em um aplicativo Go simples que utiliza o MongoDB como dependência para a probe de readiness. Vamos mostrar como configurar os handlers em nosso aplicativo Go, bem como como configurar as probes no Kubernetes para monitorar a saúde e a prontidão de nosso aplicativo.

Preparação do ambiente

Antes de começarmos, certifique-se de ter o Kubernetes instalado em seu ambiente de desenvolvimento. Você também precisará do Docker para construir e executar o contêiner de sua aplicação. Além disso, tenha o código de sua aplicação Go e um arquivo Dockerfile configurado para criar a imagem Docker de sua aplicação.

Você pode utilizar este repositório do GitLab como referência: repositório

Implementando as probes de liveness e readiness

Vamos começar implementando os handlers para os endpoints /health/live e /health/ready em nosso aplicativo Go. O endpoint /health/live será responsável por verificar se a aplicação está em execução, enquanto o endpoint /health/ready verificará se a aplicação está pronta para receber tráfego.


func healthHandler(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
fmt.Fprintf(w, "OK")
}

func readyHandler(w http.ResponseWriter, r *http.Request) {
// Obter a URI do MongoDB da variável de ambiente
mongoURI := os.Getenv("MONGO_URI")
if mongoURI == "" {
w.WriteHeader(http.StatusInternalServerError)
fmt.Fprintf(w, "URI do MongoDB não configurada")
return
}

clientOptions := options.Client().ApplyURI(mongoURI)

// Conectar ao MongoDB
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()
client, err := mongo.Connect(ctx, clientOptions)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
fmt.Fprintf(w, "Falha ao conectar ao MongoDB: %v", err)
return
}

// Verificar se a conexão foi bem-sucedida
err = client.Ping(ctx, nil)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
fmt.Fprintf(w, "Falha ao pingar o MongoDB: %v", err)
return
}

// Se a conexão for bem-sucedida, retornar status HTTP 200 OK
w.WriteHeader(http.StatusOK)
fmt.Fprintf(w, "Conectado ao MongoDB")
}

Agora, precisamos configurar os handlers em nosso servidor HTTP e iniciar o servidor. Adicione o seguinte código ao seu main:

func main() {
http.HandleFunc("/health/live", healthHandler)
http.HandleFunc("/health/ready", readyHandler)
http.ListenAndServe(":8080", nil)
}

Este código configurará os endpoints /health/live e /health/ready em seu servidor HTTP.

Configurando os probes no Kubernetes

Agora que implementamos os handlers em nosso aplicativo Go, vamos configurar as probes no Kubernetes para monitorar a saúde de nossa aplicação. Adicione as seguintes seções ao seu arquivo de manifesto do Kubernetes (deployment.yaml):

apiVersion: apps/v1
kind: Deployment
metadata:
name: minha-aplicacao
spec:
replicas: 1
selector:
matchLabels:
app: minha-aplicacao
template:
metadata:
labels:
app: minha-aplicacao
spec:
containers:
- name: minha-aplicacao
image: minha-imagem:latest
ports:
- containerPort: 8080
env:
- name: MONGO_URI
value: "mongodb://mongo:27017" # Substitua pelo URI do seu MongoDB
livenessProbe:
httpGet:
path: /health/live
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
readinessProbe:
httpGet:
path: /health/ready
port: 8080
initialDelaySeconds: 10
periodSeconds: 5

Este arquivo de manifesto cria um deployment no Kubernetes para a sua aplicação Go, com as probes de liveness e readiness configuradas. Certifique-se de substituir minha-imagem:latest pelo nome da imagem Docker de sua aplicação Go e mongodb://mongo:27017 pelo URI do seu MongoDB.

Configurando o MongoDB no Kubernetes

Para configurar o MongoDB no Kubernetes, você pode usar o seguinte YAML:

apiVersion: v1
kind: Service
metadata:
name: mongo
spec:
selector:
app: mongo
ports:
- protocol: TCP
port: 27017
targetPort: 27017
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: mongo
spec:
replicas: 1
selector:
matchLabels:
app: mongo
template:
metadata:
labels:
app: mongo
spec:
containers:
- name: mongo
image: mongo:latest
ports:
- containerPort: 27017

Este arquivo de manifesto cria um serviço do Kubernetes para o MongoDB, permitindo que outros pods se conectem a ele, e um deployment que inicia um único pod do MongoDB. Certifique-se de substituir image: mongo:latest pelo nome da imagem MongoDB que você deseja usar.

Lidando com falhas na dependência

É crucial que sua aplicação seja capaz de lidar com falhas em suas dependências para garantir a disponibilidade do serviço. No Kubernetes, a probe de readiness nos permite fazer isso de forma eficaz.

Quando a dependência, como o MongoDB, falha, a probe de readiness detecta essa falha e marca a aplicação como não pronta para receber tráfego. Isso impede que novas requisições sejam direcionadas para a aplicação, evitando assim que os usuários sejam impactados pela falha.

Veja abaixo um GIF que simula a falha da dependência (MongoDB) e como a probe de readiness impede que a aplicação receba tráfego:

Conclusão

Neste artigo, mostramos como implementar probes de liveness e readiness em um aplicativo Go que utiliza o MongoDB como dependência para a probe de readiness. Utilizamos o Kubernetes para configurar e monitorar a saúde de nossa aplicação em um ambiente de contêiner. Esperamos que este guia seja útil para você implementar probes em seus próprios aplicativos e garantir a alta disponibilidade de seus serviços no Kubernetes.

--

--