유휴 시간 이후 systemd 서비스 비활성화

유휴 시간 이후 systemd 서비스 비활성화

부팅 시가 아닌 요청 시 서비스가 시작되기를 원합니다. 이를 위해 systemd 소켓 활성화(서비스 및 소켓 파일 사용)를 사용할 수 있습니다.

하지만 이 서버는 리소스가 제한되어 있으므로 일정 기간(예: 1시간) 활동이 없으면 서비스가 다시 트리거될 때까지 서비스를 중지하고 싶습니다. 어떻게 해야 하나요?

좀 찾아봤는데문서하지만 이것이 지원되는지는 모르겠습니다.


업데이트:
이것이 지원되지 않는다고 가정하면 사용 사례는 여전히 일반적일 수 있습니다. 이를 달성하는 좋은 방법/해결 방법은 무엇입니까?

답변1

systemd의 소켓 활성화는 두 가지 모드로 작동할 수 있습니다.

  • Accept=true:systemd는 청취 소켓을 보유하고 들어오는 각 연결을 수락하고 각 연결에 대해 새 프로세스를 생성하고 설정된 소켓을 전달합니다. 이 경우는 간단합니다(각 프로세스는 완료 후 종료됩니다).
  • Accept=false:systemd는 청취 소켓을 생성하고 들어오는 연결을 모니터링합니다. 누군가 들어오자마자 systemd는 서비스를 생성하고 청취 소켓을 전달합니다. 그런 다음 서비스는 들어오는 연결과 모든 후속 연결을 수락합니다. Systemd는 더 이상 소켓에서 일어나는 일을 추적하지 않으므로 비활성 상태를 감지할 수 없습니다.

후자의 경우 정말 깨끗한 유일한 해결책은 잠시 동안 유휴 상태가 된 후 종료되도록 애플리케이션을 수정하는 것입니다. 이 작업을 수행할 수 없는 경우 매시간 서비스를 종료하도록 cron 또는 systemd 타이머를 설정하는 것이 간단한 해결 방법일 수 있습니다. 서비스가 자주 생성되지 않는 경우 이는 합리적인 근사치일 수 있습니다.

이 사용 사례는 매우 드물다는 점에 유의하세요. poll()/select()에서 연결을 기다리는 프로세스는 CPU 시간을 소비하지 않으므로 이 경우 사용되는 유일한 리소스는 메모리입니다. 일부 스와핑을 설정하고 프로세스를 항상 RAM에 유지할 가치가 있는지 커널이 결정하도록 하는 것이 더 쉽고 효율적일 수 있습니다.

답변2

소켓 활동 없이 잠시 후에 종료되도록 프로그램의 메인 루프를 조정할 수 없는 경우 다음을 사용할 수 있습니다.systemd-socket-proxyd, 유휴 시간 초과 옵션이 있습니다.

thing.service귀하의 서비스 이름이 .그것이 듣고 있다고 가정 해 봅시다.청취 주소. 와 사이에 서비스를 추가 thing.socket하고 thing.service다음에서 전달합니다.청취 주소도착하다PRIVATE_LISTEN_ADDR.

  1. thing청취 구성 조정PRIVATE_LISTEN_ADDR바꾸다청취 주소. 이 작업은 에서 수행될 수도 thing.service있고, 수행될 수도 있습니다. thing.conf이는 애플리케이션에 따라 다릅니다.

  2. 다른 장치가 의존하지 않을 때 서비스가 중지되도록 구성하십시오. 이는 설정을 통해 수행할 수 있습니다.StopWhenUnneeded=true[Unit]섹션을 참조 하세요 thing.service.

  3. 에 추가하세요 thing-proxy.service. 이렇게 하면 다음을 thing.service통해 연결됩니다 .PRIVATE_LISTEN_ADDR. 여기서는 유휴 시간 제한을 10분으로 구성합니다.

    [Unit]
    Requires=thing.service
    After=thing.service
    Requires=thing.socket
    After=thing.socket
    
    [Service]
    ExecStart=/usr/lib/systemd/systemd-socket-proxyd --exit-idle-time=10min PRIVATE_LISTEN_ADDR
    PrivateTmp=yes
    PrivateNetwork=yes
    
  4. 다음 대신 thing.socket시작하도록 조정하십시오 .thing-proxy.servicething.service

    [Socket]
    Accept=false
    ListenStream=LISTEN_ADDR
    Service=thing-proxy.service
    
    [Install]
    WantedBy=sockets.target
    

가치청취 주소그리고PRIVATE_LISTEN_ADDRhostname:port원하는 것과 응용 프로그램이 수행할 수 있는 작업에 따라 TCP 서비스나 UNIX 도메인 소켓 경로 또는 둘 다에 사용할 수 있습니다 . 이제 연결을 수신하는 두 개의 프로세스가 있으므로 주소가 다르기만 하면 됩니다.

답변3

소켓으로 서비스를 활성화할 수 있는 경우 Accept=yes소켓 단위로 사용할 수 있습니다. 그런 다음 각 연결에 대해 새 서비스 인스턴스가 실행되고 소켓이 닫히면 중지됩니다.

관련 정보