Sobes.tech
Назад к вопросам
Middle+
3

Есть ли интересные нюансы с GOMAXPROCS и cgroups в Linux?

Компании, где спрашивали
МВидеоМВидео

Ответ от нейросети

sobes.tech AI

В Linux при использовании cgroups (control groups) для ограничения ресурсов контейнеров или процессов есть важный нюанс с переменной окружения GOMAXPROCS в Go.

По умолчанию Go рантайм устанавливает GOMAXPROCS равным количеству доступных CPU, которые видит система. Однако в контейнеризованных средах (например, Docker) или при использовании cgroups, ядро может ограничивать доступный процессу CPU, но Go рантайм может не учитывать эти ограничения и считать доступными все CPU хоста.

Это приводит к ситуации, когда GOMAXPROCS больше реального количества доступных CPU, что может вызвать избыточный контекстный переключатель и ухудшение производительности.

Начиная с Go 1.5 и далее, Go пытается автоматически определять ограничения cgroups и устанавливать GOMAXPROCS согласно реальному количеству доступных CPU. Но в некоторых случаях (старые версии Go, специфичные настройки cgroups) этого не происходит.

Рекомендуется явно задавать GOMAXPROCS в контейнерах или использовать библиотеку golang.org/x/sys/unix для чтения ограничений cgroups и динамически устанавливать runtime.GOMAXPROCS.

Пример установки GOMAXPROCS вручную:

import (
    "runtime"
    "os"
    "strconv"
)

func main() {
    if val, ok := os.LookupEnv("GOMAXPROCS"); ok {
        if n, err := strconv.Atoi(val); err == nil {
            runtime.GOMAXPROCS(n)
        }
    }
    // ... остальной код
}

Или использовать пакет automaxprocs от Uber, который автоматически подстраивается под cgroups:

import "go.uber.org/automaxprocs"

func main() {
    _, _ = automaxprocs.Set()
    // ...
}