web-dev-qa-db-ja.com

実行中のpythonデーモンとの通信

デーモンとして実行する小さなPython=アプリケーションを作成しました。スレッド化とキューを利用しています。

このアプリケーションを実行中に通信できるように、このアプリケーションを変更する一般的な方法を探しています。主に私はその健康状態を監視できるようになりたいです。

一言で言えば、私は次のようなことができるようになりたいです:

python application.py start  # launches the daemon

後で、一緒に来て、次のようなことができるようになりたいです。

python application.py check_queue_size  # return info from the daemonized process

明確にするために、私はDjangoにヒントを得た構文を実装するのに何の問題もありません。デーモン化されたプロセス(開始)にシグナルを送信する方法、またはデーモンを記述してそのようなシグナルを処理および応答する方法について、私は何も考えていません。

上記で述べたように、私は一般的なアプローチを探しています。今私が見ることができる唯一のものは、デーモンにファイルに必要となる可能性のあるすべてのものを絶えず記録するように伝えることですが、私はそれについてより簡単な方法があることを願っています。

更新:うわー、たくさんの素晴らしい答え。本当にありがとう。私はPyroとweb.py/Werkzeugの両方のアプローチを検討するつもりです。なぜなら、Twistedはこの時点で私が噛み締めたいと思っているよりも少し多いからです。次の概念的な課題は、私が思うに、ワーカースレッドをハングアップすることなく、それらに話しかける方法です。

再度、感謝します。

52
hanksims

Httpサーバーを実行するのはどうですか?

奇妙に思えますが、サーバーを管理するための単純なWebサーバーを実行するには、web.pyを使用して数行だけで十分です

UNIXパイプの作成を検討することもできます。

18
fulmicoton

さらに別のアプローチ: Pyro (Pythonリモーティングオブジェクト)を使用します。

Pyroは基本的に、リモートで呼び出すことができるサービスとしてPythonオブジェクトインスタンスを公開することを許可します。私はPyroをあなたが説明した正確な目的に使用しましたが、非常にうまく機能することがわかりました。

デフォルトでは、Pyroサーバーデーモンはどこからでも接続を受け入れます。これを制限するには、接続バリデーター(ドキュメントを参照)を使用するか、Host='127.0.0.1'Daemonコンストラクターに渡し、ローカル接続のみをリッスンします。

Pyroのドキュメントから抜粋したコードの例:

サーバー

 import Pyro.core 
 
 class JokeGen(Pyro.core.ObjBase):
 def __init __(self):
 Pyro.core.ObjBase .__ init __(self)
 def joke(self、name):
 return "Sorry" + name + "、I do n't know at jokes。" 
 
 Pyro.core.initServer()
 daemon = Pyro.core.Daemon()
 uri = daemon.connect(JokeGen()、 "jokegen")
 
 print "デーモンはポートで実行されます:"、daemon.port 
 print "オブジェクトのuriは:"、uri 
 
 daemon.requestLoop()

クライアント

 import Pyro.core 
 
#自分のホスト/ポートに一致するように以下のURIを変更する必要があります。
 jokes = Pyro.core.getProxyForURI( "PYROLOC :// localhost:7766/jokegen ")
 
 print jokes.joke(" Irmen ")

他の同様のプロジェクトは RPyC です。 RPyCは試していません。

35
codeape

werkzeug を使用して、デーモンにHTTPベースのWSGIサーバーを含めます。

デーモンには、ステータス情報で応答する小さなWSGIアプリのコレクションがあります。

クライアントは単にurllib2を使用してPOSTまたはGETリクエストをlocalhost:somePortに送信します。クライアントとサーバーはポート番号(およびURL)について合意する必要があります。

これは実装が非常に簡単で、非常にスケーラブルです。新しいコマンドを追加するのは簡単なことです。

デーモンはHTMLで応答する必要がないことに注意してください(ただし、それは多くの場合単純です)。私たちのデーモンは、JSONエンコードされたステータスオブジェクトでWSGIリクエストに応答します。

16
S.Lott

名前付きパイプでツイストを使用するか、ソケットを開きます。エコーサーバーとクライアント examples を見てください。エコーサーバーを変更して、クライアントから渡された文字列を確認し、要求された情報で応答する必要があります。

Pythonのスレッド化の問題により、情報要求に応答するのに問題が生じ、同時にデーモンが意図することを何でも実行し続けることになります。非同期技術または別のプロセスのフォークは、あなたの唯一の現実的な選択肢です。

9
MrEvil
# your server

from twisted.web import xmlrpc, server
from twisted.internet import reactor

class MyServer(xmlrpc.XMLRPC):

    def xmlrpc_monitor(self, params):        
        return server_related_info

if __== '__main__':
    r = MyServer()
    reactor.listenTCP(8080, Server.Site(r))
    reactor.run()

クライアントはxmlrpclibを使用して記述できます。コード例 here を確認してください。

7
Badri

* nixを使用していると仮定すると、シェル(および他の多くの環境のアナログ)からkillを使用して、実行中のプログラムに信号を送信できます。 python内からそれらを処理するには、 signal モジュールを確認してください。

5
MarkusQ

Pyro( http://pythonhosted.org/Pyro4/ )Python Remote Objectと関連付けることができます。リモートアクセスpythonオブジェクト:実装が簡単で、オーバーヘッドが少なく、Twistedほど侵襲的ではありません。

4
directedition