goroutine leaks no go 1.26

Detectando goroutine leaks no Go 1.26

Se você já trabalhou com Go em produção, provavelmente já enfrentou aquele cenário: goroutines que ficam presas para sempre, consumindo memória sem nunca terminar. O Go 1.26 trouxe uma ferramenta experimental que ataca esse problema direto na raiz: o goroutine leak profile.

O que são goroutine leaks?

Uma goroutine leak acontece quando uma goroutine fica bloqueada permanentemente — esperando em um channel, mutex ou condition variable que nunca vai ser desbloqueado. Na prática, é memória e recursos que ficam presos sem possibilidade de liberação.

O cenário mais clássico: você cria uma goroutine que escreve em um channel sem buffer, mas a função que deveria ler esse channel retorna antes por conta de um erro. A goroutine fica ali, bloqueada para sempre.

Leia mais »

In-Place Pod Resize — redimensionando sem restart

Se você trabalha com Kubernetes em produção, sabe que ajustar recursos de CPU e memória geralmente significa recriar os pods. Neste post, vamos explorar o In-Place Pod Resize, um recurso que permite redimensionar containers sem perder o uptime.

O que é In-Place Pod Resize?

In-Place Pod Resize é uma funcionalidade do Kubernetes que permite alterar os requests e limits de CPU e memória de um container enquanto o pod continua rodando. Não há reinicialização, sem downtime, sem interrupção de conexões.

Antes dessa feature, a única forma era deletar e recriar o pod com novos valores — algo impraticável em ambientes críticos.

Por que isso importa?

Imagine este cenário: você subiu uma aplicação com 256Mi de memória, achando que era suficiente. Alguns dias depois, monitoramento mostra que está usando 400Mi, próximo ao limite. Você precisa aumentar — e rápido.

Leia mais »

Atualizando seu código com go fix

O Go, desde suas primeiras versões, se preocupa com a evolução da linguagem sem quebrar código existente, e um dos comandos que ajuda muito nesse processo é o go fix.

Nesse post, vamos entender o que ele faz, quando utilizá-lo e como ele funciona na prática.

O que é o go fix?

O go fix é um comando da toolchain do Go que atualiza automaticamente o código-fonte para se adequar a mudanças de API introduzidas em novas versões da linguagem.

Ele funciona aplicando um conjunto de fixers — pequenas transformações automatizadas que identificam padrões de código antigos e os reescrevem para o equivalente moderno.

go fix ./...

Simples assim. O comando percorre todos os pacotes do módulo e aplica as correções necessárias.

Leia mais »

Como emitir certificados wildcard no GCP

Com o crescimento das aplicações na nuvem, garantir que elas estejam protegidas por SSL/TLS é uma prática essencial. O Google Cloud Platform (GCP) oferece diferentes formas de gerenciamento de certificados SSL, incluindo a possibilidade de emitir e vincular certificados a um Load Balancer. Uma abordagem moderna para isso é o uso de DNS Authorization para a validação dos certificados, e o uso de Certificate Maps para organizar e gerenciar vários certificados.

Neste post, vamos explorar como criar certificados com autorização via DNS, como configurar um Load Balancer e vinculá-lo ao certificado criado, usando a ferramenta de infraestrutura como código, Terraform. Além disso, vamos diferenciar entre certificados e Load Balancers clássicos e suas versões mais modernas no GCP.

Diferença entre Certificado e Certificado Clássico

No GCP, o certificado clássico refere-se à forma antiga, embora ainda válida, de gerenciar certificados SSL. Nesse processo, diferente da forma mais moderna, o certificado ficava ligado diretamente a um Load Balancer (LB), havendo uma limitação de 15 certs por LB.

Leia mais »

Gerenciando ferramentas com go tool

A versão 1.24 do Go trouxe diversas melhorias significativas, incluindo suporte completo a aliases de tipos genéricos, aprimoramentos no desempenho do runtime e novas funcionalidades no sistema de módulos.

Entre essas novidades, destaca-se a introdução do comando go tool, que simplifica o gerenciamento de dependências de ferramentas auxiliares, como linters e geradores de código, diretamente no arquivo go.mod.

Nesse post, vamos ver como utilizar esse novo comando e como essa mudança elimina a necessidade de soluções alternativas anteriormente utilizadas para rastrear ferramentas como linters e geradores de código.

Como Era Antes

Antes do Go 1.24, gerenciar ferramentas auxiliares em projetos Go exigia abordagens não oficiais.

Leia mais »

Estratégias para gerenciar múltiplas versões de APIs

No universo do desenvolvimento de software, as APIs (Application Programming Interfaces) desempenham um papel fundamental na comunicação entre diferentes sistemas. No entanto, à medida que uma API evolui, surge um desafio inevitável: como gerenciar múltiplas versões sem comprometer a experiência dos usuários e sem introduzir instabilidade no sistema?

Neste post, exploraremos as principais estratégias para gerir e versionar APIs de forma eficaz. Vamos discutir diferentes abordagens, suas vantagens e desvantagens, além de apresentar ferramentas que podem facilitar o processo.

Versionamento por URL

O versionamento por URL é uma das abordagens mais comuns e simples. Nesta estratégia, a versão da API é incluída diretamente na URL, como por exemplo:

<https://api.exemplo.com/v1/recursos>
<https://api.exemplo.com/v2/recursos>
Leia mais »

Melhores práticas para tratar erros em Go

O tratamento de erros é um aspecto fundamental do desenvolvimento de software, garantindo que suas aplicações lidem adequadamente com situações inesperadas.

Em Go, o gerenciamento de erros é tratado de forma explícita e diferenciada quando comparado a outras linguagens populares como Java, Python ou JavaScript. Esse design deliberado busca tornar os erros mais visíveis e gerenciáveis, mas também exige atenção especial por parte dos desenvolvedores para evitar armadilhas comuns.

Neste post, vamos explorar as melhores práticas para tratamento de erros em Go, garantindo que suas aplicações permaneçam robustas, legíveis e fáceis de manter.

Tratamento de Erros em Go

A maneira como o Go lida com erros difere significativamente do tradicional mecanismo de try/catch encontrado em outras linguagens de programação.

Em vez de capturar exceções, o Go utiliza um retorno explícito de erros nas funções. Esse design torna o erro parte da assinatura da função, forçando os desenvolvedores a reconhecer e lidar com os erros de forma explícita.

Leia mais »

Implementando CQRS com Go

No mundo do desenvolvimento de software, arquiteturas monolíticas e baseadas em CRUD (Create, Read, Update, Delete) têm sido amplamente utilizadas. No entanto, conforme as aplicações crescem em complexidade e demanda, essas abordagens podem se tornar limitadas, especialmente em termos de escalabilidade e separação de responsabilidades.

Nesse contexto surge o CQRS (Command Query Responsibility Segregation), um padrão arquitetural que separa as operações de escrita (commands) das operações de leitura (queries).

O que é CQRS

CQRS é um padrão que propõe a separação das responsabilidades de leitura e escrita de uma aplicação. Em um sistema tradicional, uma única camada de aplicação é responsável tanto por manipular dados quanto por recuperá-los. Com CQRS, essa responsabilidade é dividida em duas partes:

Leia mais »

Como funciona for com range

Em Go, o for é uma ferramenta poderosa e flexível para realizar iterações. Dentro desse contexto, o uso do range é uma forma comum de percorrer slices, maps, strings, arrays e channels. Porém, entender como o range funciona internamente é essencial para evitar erros sutis, especialmente ao lidar com ponteiros.

Neste post, exploraremos os fundamentos do range em Go, destacaremos diferenças entre loopings com e sem range, e discutiremos erros comuns que surgem ao usar o range com ponteiros.

Avaliando a expressão

Sem range

O for em Go pode ser usado de forma simples e direta para controlar iterações com base em uma condição.

Leia mais »

Propagação de context

Propagar o mesmo context por toda uma aplicação pode fazer sentido em alguns casos, mas não é uma prática ideal ou recomendada para todas as situações. O context deve ser utilizado cuidadosamente e com objetivos específicos.

Nesse post, vamos explorar os cenários e cuidados ao se utilizar propagação de context.

O package context

O package context é parte da biblioteca padrão do Go e foi introduzido para resolver problemas relacionados ao gerenciamento de deadlines e cancelamentos em goroutines.

Ele fornece uma maneira de passar informações importantes, como limites de tempo e sinais de cancelamento, por meio de chamadas de funções e entre diferentes partes do código.

Para entender um pouco mais sobre esse package, recomendo a leitura dos posts:

Leia mais »