개발/Python

파이썬에서 데몬을 어떻게 생성합니까?

MinorMan 2021. 1. 7. 18:30
반응형

<질문>

Searching on Googlex2 코드 스 니펫을 보여줍니다. 첫 번째 결과는this code recipe많은 문서와 설명과 함께 유용한 토론이 있습니다.

하나,another code sample에는 많은 문서가 포함되어 있지 않지만 시작, 중지 및 다시 시작과 같은 명령을 전달하기위한 샘플 코드가 포함되어 있습니다. 또한 데몬이 이미 실행 중인지 확인하는 데 편리한 PID 파일을 생성합니다.

이 샘플은 모두 데몬을 만드는 방법을 설명합니다. 고려해야 할 추가 사항이 있습니까? 한 샘플이 다른 샘플보다 낫고 그 이유는 무엇입니까?


<답변1>

현재 솔루션

참조 구현PEP 3143 (Standard daemon process library)이제 다음과 같이 사용할 수 있습니다.python-daemon.

역사적 답변

샌더 원수code sample원래 2004 년에 게시 된 원본보다 우월합니다. 저는 한때 Pyro의 데몬 나이저를 제공했지만 다시해야한다면 Sander의 코드를 사용할 것입니다.


<답변2>

있습니다많은 이상한 것들될 때 돌봐well-behaved daemon process:

  • 코어 덤프 방지 (많은 데몬이 루트로 실행되고 코어 덤프에 민감한 정보가 포함될 수 있음)

  • chroot gaol 내에서 올바르게 작동

  • 사용 사례에 맞게 UID, GID, 작업 디렉토리, umask 및 기타 프로세스 매개 변수를 설정합니다.

  • 상승 된 suid , sgid 권한 포기

  • 사용 사례에 따라 제외를 사용하여 열려있는 모든 파일 설명자를 닫습니다.

  • init , inetd 등과 같이 이미 분리 된 컨텍스트 내에서 시작되면 올바르게 작동합니다.

  • 현명한 데몬 동작을위한 신호 처리기를 설정하지만 사용 사례에 따라 결정되는 특정 처리기를 사용합니다.

  • 데몬 프로세스에 더 이상 제어 터미널이 없으므로 표준 스트림 stdin , stdout , stderr 리디렉션

  • PID 파일을 협조적인 자문 잠금으로 처리합니다. 이는 여러 모순되지만 유효한 동작 방식을 가진 웜 자체전체 캔입니다.

  • 프로세스가 종료 될 때 적절한 정리 허용

  • 좀비이어지지 않고 실제로 데몬 프로세스가됩니다.

이들 중 일부는표준, 표준 Unix 문헌 (UNIX 환경의 고급 프로그래밍, 후기 W. Richard Stevens, Addison-Wesley, 1992). 스트림 리디렉션 및PID file handling, 아르전통적인 행동대부분의 데몬 사용자는 기대하지만 덜 표준화되어 있습니다.

이들 모두는PEP 3143 “표준 데몬 프로세스 라이브러리”사양. 그만큼python-daemon참조 구현은 Python 2.7 이상 및 Python 3.2 이상에서 작동합니다.


<답변3>

다음은 새로운 데몬 애플리케이션을 개발할 때 시작하는 기본적인 'Howdy World'Python 데몬입니다.

#!/usr/bin/python
import time
from daemon import runner

class App():
    def __init__(self):
        self.stdin_path = '/dev/null'
        self.stdout_path = '/dev/tty'
        self.stderr_path = '/dev/tty'
        self.pidfile_path =  '/tmp/foo.pid'
        self.pidfile_timeout = 5
    def run(self):
        while True:
            print("Howdy!  Gig'em!  Whoop!")
            time.sleep(10)

app = App()
daemon_runner = runner.DaemonRunner(app)
daemon_runner.do_action()

당신이 필요합니다python-daemon도서관. 다음과 같이 설치할 수 있습니다.

pip install python-daemon

그런 다음 시작하십시오../howdy.py start, 중지./howdy.py stop.


<답변4>

참고python-daemon데몬 뒤의 많은 문제를 즉시 해결하는 패키지입니다.

(데비안 패키지 설명에서) 다음과 같은 기능을 활성화합니다.

  • 프로세스를 자체 프로세스 그룹으로 분리하십시오.
  • chroot 내부에서 실행하기에 적합한 프로세스 환경을 설정하십시오.
  • suid 및 sgid 권한을 포기하십시오.
  • 열려있는 모든 파일 설명자를 닫습니다.
  • 작업 디렉토리, uid, gid 및 umask를 변경하십시오.
  • 적절한 신호 처리기를 설정합니다.
  • stdin, stdout 및 stderr에 대한 새 파일 설명자를 엽니 다.
  • 지정된 PID 잠금 파일을 관리합니다.
  • 종료시 처리를위한 정리 기능을 등록합니다.

<답변5>

대안-데몬 화되지 않은 정상적인 Python 프로그램을 만든 다음 다음을 사용하여 외부 적으로 데몬 화합니다.supervisord. 이것은 많은 골칫거리를 줄일 수 있으며 * nix 및 언어 이식이 가능합니다.


<답변6>

아마도 질문에 대한 직접적인 대답은 아니지만 systemd를 사용하여 애플리케이션을 데몬으로 실행할 수 있습니다. 다음은 그 예입니다.

[Unit]
Description=Python daemon
After=syslog.target
After=network.target

[Service]
Type=simple
User=
Group=
ExecStart=/usr/bin/python /script.py

# Give the script some time to startup
TimeoutSec=300

[Install]
WantedBy=multi-user.target

많은 작업이 수행되고 데몬 스크립트가 나머지 시스템과 유사하게 작동하기 때문에이 방법을 선호합니다.

-Orby


<답변7>

YapDiHacker News에 등장한 비교적 새로운 파이썬 모듈입니다. 매우 유용 해 보이며 스크립트 내부에서 파이썬 스크립트를 데몬 모드로 변환하는 데 사용할 수 있습니다.


<답변8>

python-daemon은 아직 python 3.x를 지원하지 않았기 때문에 메일 링리스트에서 읽을 수있는 내용에서 읽지 못할 수도 있습니다. 저는 PEP 3143의 새로운 구현을 작성했습니다.pep3143daemon

pep3143daemon은 최소한 python 2.6, 2.7 및 3.x를 지원해야합니다.

또한 PidFile 클래스도 포함합니다.

라이브러리는 표준 라이브러리와 6 개 모듈에만 의존합니다.

python-daemon 대신 드롭 인으로 사용할 수 있습니다.

여기 있습니다documentation.


<답변9>

이 함수는 애플리케이션을 데몬으로 변환합니다.

import sys
import os

def daemonize():
    try:
        pid = os.fork()
        if pid > 0:
            # exit first parent
            sys.exit(0)
    except OSError as err:
        sys.stderr.write('_Fork #1 failed: {0}\n'.format(err))
        sys.exit(1)
    # decouple from parent environment
    os.chdir('/')
    os.setsid()
    os.umask(0)
    # do second fork
    try:
        pid = os.fork()
        if pid > 0:
            # exit from second parent
            sys.exit(0)
    except OSError as err:
        sys.stderr.write('_Fork #2 failed: {0}\n'.format(err))
        sys.exit(1)
    # redirect standard file descriptors
    sys.stdout.flush()
    sys.stderr.flush()
    si = open(os.devnull, 'r')
    so = open(os.devnull, 'w')
    se = open(os.devnull, 'w')
    os.dup2(si.fileno(), sys.stdin.fileno())
    os.dup2(so.fileno(), sys.stdout.fileno())
    os.dup2(se.fileno(), sys.stderr.fileno())

<답변10>

@Dustin이 언급 한 데몬 모듈이 저에게 적합하지 않은 것 같습니다. 대신 나는 설치했다python-daemon다음 코드를 사용했습니다.

# filename myDaemon.py
import sys
import daemon
sys.path.append('/home/ubuntu/samplemodule') # till __init__.py
from samplemodule import moduleclass 

with daemon.DaemonContext():
    moduleclass.do_running() # I have do_running() function and whatever I was doing in __main__() in module.py I copied in it.

달리기는 쉽습니다

> python myDaemon.py

여기 완전성을 위해 samplemodule 디렉토리 내용이 있습니다.

>ls samplemodule
__init__.py __init__.pyc moduleclass.py

moduleclass.py의 내용은 다음과 같습니다.

class moduleclass():
    ...

def do_running():
    m = moduleclass()
    # do whatever daemon is required to do.

<답변11>

파이썬에서 데몬화할 때 고려해야 할 사항이 하나 더 있습니다.

파이썬을 사용하는 경우벌채 반출데몬 화 후 계속 사용하려면 다음을 호출하십시오.close()핸들러 (특히 파일 핸들러)에서.

이렇게하지 않으면 핸들러는 여전히 파일이 열려 있다고 생각할 수 있으며 메시지는 단순히 사라집니다. 즉, 로거가 파일이 닫 혔음을 알고 있는지 확인하십시오!

이것은 데몬화할 때 열려있는 모든 파일 설명자를 무차별 적으로 닫는다 고 가정합니다. 대신 로그 파일을 제외한 모든 파일을 닫을 수 있습니다 (하지만 일반적으로 모두 닫은 다음 원하는 파일을 다시 여는 것이 더 간단합니다).


<답변12>

python-daemon 모듈에서 제공하는 순수한 Python 솔루션을 선호 할 수 있지만daemon(3)기능libc-적어도BSDLinux-올바른 일을 할 것입니다.

파이썬에서 호출하는 것은 쉽습니다.

import ctypes

ctypes.CDLL(None).daemon(0, 0) # Read the man-page for the arguments' meanings

남은 작업은 PID 파일의 생성 (및 잠금)입니다. 하지만 너 자신을 다룰 수 있다는 ...


<답변13>

Sander Marechal의 코드 샘플에서 몇 줄을 수정했습니다 (@JeffBauer가the accepted answer)를 추가하려면quit()데몬이 중지되기 전에 실행되는 메서드입니다. 이것은 때때로 매우 유용합니다.

Here it is.

참고 : 문서가 아직 누락되어 있고 (다른 SO 질문도 참조) 다소 모호하기 때문에 "python-daemon"모듈을 사용하지 않습니다 (이 모듈을 사용하여 명령 줄에서 데몬을 올바르게 시작 / 중지하는 방법?).


<답변14>

몇 년 동안 여러 번 시도한 후 (여기에 제공된 모든 답변을 시도했지만 결국에는 모두 사소한 단점이있었습니다) 이제 Python에서 직접 데몬을 시작, 중지, 다시 시작하는 것보다 더 좋은 방법이 있음을 알게되었습니다. : 대신 OS 도구를 사용합니다.

예를 들어 Linux의 경우python myapp startpython myapp stop, 앱을 시작하려면 다음을 수행합니다.

screen -S myapp python myapp.py    
CTRL+A, D to detach

또는screen -dmS myapp python myapp.py...에start and detach it in one command.

그때:

screen -r myapp

이 터미널에 다시 연결합니다. 터미널에서 CTRL + C를 사용하여 중지 할 수 있습니다.


<답변15>

Python으로 데몬을 만드는 가장 쉬운 방법은Twisted이벤트 중심 프레임 워크. 데몬 화에 필요한 모든 것을 처리합니다. 그것은Reactor Pattern동시 요청을 처리합니다.


<답변16>

사람들이 "데몬"이라고 말하는 경우의 80 %는 서버 만 원합니다. 이 시점에서 질문이 완전히 불분명하기 때문에 가능한 답변 영역이 무엇인지 말하기가 어렵습니다. 서버가 충분하므로 거기서 시작하십시오. 실제 "데몬"이 실제로 필요한 경우 (드문 경우 임) 계속 읽어보십시오.nohup서버를 데몬 화하는 방법으로.

실제 데몬이 실제로 필요할 때까지 간단한 서버를 작성하십시오.

또한보세요WSGI reference이행.

또한보세요Simple HTTP Server.

"추가로 고려해야 할 사항이 있습니까?"예. 약 백만 가지. 무슨 프로토콜? 얼마나 많은 요청이 있습니까? 각 요청을 처리하는 데 얼마나 걸립니까? 얼마나 자주 도착합니까? 전용 프로세스를 사용 하시겠습니까? 스레드? 하위 프로세스? 데몬을 작성하는 것은 큰 일입니다.

반응형