Sobes.tech
Middle+

Pastāsti par pēdējo kļūdu — kas notika, kā to atradāt un kā risinājāt?

sobes.tech AI

Atbilde no AI

Vienā no mūsu pēdējiem projektiem Go valodā mēs saskārāmies ar atmiņas noplūdes problēmu pakalpojumā, kas apstrādāja lielu skaitu paralēlo pieprasījumu. Sistēma pakāpeniski palēninājās un beigās sabruka ar kļūdu par izsīkstošu atmiņu.

Iemesls bija nepareiza gorutīnu izmantošana: mēs katram pieprasījumam sākām gorutīnu, bet neuzraudzījām to pabeigšanu un nebrīvojām resursus, kas saistīti ar kontekstu.

Problēma tika atklāta ar pprof profiler, kas parādīja gorutīnu skaita un atmiņas patēriņa pieaugumu.

Risinājums:

  • Pievienojām kontekstu ar laika limitu un atcelšanu gorutīnām.
  • Pārrakstījām pieprasījumu apstrādi, lai nodrošinātu gorutīnu pabeigšanu.
  • Ieviesām gorutīnu baseinu, lai ierobežotu vienlaicīgi darbojošo gorutīnu skaitu.

Piemērs, kā izmantot kontekstu gorutīnas atcelšanai:

ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
defer cancel()
go func(ctx context.Context) {
    select {
    case <-ctx.Done():
        // tīrīšana un pabeigšana
        return
    // apstrāde
    }
}(ctx)