파이썬에서 데몬을 어떻게 만드나요?
Google에서 검색하면 x2 코드 스 니펫이 나타납니다. 첫 번째 결과는 이 코드 레시피에 관한 것인데, 이 코드 레시피 는 아래에 유용한 토론과 함께 많은 문서와 설명이 있습니다.
그러나 다른 문서에는 많은 문서가 포함되어 있지 않지만 시작, 중지 및 다시 시작과 같은 명령을 전달하기위한 샘플 코드가 포함되어 있습니다. 또한 데몬이 이미 실행 중인지 확인하는 데 편리한 PID 파일을 만듭니다.
이 샘플은 모두 데몬을 만드는 방법을 설명합니다. 고려해야 할 추가 사항이 있습니까? 한 샘플이 다른 샘플보다 낫습니까? 왜 그렇습니까?
현재 솔루션
PEP 3143 (표준 데몬 프로세스 라이브러리) 의 참조 구현을 python-daemon으로 사용할 수 있습니다 .
역사적 답변
Sander Marechal의 코드 샘플 은 원래 2004 년에 게시 된 원본보다 우수합니다. Pyro의 데몬 타이 저에 기여한 적이 있지만, 그렇게해야한다면 Sander의 코드를 사용했을 것입니다.
잘 작동하는 데몬 프로세스 가 될 때주의 해야 할 사항 이 많이 있습니다 .
코어 덤프 방지 (많은 데몬이 루트로 실행되며 코어 덤프에는 중요한 정보가 포함될 수 있음)
chroot
gaol 안에서 올바르게 행동하다사용 사례에 맞게 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 솔루션을 선호 할 수도 있지만 적어도 BSD 및 Linux 에는 올바른 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
'IT story' 카테고리의 다른 글
Visual Studio 2010 이상에서 확대 / 축소를 다시 설정하는 방법 (0) | 2020.04.12 |
---|---|
React Native를 어떻게 디버깅합니까? (0) | 2020.04.12 |
데이터 프레임 열에서 값이 발생하는 빈도를 계산 (0) | 2020.04.12 |
C ++로 HTTP 요청을 어떻게합니까? (0) | 2020.04.12 |
Chrome의 스크립트 디버거가 자바 스크립트를 다시로드하도록 강제하는 방법은 무엇입니까? (0) | 2020.04.12 |