Eu quero que um serviço seja iniciado sob demanda e não na inicialização. Para fazer isso, eu poderia usar a ativação do soquete do systemd (com os arquivos de serviço e soquete).
Mas este é um servidor com recursos limitados, portanto, após algum tempo (por exemplo, 1 hora) de inatividade, quero interromper o serviço (até que seja acionado novamente). Como eu posso fazer isso?
Eu olhei através de alguma documentação, mas não consigo descobrir se isso é suportado.
Atualização:
Supondo que isso não seja suportado, o caso de uso provavelmente ainda é bastante comum. Qual seria uma boa maneira / solução alternativa para conseguir isso?
A ativação do soquete no systemd pode funcionar em dois modos:
Accept=true
: systemd mantém o socket de escuta, aceita todas as conexões de entrada, gera um novo processo para cada conexão e passa o socket estabelecido para ele. Este caso é trivial (cada processo sai quando é feito).Accept=false
: systemd cria o soquete de escuta e o observa para conexão de entrada. Assim que um entra, o systemd gera o serviço e passa o soquete de escuta para ele. O serviço então aceita a conexão de entrada e quaisquer conexões subsequentes. O Systemd não rastreia mais o que está acontecendo no soquete, portanto, não pode detectar inatividade.No último caso, acho que a única solução realmente limpa é modificar o aplicativo para que ele saia quando estiver ocioso por algum tempo. Se você não puder fazer isso, uma solução grosseira poderia ser configurar o cron ou um timer systemd para matar o serviço uma vez por hora. Isso pode ser uma aproximação razoável se o serviço for gerado com pouca frequência.
Observe que o caso de uso é provavelmente muito raro. Um processo sentado em poll()/select() esperando por uma conexão não consome tempo de CPU, então o único recurso usado nessa situação é a memória. Provavelmente é mais fácil e eficiente apenas configurar alguma troca e deixar o kernel decidir se vale a pena manter o processo na RAM o tempo todo ou não.
Se você não pode ajustar o loop principal do seu programa para que ele saia após um certo período sem atividade de soquete, então você pode usar
systemd-socket-proxyd
, que tem uma opção de tempo limite ocioso.Suponha que seu serviço seja chamado
thing.service
. Ele está escutando em LITEN_ADDR . Você adicionará um serviço que fica entrething.socket
ething.service
encaminha conexões de LISTEN_ADDR para PRIVATE_LISTEN_ADDR .Ajuste a configuração para
thing
escutar em PRIVATE_LISTEN_ADDR em vez de LISTEN_ADDR . Isso pode ser feito emthing.service
, ou talvez emthing.conf
- depende do aplicativo.Configure seu serviço para ser interrompido se nenhuma outra unidade depender dele. Isso pode ser feito definindo
StopWhenUnneeded=true
na[Unit]
seção do seuthing.service
arquivo.Adicionar
thing-proxy.service
. Isso faz conexõesthing.service
via PRIVATE_LISTEN_ADDR . Configuramos o tempo limite ocioso aqui para ser de 10 minutos.Ajuste
thing.socket
para que iniciething-proxy.service
em vez dething.service
:Os valores de LISTEN_ADDR e PRIVATE_LISTEN_ADDR podem ser
hostname:port
para serviços TCP ou caminhos de soquete de domínio UNIX, ou talvez ambos, dependendo do que você deseja e do que o aplicativo pode fazer. Eles só precisam ser endereços diferentes porque agora você tem dois processos ouvindo conexões.Se o seu serviço for capaz de ser ativado por soquete, você poderá usá-lo
Accept=yes
na unidade de soquete. Em seguida, uma nova instância do seu serviço seria executada para cada conexão e interrompida quando o soquete fosse fechado.