2016-09-02 12 views
0

私は2つのTornadoサーバーを同じPythonプロセスで実行しています。 1つはTCPServerで、もう1つはHTTPServerです。 TCPServerは何らかのソースからデータを受信し、HTTPServerはそのデータを配信されたWebページに接続されているすべてのクライアントにブロードキャストします。私は2台のサーバがtornado.queues.Queue()でデータをやりとりしていて、TCPServerはデータをキューに入れ、HTTPServerはそこからデータを得て、それをウェブページクライアントに送ります。Tornado/Python3でマルチプロセスTCPServerとHTTPServerを起動しますか?

質問は、どうすれば複数のコアを利用できるのですか?データは1回の送信元からしか届かないので、TCPServerには1つのコアを割り当てるのが理にかなっていますが、任意の数のクライアントが存在する可能性があるので、それぞれ独自のインスタンスHTTPServerクライアント。私は、単一のプロセスで実行されている2つのサーバーを持っているので、しかし

def main(): 
    app = make_app() 
    server = tornado.httpserver.HTTPServer(app) 
    server.bind(8888) 
    server.start(0) # forks one process per cpu 
    IOLoop.current().start() 

:トルネードのドキュメントから

、私はすべてのサーバーが無関係だったら、私はちょうどこのような何かをしなければならないだろうと見、私はそれを鏡にすることはできません。

Traceback (most recent call last): 
    File "./tcp_server.py", line 28, in <module> 
    http_server.start(0) 
    File "/usr/local/lib/python3.5/dist-packages/tornado/tcpserver.py", line 205, in start 
    process.fork_processes(num_processes) 
    File "/usr/local/lib/python3.5/dist-packages/tornado/process.py", line 130, in fork_processes 
    raise RuntimeError("Cannot run in multiple processes: IOLoop instance " 
RuntimeError: Cannot run in multiple processes: IOLoop instance has already been initialized. You cannot call IOLoop.instance() before calling start_processes() 

がどのように私はTCPServer 1でプロセスを持つように起動手順を再編成し、他のすべてのプロセスにHTTPServerの複数のインスタンスことができます。私はそれをしようとすると、私はというエラーを取得します?

import logging 
import tornado 
import tornado.queues 
from buggy_data_server import BuggyDataServer 
from buggy_http_server import BuggyHttpServer 

if __name__ == "__main__": 
    logging.basicConfig(level=logging.DEBUG) 
    data_queue = tornado.queues.Queue() 

    # Currently, both servers are started in a single process. This needs to be 
    # split up into a multiprocess configuration later. 
    data_sock = tornado.netutil.bind_sockets(4242) 
    data_server = BuggyDataServer(data_queue) # TCPServer 
    data_server.add_sockets(data_sock) 

    http_sock = tornado.netutil.bind_sockets(8080) 
    http_server = BuggyHttpServer(data_queue) # HTTPServer 
    http_server.add_sockets(http_sock) 
    http_server.start(0) 

    tornado.ioloop.IOLoop.instance().start() 

答えて

1

これはTCPServer docsの「高度なマルチプロセス」に該当。サーバの1台にそれをさせる代わりに、fork_processesを明示的に呼び出す必要があります。 (経験則として、あなたはフォークの前にできるだけやりたい)あなたはフォークの前に、すべてのソケットをバインドするようにセットアップの呼び出しの順序を変更し、後にサーバに追加します:

data_sock = tornado.netutil.bind_sockets(4242) 
http_sock = tornado.netutil.bind_sockets(8080) 

tornado.process.fork_processes(0) 

data_server = BuggyDataServer(data_queue) # TCPServer 
data_server.add_sockets(data_sock) 
http_server = BuggyHttpServer(data_queue) # HTTPServer 
http_server.add_sockets(http_sock) 

この各プロセスでHTTPサーバーとTCPサーバーを開始します。あなたが唯一のTCPサーバーを実行(およびその過程でHTTPサーバを実行しない)する必要がある場合は、fork_processesの戻り値を見ることができます。

http_sock = tornado.netutil.bind_sockets(8080) 
proc_num = tornado.process.fork_processes(0) 

if proc_num == 0: 
    # Close the HTTP sockets in the TCP server's process 
    for s in http_sock: s.close() 
    BuggyDataServer(data_queue).listen(4242) 
else: 
    BuggyHttpServer(data_queue).add_sockets(http_sock) 
+0

おかげでベンを!ノートと同様に、小さなタイプミス(proc_num == 0)がありますが、変更が十分ではないので編集できません。 – Vasu

関連する問題