IT story

파이썬에서 데몬을 어떻게 만드나요?

hot-time 2020. 4. 12. 10:32
반응형

파이썬에서 데몬을 어떻게 만드나요?


Google에서 검색하면 x2 코드 스 니펫이 나타납니다. 첫 번째 결과는 이 코드 레시피에 관한 것인데, 이 코드 레시피 는 아래에 유용한 토론과 함께 많은 문서와 설명이 있습니다.

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

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


현재 솔루션

PEP 3143 (표준 데몬 프로세스 라이브러리) 의 참조 구현을 python-daemon으로 사용할 수 있습니다 .

역사적 답변

Sander Marechal의 코드 샘플 은 원래 2004 년에 게시 된 원본보다 우수합니다. Pyro의 데몬 타이 저에 기여한 적이 있지만, 그렇게해야한다면 Sander의 코드를 사용했을 것입니다.


잘 작동하는 데몬 프로세스 가 될 때주의 해야사항많이 있습니다 .

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

  • chrootgaol 안에서 올바르게 행동하다

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

  • 승계 suid, sgid특권 포기

  • 사용 사례에 따라 제외 된 모든 열린 파일 디스크립터를 닫습니다.

  • 이미 분리 된 컨텍스트 내에서 시작하는 경우, 제대로 동작 등 init, inetd

  • 현명한 데몬 동작에 대한 신호 처리기를 설정하고 사용 사례에 따라 결정된 특정 처리기를 사용합니다.

  • 표준 스트림을 리디렉션하는 것은 stdin, stdout, stderr데몬 프로세스는 더 이상 제어 단자가 없기 때문에

  • PID 파일을 협력 자문 잠금으로 처리합니다.이 잠금은 모순이 많지만 유효한 행동 방법을 가진 웜 자체 입니다.

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

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

표준 유닉스 문헌 ( UNIX 환경의 고급 프로그래밍 , W. Richard Stevens, Addison-Wesley, 1992)에 설명 된대로 이들 중 일부는 표준 입니다. 이러한 스트림 재와 같은 다른, PID 파일 처리는 ,있는 기존의 행동에 대부분의 데몬 사용자가 기대하는 것하지만 덜 표준화되어있다.

이 모든 것들은 PEP 3143 “표준 데몬 프로세스 라이브러리”사양에서 다룹니다 . 파이썬 데몬 참조 구현은 이상 파이썬 2.7에서 작동하고, 나중에 파이썬 3.2.


다음은 새로운 데몬 응용 프로그램을 개발할 때 시작하는 기본 '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.


노트 파이썬 데몬 상자에서 데몬 뒤에 많은 문제를 해결 패키지를.

다른 기능들 중에서도 데비안 패키지 설명에서 가능합니다 :

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

대안-일반적인 비 데몬 (non-demonized) 파이썬 프로그램을 만든 다음 supervisord를 사용하여 외부에서 데몬을 만듭니다. 이것은 많은 두통을 줄일 수 있으며 * nix 및 언어 이식이 가능합니다.


아마도 질문에 대한 직접적인 대답은 아니지만 systemd를 사용하여 응용 프로그램을 데몬으로 실행할 수 있습니다. 예를 들면 다음과 같습니다.

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

[Service]
Type=simple
User=<run as user>
Group=<run as group group>
ExecStart=/usr/bin/python <python script home>/script.py

# Give the script some time to startup
TimeoutSec=300

[Install]
WantedBy=multi-user.target

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

오비


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

pep3143 데몬은 적어도 파이썬 2.6, 2.7 및 3.x를 지원해야합니다.

PidFile 클래스도 포함합니다.

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

python-daemon의 대체품으로 사용할 수 있습니다.

여기 문서가 있습니다.


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


이 함수는 응용 프로그램을 데몬으로 변환합니다.

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())

@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

완성도를 위해 여기 샘플 모듈 디렉토리 내용이 있습니다.

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

moduleclass.py의 내용은

class moduleclass():
    ...

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

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

파이썬 로깅 을 사용하고 있으며 데몬 화 후 계속 사용 close()하려면 처리기 (특히 파일 처리기) 를 호출해야합니다 .

이 작업을 수행하지 않으면 처리기는 여전히 파일이 열려 있다고 생각할 수 있으며 메시지는 단순히 사라집니다. 즉, 로거가 파일이 닫 혔음을 알 수 있습니다.

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


데몬이 멈추기 전에 실행 되는 메소드 를 추가하기 위해 Sander Marechal의 코드 샘플에서 몇 줄을 수정했습니다 ( 허용 된 답변 에서 @JeffBauer에 의해 언급 됨 ) quit(). 이것은 때때로 매우 유용합니다.

여기있어.

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


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

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

import ctypes

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

남은 것은 PID 파일의 생성 및 잠금뿐입니다. 그러나 당신은 자신을 다룰 수 있습니다 ...


Python으로 데몬을 만드는 가장 쉬운 방법은 Twisted 이벤트 중심 프레임 워크 를 사용하는 것 입니다. 데몬 화에 필요한 모든 것을 처리합니다. 리액터 패턴사용하여 동시 요청을 처리합니다.


몇 년 동안 많은 시도 (여기에서 주어진 모든 답변을 시도했지만 결국에는 약간의 단점이 있음), 이제 파이썬에서 직접 데몬을 시작, 중지, 다시 시작하는 것보다 더 좋은 방법이 있음을 알았습니다. : 대신 OS 도구를 사용하십시오.

예를 들어, 리눅스, 대신 일을 python myapp start하고 python myapp stop, 나는 응용 프로그램을 시작하려면 다음을 수행하십시오

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

또는 하나의 명령screen -dmS myapp python myapp.py 으로 시작하고 분리합니다 .

그때:

screen -r myapp

이 터미널에 다시 연결하십시오. 터미널에 들어가면 Ctrl + C를 사용하여 터미널을 중지 할 수 있습니다.


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

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

또한 WSGI 참조 구현 도 살펴보십시오 .

또한보고 간단한 HTTP 서버 .

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

참고 URL : https://stackoverflow.com/questions/473620/how-do-you-create-a-daemon-in-python

반응형