

As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.

# Limitar o uso de recursos do processo no AL2023 usando systemd
<a name="resource-limiting-systemd"></a>

 No Amazon Linux 2023 (AL2023), recomendamos o uso de `systemd` para controlar quais recursos podem ser usados por processos ou grupos de processos. O uso de `systemd` é um substituto poderoso e fácil de usar para manipular `cgroups` manualmente ou usar utilitários como [`cpulimit`](epel.md#cpulimit), que antes só estavam disponíveis para o Amazon Linux no repositório [EPEL](epel.md) de terceiros. 

 Para obter informações abrangentes, consulte a documentação do `systemd` upstream para [systemd.resource-control](https://www.freedesktop.org/software/systemd/man/latest/systemd.resource-control.html) ou a página man para `systemd.resource-control` em uma instância do AL2023. 

 Os exemplos abaixo usarão o teste de estresse da CPU `stress-ng` (do pacote `stress-ng`) para simular uma aplicação com uso intenso da CPU e `memcached` para simular uma aplicação com uso intenso da memória. 

 Os exemplos abaixo abrangem a aplicação de um limite de CPU em um comando único e um limite de memória em um serviço. A maioria das restrições de recursos que `systemd` oferece podem ser usadas em qualquer lugar que `systemd` execute um processo, e é possível usar várias ao mesmo tempo. Os exemplos abaixo são limitados a uma única restrição para fins ilustrativos. 

## Controle de recursos com `systemd-run` para execução de comandos únicos
<a name="resource-limiting-systemd-interactive"></a>

 Embora comumente associado aos serviços do sistema, `systemd` também pode ser usado por usuários que não são raiz para executar serviços, agendar temporizadores ou executar processos pontuais. No exemplo a seguir, vamos usar `stress-ng` como a aplicação. No primeiro exemplo, vamos executá-la usando `systemd-run` na conta padrão `ec2-user` e, no segundo exemplo, vamos aplicar limites quanto ao uso da CPU. 

**Example : usar `systemd-run` na linha de comandos para executar um processo, sem limitar o uso de recursos**  

1.  Garanta que o pacote `stress-ng` esteja instalado, pois vamos usá-lo no exemplo. 

   ```
   [ec2-user ~]$ sudo dnf install -y {{stress-ng}}
   ```

1.  Use `systemd-run` para executar um teste de estresse da CPU de 10 segundos sem limitar a quantidade de CPU que ele pode usar. 

   ```
   [ec2-user ~]$ systemd-run --user --tty --wait --property=CPUAccounting=1 {{stress-ng --cpu 1 --timeout 10}}
   Running as unit: run-u6.service
   Press ^] three times within 1s to disconnect TTY.
   stress-ng: info:  [339368] setting to a 10 second run per stressor
   stress-ng: info:  [339368] dispatching hogs: 1 cpu
   stress-ng: info:  [339368] successful run completed in 10.00s
   Finished with result: success
   Main processes terminated with: code=exited/status=0
   Service runtime: 10.068s
   CPU time consumed: 9.060s
   ```

    A opção `--user` instrui `systemd-run` a executar o comando como o usuário conectado, a opção `--tty` significa que há um TTY anexado, `--wait` indica para esperar até que o serviço seja concluído e a opção `--property=CPUAccounting=1` instrui `systemd-run` a registrar quanto tempo de CPU é usado na execução do processo. A opção da linha de comandos `--property` pode ser usada para enviar as configurações de `systemd-run` que podem estar definidas em um arquivo de configuração `systemd.unit`. 

 Quando instruído a colocar carga na CPU, o programa `stress-ng` usará todo o tempo de CPU disponível para realizar o teste durante o período solicitado. Para uma aplicação do mundo real, pode ser desejável limitar o tempo total de execução de um processo. No exemplo abaixo, solicitaremos que `stress-ng` seja executado por um tempo maior do que a restrição de duração máxima que foi imposta usando `systemd-run`. 

**Example : usar `systemd-run` na linha de comandos para executar um processo, limitando o uso da CPU a 1 segundo**  

1. Verifique se `stress-ng` está instalado para executar este exemplo.

1.  A propriedade `LimitCPU` é equivalente a `ulimit -t`, que limitará o tempo máximo que esse processo poderá usar a CPU. Nesse caso, como estamos solicitando uma execução de estresse de 10 segundos e limitando o uso da CPU a 1 segundo, o comando receberá um sinal `SIGXCPU` e falhará. 

   ```
   [ec2-user ~]$ systemd-run --user --tty --wait --property=CPUAccounting=1 --property=LimitCPU=1 {{stress-ng --cpu 1 --timeout 10}}
   Running as unit: run-u12.service
   Press ^] three times within 1s to disconnect TTY.
   stress-ng: info:  [340349] setting to a 10 second run per stressor
   stress-ng: info:  [340349] dispatching hogs: 1 cpu
   stress-ng: fail:  [340349] cpu instance 0 corrupted bogo-ops counter, 1370 vs 0
   stress-ng: fail:  [340349] cpu instance 0 hash error in bogo-ops counter and run flag, 3250129726 vs 0
   stress-ng: fail:  [340349] metrics-check: stressor metrics corrupted, data is compromised
   stress-ng: info:  [340349] unsuccessful run completed in 1.14s
   Finished with result: exit-code
   Main processes terminated with: code=exited/status=2
   Service runtime: 1.201s
   CPU time consumed: 1.008s
   ```

 Mais comumente, talvez você queira restringir a porcentagem do tempo da CPU que pode ser consumido por um processo específico. No exemplo abaixo, restringiremos a porcentagem do tempo da CPU que pode ser consumido por `stress-ng`. Para um serviço do mundo real, pode ser desejável limitar a porcentagem máxima do tempo da CPU que um processo em segundo plano pode consumir para deixar os recursos livres para o processo que atende às solicitações do usuário. 

**Example : usar `systemd-run` para limitar um processo a 10% do tempo de uma CPU**  

1. Verifique se `stress-ng` está instalado para executar este exemplo.

1.  Vamos usar a propriedade `CPUQuota` para instruir `systemd-run` a restringir o uso da CPU pelo comando que vamos executar. Não vamos limitar a quantidade de tempo que o processo pode permanecer em execução, apenas a quantidade de CPU que ele pode usar. 

   ```
   [ec2-user ~]$ systemd-run --user --tty --wait --property=CPUAccounting=1 --property=CPUQuota=10% {{stress-ng --cpu 1 --timeout 10}}
   Running as unit: run-u13.service
   Press ^] three times within 1s to disconnect TTY.
   stress-ng: info:  [340664] setting to a 10 second run per stressor
   stress-ng: info:  [340664] dispatching hogs: 1 cpu
   stress-ng: info:  [340664] successful run completed in 10.08s
   Finished with result: success
   Main processes terminated with: code=exited/status=0
   Service runtime: 10.140s
   CPU time consumed: 1.014s
   ```

    Observe como a contabilidade da CPU nos informa que, embora o serviço tenha sido executado por 10 segundos, ele consumiu apenas 1 segundo de tempo real da CPU. 

 Há várias maneiras de configurar `systemd` para limitar o uso de recursos de CPU, memória, rede e E/S. Consulte a documentação do `systemd` upstream para [systemd.resource-control](https://www.freedesktop.org/software/systemd/man/latest/systemd.resource-control.html) ou a página man para `systemd.resource-control` em uma instância do AL2023 para obter informações abrangentes. 

 Nos bastidores, `systemd` usa recursos de kernel do Linux, como `cgroups`, para implementar esses limites, evitando a necessidade de configurá-los manualmente. A [documentação de kernel do Linux para `cgroup-v2`](https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v2.html) contém muitos detalhes sobre como `cgroups` funcionam. 

## Controle de recursos em um serviço de `systemd`
<a name="resource-limiting-systemd-service"></a>

 Há vários parâmetros que podem ser adicionados à seção `[Service]` dos serviços de `systemd` para controlar o uso dos recursos do sistema. Isso inclui limites rígidos e flexíveis. Para conhecer o comportamento exato de cada opção, consulte a documentação de `systemd` upstream para [systemd.resource-control](https://www.freedesktop.org/software/systemd/man/latest/systemd.resource-control.html) ou a página man para `systemd.resource-control` em uma instância do AL2023. 

 Os limites comumente usados são `MemoryHigh` para especificar um limite de controle de utilização para o uso de memória, `MemoryMax` para definir um limite superior rígido (uma vez atingido, o OOM Killer é invocado) e `CPUQuota` (conforme ilustrado na seção anterior). Também é possível configurar pesos e prioridades em vez de números fixos. 

**Example : usar `systemd` para definir limites de uso de memória para os serviços**  
 Neste exemplo, definiremos um limite rígido de uso de memória para `memcached`, um cache simples de valores-chave, e mostraremos como o OOM Killer é invocado para esse serviço e não para todo o sistema.   

1.  Primeiro, precisamos instalar os pacotes necessários para este exemplo. 

   ```
   [ec2-user ~]$ sudo dnf install -y {{memcached libmemcached-awesome-tools}}
   ```

1.  Habilite `memcached.service`, depois inicie o serviço para que `memcached` esteja em execução. 

   ```
   [ec2-user ~]$ sudo systemctl enable {{memcached.service}}
   Created symlink /etc/systemd/system/multi-user.target.wants/memcached.service → /usr/lib/systemd/system/memcached.service.
   [ec2-user ~]$ sudo systemctl start {{memcached.service}}
   ```

1.  Verifique se `memcached.service` está em execução. 

   ```
   [ec2-user ~]$ sudo systemctl status {{memcached.service}}
   ● memcached.service - memcached daemon
        Loaded: loaded (/usr/lib/systemd/system/memcached.service; enabled; preset: disabled)
        Active: active (running) since Fri 2025-01-31 22:36:42 UTC; 1s ago
      Main PID: 356294 (memcached)
         Tasks: 10 (limit: 18907)
        Memory: 1.8M
           CPU: 20ms
        CGroup: /system.slice/memcached.service
        └─356294 /usr/bin/memcached -p 11211 -u memcached -m 64 -c 1024 -l 127.0.0.1,::1
   
   Jan 31 22:35:36 ip-1-2-3-4.us-west-2.compute.internal systemd[1]: Started memcached.service - memcached daemon.
   ```

1.  Agora que `memcached` está instalado e em execução, podemos observar que ele funciona inserindo alguns dados aleatórios no cache. 

    Em `/etc/sysconfig/memcached`, a variável `CACHESIZE` é definida como 64 por padrão, o que significa 64 megabytes. Ao inserir mais dados do que o tamanho máximo do cache, podemos ver que preenchemos o cache e alguns itens são removidos usando `memcached-tool`, e que `memcached.service` está usando cerca de 64 MB de memória. 

   ```
   [ec2-user ~]$ for i in $(seq 1 150); do dd if=/dev/random of=$i bs=512k count=1; memcp -s localhost $i; done
   [ec2-user ~]$ memcached-tool localhost display
     #  Item_Size  Max_age   Pages   Count   Full?  Evicted Evict_Time OOM
     2     120B         0s       1       0      no        0        0    0
    39   512.0K         4s      63     126     yes       24        2    0
   [ec2-user ~]$ sudo systemctl status {{memcached.service}}
   ● memcached.service - memcached daemon
        Loaded: loaded (/usr/lib/systemd/system/memcached.service; enabled; preset: disabled)
        Active: active (running) since Fri 2025-01-31 22:36:42 UTC; 7min ago
      Main PID: 356294 (memcached)
         Tasks: 10 (limit: 18907)
        Memory: 66.7M
           CPU: 203ms
        CGroup: /system.slice/memcached.service
                └─356294 /usr/bin/memcached -p 11211 -u memcached -m 64 -c 1024 -l 127.0.0.1,::1
   
   Jan 31 22:36:42 ip-1-2-3-4.us-west-2.compute.internal systemd[1]: Started memcached.service - memcached daemon.
   ```

1.  Use a propriedade `MemoryMax` para definir um limite rígido para `memcached.service`. Se esse limite atingido, o OOM Killer será invocado. Opções adicionais podem ser definidas para o serviço adicionando-as a um arquivo de substituição. Isso pode ser feito editando diretamente o arquivo `/etc/systemd/system/memcached.service.d/override.conf` ou de forma interativa, usando o comando `edit` de `systemctl`. 

   ```
   [ec2-user ~]$ sudo systemctl edit {{memcached.service}}
   ```

   Adicione o seguinte à substituição para definir um limite rígido de 32 MB de memória para o serviço.

   ```
   [Service]
   MemoryMax=32M
   ```

1. Instrua `systemd` a recarregar sua configuração.

   ```
   [ec2-user ~]$ sudo systemctl daemon-reload
   ```

1. Observe que `memcached.service` agora está sendo executado com um limite de memória de 32 MB.

   ```
   [ec2-user ~]$ sudo systemctl status {{memcached.service}}
   ● memcached.service - memcached daemon
        Loaded: loaded (/usr/lib/systemd/system/memcached.service; enabled; preset: disabled)
       Drop-In: /etc/systemd/system/memcached.service.d
                └─override.conf
        Active: active (running) since Fri 2025-01-31 23:09:13 UTC; 49s ago
      Main PID: 358423 (memcached)
         Tasks: 10 (limit: 18907)
        Memory: 1.8M (max: 32.0M available: 30.1M)
           CPU: 25ms
        CGroup: /system.slice/memcached.service
                └─358423 /usr/bin/memcached -p 11211 -u memcached -m 64 -c 1024 -l 127.0.0.1,::1
   
   Jan 31 23:09:13 ip-1-2-3-4.us-west-2.compute.internal systemd[1]: Started memcached.service - memcached daemon.
   ```

1.  O serviço funcionará normalmente usando menos de 32 MB de memória, o que podemos confirmar ao carregar menos de 32 MB de dados aleatórios no cache e verificar o status do serviço. 

   ```
   [ec2-user ~]$ for i in $(seq 1 30); do dd if=/dev/random of=$i bs=512k count=1; memcp -s localhost $i; done
   ```

   ```
   [ec2-user ~]$ sudo systemctl status {{memcached.service}}
   ● memcached.service - memcached daemon
        Loaded: loaded (/usr/lib/systemd/system/memcached.service; enabled; preset: disabled)
       Drop-In: /etc/systemd/system/memcached.service.d
                └─override.conf
        Active: active (running) since Fri 2025-01-31 23:14:48 UTC; 3s ago
      Main PID: 359492 (memcached)
         Tasks: 10 (limit: 18907)
        Memory: 18.2M (max: 32.0M available: 13.7M)
           CPU: 42ms
        CGroup: /system.slice/memcached.service
                └─359492 /usr/bin/memcached -p 11211 -u memcached -m 64 -c 1024 -l 127.0.0.1,::1
   
   Jan 31 23:14:48 ip-1-2-3-4.us-west-2.compute.internal systemd[1]: Started memcached.service - memcached daemon.
   ```

1.  Agora podemos fazer com que `memcached` use mais de 32 MB de memória, tentando usar os 64 MB completos de cache que são a configuração padrão de `memcached`. 

   ```
   [ec2-user ~]$ for i in $(seq 1 150); do dd if=/dev/random of=$i bs=512k count=1; memcp -s localhost $i; done
   ```

    Você observará que em algum momento durante o comando acima, há erros de conexão com o servidor de `memcached`. Isso ocorre porque o OOM Killer encerrou o processo devido à restrição que impusemos a ele. O restante do sistema funcionará normalmente e nenhum outro processo será considerado pelo OOM Killer, já que restringimos apenas `memcached.service`. 

   ```
   [ec2-user ~]$ sudo systemctl status {{memcached.service}}
   ● memcached.service - memcached daemon
        Loaded: loaded (/usr/lib/systemd/system/memcached.service; enabled; preset: disabled)
       Drop-In: /etc/systemd/system/memcached.service.d
                └─override.conf
        Active: failed (Result: oom-kill) since Fri 2025-01-31 23:20:28 UTC; 2s ago
      Duration: 2.901s
       Process: 360130 ExecStart=/usr/bin/memcached -p ${PORT} -u ${USER} -m ${CACHESIZE} -c ${MAXCONN} $OPTIONS (code=killed, signal=KILL)
      Main PID: 360130 (code=killed, signal=KILL)
           CPU: 94ms
   
   Jan 31 23:20:25 ip-1-2-3-4.us-west-2.compute.internal systemd[1]: Started memcached.service - memcached daemon.
   Jan 31 23:20:28 ip-1-2-3-4.us-west-2.compute.internal systemd[1]: memcached.service: A process of this unit has been killed by the OOM killer.
   Jan 31 23:20:28 ip-1-2-3-4.us-west-2.compute.internal systemd[1]: memcached.service: Main process exited, code=killed, status=9/KILL
   Jan 31 23:20:28 ip-1-2-3-4.us-west-2.compute.internal systemd[1]: memcached.service: Failed with result 'oom-kill'.
   ```