2009-02-26 38 views
23

我有一個我用python編寫的工具,一般應該作爲守護進程運行。打包此工具進行分發的最佳做法是什麼,特別是如何處理設置文件和守護程序可執行文件/腳本?Python守護進程包裝最佳實踐

與此相關的是有用於設置守護程序在啓動時運行的適合特定平臺的任何常用的工具(在Linux上即初始化腳本,服務在Windows,OS X上的launchd)?

+1

另請參閱此SO問題:http://stackoverflow.com/questions/473620/how-do-you-create-a-daemon-in-python – Rabarberski 2012-01-11 09:42:43

回答

11

要回答你的問題的一部分,沒有工具,我知道的,會做可移植甚至跨Linux系統守護進程設置更不用說Windows或Mac OS X.

大多數Linux發行版似乎可以用start-stop-daemon內init腳本,但是你仍然會在文件系統佈局上有細微的差別,在包裝上也有很大的差異。如果你的項目都是Python,使用autotools/configure或者distutils/easy_install將會大大簡化爲不同的Linux/BSD發行版構建軟件包的過程。

Windows是一個完全不同的遊戲,將需要Mark Hammond's win32擴展名和可能Tim Golden's WMI擴展名。

我不知道Launchd除了「以上都不是」是相關的。

關於守護Python腳本的提示,我會看看實際在真實世界中執行它的Python應用程序,例如Twisted內部。

14

我發現的幫助init.d腳本的最佳工具是「start-stop-daemon」。它將運行任何應用程序,監視運行/ pid文件,必要時創建它們,提供停止守護進程的方法,設置進程用戶/組ID,甚至可以爲進程提供後臺。

例如,這是一個可以啓動/停止WSGI服務器的腳本:

#! /bin/bash 

case "$1" in 
    start) 
    echo "Starting server" 

    # Activate the virtual environment 
    . /home/ali/wer-gcms/g-env/bin/activate 

    # Run start-stop-daemon, the $DAEMON variable contains the path to the 
    # application to run 
    start-stop-daemon --start --pidfile $WSGI_PIDFILE \ 
     --user www-data --group www-data \ 
     --chuid www-data \ 
     --exec "$DAEMON" 
    ;; 
    stop) 
    echo "Stopping WSGI Application" 

    # Start-stop daemon can also stop the application by sending sig 15 
    # (configurable) to the process id contained in the run/pid file 
    start-stop-daemon --stop --pidfile $WSGI_PIDFILE --verbose 
    ;; 
    *) 
    # Refuse to do other stuff 
    echo "Usage: /etc/init.d/wsgi-application.sh {start|stop}" 
    exit 1 
    ;; 
esac 

exit 0 

你也可以看到有一個如何用virtualenv中,我總是建議使用它的一個例子。 「一般應該作爲一個守護進程運行?」

-10

不 - 在表面上 - 有很大的意義。 「一般」不明智。它不是一個守護進程就是一個守護進程。你可能想更新你的問題。

有關守護程序的示例,請閱讀諸如Apache的httpd或任何數據庫服務器(它們是守護程序)或SMTPD郵件守護程序的守護程序。或者,也許讀一些更簡單的東西,比如FTP守護進程,SSH守護進程,Telnet守護進程。

在Linux世界中,您將擁有應用程序安裝目錄,某些工作目錄以及配置文件目錄。

我們使用/opt/ourapp的應用程序(這是Python,但我們不要安裝在Python的lib/site-packages

我們使用/var/ourapp的工作文件,我們的配置文件。

我們可以使用/etc/ourapp作爲配置文件 - 這是一致的 - 但我們不這樣做。

我們尚未使用init.d腳本進行啓動。但這是最後一塊,自動化的啓動。現在,我們有sys管理員啓動守護進程。

這部分基於http://www.pathname.com/fhs/http://tldp.org/LDP/Linux-Filesystem-Hierarchy/html/Linux-Filesystem-Hierarchy.html

+2

你很漂亮強硬!? 守護進程只是守護進程的程序。有時將它們作爲Ctrl-C的常規進程運行會很有用,請檢查stdout上的輸出等。 – fulmicoton 2009-02-26 02:15:32

+0

@Paul:同意。你能澄清這個問題嗎? – 2009-02-26 02:21:41

0

在Linux系統上,系統的軟件包管理器(Portage for Gentoo,Aptitude for Ubuntu/Debian,yum for Fedora等)通常負責安裝程序,包括將init腳本放在正確的位置。如果你想分發你的Linux程序,你可能需要考慮將它捆綁到各種發行版軟件包管理器的正確格式中。

這個建議顯然與沒有包管理器的系統無關(Windows和Mac我認爲)。

+0

有很多其他Unices的包裝系統!例如NetBSD的pkgsrc。 – bortzmeyer 2009-02-26 08:57:52

+0

有趣的是,我不知道 – 2009-02-26 17:54:37

8

有在互聯網上提供許多片段寫在純Python守護程序(沒有的bash腳本)

http://www.jejik.com/articles/2007/02/a_simple_unix_linux_daemon_in_python/ 看起來乾淨...

如果你想編寫自己的,
的原理與bash守護進程功能相同。

基本上是:

在啓動:

  • 你叉到另一個進程
  • 打開日誌文件到PID某處重定向你 輸出和錯誤
  • 保存。

在車站:

  • 您發送SIGTERM到進程的PID與存儲在您的pidfile進程文件。
  • 使用signal.signal(signal.SIGTERM,sigtermhandler),您可以將停止 過程綁定到SIGTERM信號。

我不知道這樣做的任何廣泛使用的軟件包。

3

我不記得我在哪裏下載了它......但這是我找到的最好的守護進程腳本。它精美作品(在Mac和Linux操作系統。)(保存爲daemonize.py)

import sys, os 
def daemonize (stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'): 
    # Perform first fork. 
    try: 
     pid = os.fork() 
     if pid > 0: 
      sys.exit(0) # Exit first parent. 
    except OSError, e: 
     sys.stderr.write("fork #1 failed: (%d) %sn" % (e.errno, e.strerror)) 
     sys.exit(1) 
    # Decouple from parent environment. 
    os.chdir("/") 
    os.umask(0) 
    os.setsid() 
    # Perform second fork. 
    try: 
     pid = os.fork() 
     if pid > 0: 
      sys.exit(0) # Exit second parent. 
    except OSError, e: 
     sys.stderr.write("fork #2 failed: (%d) %sn" % (e.errno, e.strerror)) 
     sys.exit(1) 
    # The process is now daemonized, redirect standard file descriptors. 
    for f in sys.stdout, sys.stderr: f.flush() 
    si = file(stdin, 'r') 
    so = file(stdout, 'a+') 
    se = file(stderr, 'a+', 0) 
    os.dup2(si.fileno(), sys.stdin.fileno()) 
    os.dup2(so.fileno(), sys.stdout.fileno()) 
    os.dup2(se.fileno(), sys.stderr.fileno()) 

在腳本中,您只需:

from daemonize import daemonize 
daemonize() 

而且你還可以指定地方重定向標準輸入輸出,錯誤等...

3

不是你問什麼銀彈,但檢查出supervisord。它處理管理流​​程的所有有趣部分。我在大型生產環境中大量使用它。另外,它是用Python編寫的!

0

blog entry清楚對我來說其實有讓你的Python程序作爲deamon運行的兩種常見方法(我沒有從現有的答案中清楚地看出):

有兩種方法可以在Python中編寫像服務器 這樣的守護進程應用程序。

  • 首先是手柄sarting的所有任務,並在Python代碼本身 停止守護進程。最簡單的方法是使用 和python-daemon軟件包,它最終可能會將 轉換爲Python發行版。

Poeljapon's answer這是第一個方法的一個例子,雖然它不使用python-daemon包,但鏈接到一個自定義的,但非常乾淨的python腳本。

  • 的另一種方法是使用由操作系統供給的工具 。在Debain的情況下,這意味着 編寫一個使用start-stop-daemon 程序的初始化腳本。

Ali Afshar's answer是第二方法的一個外殼腳本例如,使用start-stop-daemon

的博客中我引用了一個shell腳本例子,在一些事情的更多詳細信息,例如在系統啓動時啓動您的守護進程,並自動重新啓動守護進程時,它停止以任何理由。

0

糾正我,如果錯了,但我相信問題是如何部署守護進程。將您的應用設置爲通過點安裝,然後使entry_point爲cli(daemon())。然後創建一個初始化腳本,只需運行$app_name &