윈도우 서비스를 자체적으로 주기적으로 재시작하는 방법이 있을까요?

안녕하세요.
주기적으로 시스템 감시나 제어 등을 하는 윈도우 서비스 프로그램이 있습니다.
감시해야 할 대상이 계속적으로 늘어나는 상황인데 메모리가 실행시간과 감시 및 제어 대상이 늘어남에 따라 지속적으로 늘어나는 문제가 있습니다.
원론적으로는 메모리를 사용하고 제대로 Dispose 시키고 누수되는 부분도 확인하고 하는게 맞을듯 합니다만 이 부분은 시간을 좀 오래 두고 확인해야 할것 같아 임시 방편으로 주기적으로 재실행 시켜주면 될듯 한데요. 그러다 보니 이걸 매번 사용자가 수동으로 재실행 시켜시 신경써야하는 부분도 자동화가 됐으면 합니다.

그래서 일정 시간이 지나면 자체적으로 주기적으로 스스로 재시작이 가능한지가 궁금해 졌습니다.
혹시 가능여부를 아시는 분이나 같은 경험을 해보신 분의 조언 부탁드립니다.

–추가내용
서비스 2개를 이용하여 구현하는 방식에 대한 답글을 주신분들 우선 감사합니다.
해당 방식으로 구현하는 방법이 일반적인듯 합니다. 여기서 좀더 궁금한 부분은 2개가 아닌 1개의 서비스가 자체적으로 초기화 또는 재시작하는 방법에 대한 부분입니다.

감사합니다.

2개의 좋아요

윈도우 서비스 같은 경우
Controller 와 Agent 개념을 갖고 설계를 했던 경험이 있습니다.

@ aceCarrot 님이 만드신걸 Agent 라고 보면
Agent 는 스스로 메모리 체크를 해서 일정량 커지면 모든 쓰래드를 종료 후 GC 로 수집을 하고
다시 쓰래드를 시작 하는 로직으로 설계 되었고
그래도 메모리가 회수가 안되고 내부 한계치 까지 메모리가 커졌다면
모든 쓰래드 종료 후 본인 Agent도 종료 합니다.

허면 Controller 는 30초 ~1분 간격 으로 Agent 로 IPC 또는 SendMessage 등 여러 가지 방법으로
살아 있는지 체크 후 죽었다면 Controller가 Agent를 다시 시작 시켜 주는 형식으로 설계 했었는데
이 방법이 님에게도 적용 될런지 모르겠네요…

참고로 Controller , Agent 들은 다 윈도우 서비스 형태 입니다.

물론 다른 좋은 방법이 있다면 다른 분이 답을 해주실지도…

2개의 좋아요

님이 만든 서비스(A)와 별개로 또다른 서비스(B)를 만들고, 원래 서비스(A)의 메모리 사용량이 일정량 이상일 경우 재시작하라는 메세지를 전달하는 방법이 있습니다.
이 방식은 일부 백신과 악성코드가 자사 서비스를 종료하지 못하게 막는 방식입니다.

2개의 좋아요

네. 우선 관심 및 답변 감사합니다.
알려주신 해당 방식은 이미 알고 있는 방식이긴 합니다.
궁금한건 자체적으로 가능한 방법이 있는가 입니다.
왜 자체적인것에 집착하는가는 다른서비스를 관리해야 하는 추가 업무가 발생할 가능성 때문입니다.

2개의 좋아요

네. 상세한 답변 감사드립니다.
아직 시간적인 여유가 있어 서비스 1개로 자체적으로
재시작할수 있는 방법이 있는지 좀더 확인해 보겠습니다.

감사합니다.

2개의 좋아요

안녕하세요. 서비스를 두 개로 만든다던가 별도의 Agent가 아니라면 스크립트 방식은 어떨까요?
윈도우 서비스가 동작되는 폴더에 배치파일을 만든다던가 시간차를 두고 서비스를 껐다가 다시 실행시키도록 하면 어떨까 싶은데요.

아래는 10초 정도 텀을 뒀다가 현재 서비스를 종료하고 다시 서비스를 실행하도록 하는 방식입니다. 선결 조건은 동작하는 서비스가 관리자 권한이어야 된다는 것입니다.

추가적으로 만약 메모리나 별도의 상황을 자기자신이 체크하고 있다가 특정 동작을 실행하도록 뺄 수도 있을 것 같긴한데 텀이라던가 수동으로 명령을 때린다라고하면 현재 시스템의 사용률을 서버로 주기적으로 보내고 Kafka나 RabbitMQ로 서버에서 이벤트성으로 보내주는 것도 어떨까 싶습니다. 다시 동작을 하게 되면 서버로 또 정보가 날아올테니… 중단되었는지도 알 수 있을것 같기도하고…

    string command = "cmd.exe";
    string arguments = "/C timeout /t 10 && net stop 서비스명 && net start 서비스명";
    
    ProcessStartInfo processStartInfo = new ProcessStartInfo(command, arguments)
    {
        CreateNoWindow = true,
        UseShellExecute = false
    };

    Process process = Process.Start(processStartInfo);
    this.Stop();

원하시는 답변이 아니실 수 있지만 우선 야매 느낌으로 써봤습니다.

2개의 좋아요

윈도우 서비스 재시작 (서비스 명령어서비스 자동 재시작 스케줄 관리) (tistory.com)

7개의 좋아요

서비스 하시는 프로세스의 메모리 사용량이 늘어나는건가요?
아니면 프로세스의 메모리 사용량은 변함 없는데 윈도우의 메모리 사용량이 늘어나는건가요?

2개의 좋아요

주기적으로 프로그램을 자체적으로 종료하게 만드시죠.
내부적으로 타이머 하나 두고 한시간마다 라던지 그렇게 종료시키면 서비스라서 다시 돌아갈텐데요

2개의 좋아요

서비스에서,

원하는 기간으로 설정된 타이머를 넣고,
타이머 핸들러로 non-zero 종료를 하게 만들어서 서비스 복구 시스템이 가동되도록 만들고,
(종료 전에 필요한 작업 마무으리)

윈도우 서비스 관리자 (관리자 권한으로 실행)> 서비스 더블 클릭 > 복구 탭에서,

모든 실패의 응답을 [서비스 다시 시작] 로 만들면 될 것 같습니다.

2개의 좋아요

상세한 답변 감사드립니다.
위에 의견들과 종합적으로 고민해 봐야 겠네요.
제 상황에서 어떤 방식이 최선일지.

다시하번 감사드립니다.

3개의 좋아요

프로세스의 메모리가 늘어나요.
메모리가 어딘가에서 누수되고 있는거 같은데… ㅠ

1개의 좋아요

늦었지만 작업 스케쥴러에 서비스 재시작 동작을 걸어 놓는게 가장 간단할 것 같습니다.

1개의 좋아요

ServiceRestart.exe 를 만듭니다.
서비스는 재시작이 필요할 때 이 exe 를 호출합니다.
exe 가 시작되면서 재시작할 목록을 ini 를 통해 읽고 서비스를 중지 후 재시작 시킵니다.
모두 완료되면 스스로 종료합니다.

서비스 또 하나 만드는 것과 비슷하기도 하지만
별도 서비스 등록을 하지 않아도 되는 점이 다릅니다.

1개의 좋아요