This post has been republished via RSS; it originally appeared at: New blog articles in Microsoft Community Hub.
As configurações do ambiente execução do Go podem impactar o comportamento de um serviço em determinado ambiente.
Entender quais configurações são necessárias é imprescindível quando se trata de garantir o máximo de eficiência e desempenho de um serviço escrito em Go.
A configuração GOMAXPROCS dita o comportamento do serviço em relação ao consumo de CPU.
GOMAXPROCS: Número de "threads" disponíveis para o processo. O valor padrão é o número de núcleos daCPU.
Neste artigo, vou descrever minha experiência em busca da configuração ideal para um serviço hospedado no Kubernetes.
GOMAXPROCS e goroutines
A documentação oficial do Go refere-se às goroutines como sendo um tipo de thread mais leve. Embora correta, essa afirmação pode gerar confusões.
Uma goroutine é uma estrutura usada pelo runtime da qual conterá uma pilha de execução, onde o próprio runtime pode gerenciar sua execução. Para gerenciar a execução das rotinas, o Go implementa três componentes principais, introduzidos por Dmitry Vyukov em seu trabalho Scalable Go Scheduler Design Doc.
De forma resumida, são eles:
G (Goroutine): Contem a pilha de execução e todos artefatos necessários para execução, descrito na documentação como um tipo dethread, porém muito mais leve.M (Thread): M é a forma mais comum de referenciar umathreaddo sistema operacional.P (Processor): Processor é uma estrutura lógica introduzida porDmitry Vyukovpara minimizar o número degoroutinesque ficam em estado de espera quando umathread Mrealiza uma operação bloqueante, conhecida comosys-call. OProcessorimplementa uma série de algoritmos que controlam a distribuição das rotinas entre asthreadsdisponíveis. Vale lembrar que existe uma relação íntima entre umProcessor Pe umaThread M, porque oPé uma estrutura lógica e, no fim do dia, vai rodar no contexto de umaThread M.
A variável de ambiente GOMAXPROCS controla o número máximo de Processors disponíveis para nossa aplicação. Para facilitar o entendimento deste ponto, o GOMAXPROCS não controla o número máximo de Threads M disponíveis para nossa aplicação. Em outras palavras, ela não inclui o número de threads bloqueadas, realizando uma chamada para o kernel do SO.
Em outras palavras, o GOMAXPROCS controla o número máximo de threads que podem ser processadas de forma concorrente pelo processador do sistema operacional. O valor padrão é o número de núcleos do processador do host da aplicação.
Definir um valor muito alto para o GOMAXPROCS pode gerar um grande número de trocas de contexto da CPU.
GOMAXPROCS no Kubernetes
O GOMAXPROCS ainda não tem uma integração nativa com os limites definidos para um pod do Kubernetes.
Por exemplo, um pod com limite de 1 núcleo de CPU, rodando em um node com 64 núcleos de CPU, vai acabar tendo o valor padrão GOMAXPROCS=64.
A empresa Uber realizou uma série de estudos em relação aos comportamentos desse desencontro de configurações no repositório do Github: uber-go/automaxprocs.
Configurar GOMAXPROCS na definição do contêiner
Para resolver esse problema, podemos configurar a variável nas especificações do contêiner da seguinte forma:
env:
- name: GOMAXPROCS
valueFrom:
resourceFieldRef:
resource: limits.cpu
Imagine uma imagem docker, contendo a seguinte aplicação:
package main
import (
"fmt"
"runtime"
"runtime/debug")
func main() {
fmt.Printf("GOMAXPROCS: %d\n", runtime.GOMAXPROCS(0))
}
Podemos aplicar a configuração mencionada anteriormente na definição de um contêiner, como no exemplo abaixo:
apiVersion: v1
kind: Pod
metadata:
name: app
spec:
containers:
- name: app
image: imagem-da-aplicação
resources:
limits:
cpu: 1500m
env:
- name: GOMAXPROCS
valueFrom:
resourceFieldRef:
resource: limits.cpu
O resultado que você terá, ao conferir os logs de execução deste pod é:
GOMAXPROCS: 2
Conclusão
Entender a relação entre o número de núcleos da CPU, threads e goroutines é essencial para elevar o nível de eficiência do seu serviço Go. Este artigo pode servir de base para que você realize e aprofunde seus estudos sobre o assunto proposto, para que possa ter uma grande consciência da estratégia que pretende utilizar, mudando ou não a configuração GOMAXPROCS.
