服务器和后台进程之间通信的最佳实践

时间:2016-02-11 14:26:07

标签: python django

我有一个Django Web应用程序,它公开了我用来控制服务器的api。在同一台服务器上,我有一个后台进程。 Web应用程序需要定期通知后台进程某些内容已更改,以便进程可以从数据库刷新其信息。现在我设置它使后台进程在启动Django应用程序的wsgi脚本中的单独线程(使用multiprocessing.Process)中启动。这对于在开发期间轻松启动/停止所有内容非常方便。

我知道有一百种方法可以让这只特别的猫去皮,但我正在寻找最优雅的猫。我的预感是使用multiprocessing.Queue将数据传递给后台进程是一种很棒的方式。但是,我不知道队列在Django应用程序中的位置。我会在wsgi中实例化它吗?如果是这样,我将如何将其传递给应用程序?是否有其他地方应该创建它,以便我可以在应用程序视图中访问它?

我很好奇是否有人之前已经处理过这个挑战。

解决:

根据Aviah的建议,这是我使用SocketServer和静态类成员Queue的解决方案。工作得很漂亮。

我在服务器上的主要启动脚本:

if __name__ == "__main__":
    scanner = Scanner(API.queue)
    scanner.launch()

    print("Launcing Socket Server...")
    server = socketserver.TCPServer(('localhost', settings.PORT), API)
    server.serve_forever()

API类:

class API(socketserver.BaseRequestHandler):
    queue = Queue()

    def handle(self):
        data = pickle.loads(self.request.recv(RECEIVE_BUFFER_SIZE))

        ... bla bla ...

        API.queue.put(settings.SIGNALS.update)
        response = {Comm.response_label: Comm.response.ok}
        self.request.sendall(pickle.dumps(response))

扫描仪课程:

class Scanner:
    def __init__(self, signal_queue):
        self.queue = signal_queue

    def launch(self):
        # Launch the worker thread
        x = Process(target=self.scan)
        x.start()

    def scan(self):
        print("FileScanner started...")

        # Service Loop
        while True:
            try:
                signal = self.queue.get(block=False)
                print("Signal received.")
            except queue.Empty:
                pass

            ... bla bla ...

1 个答案:

答案 0 :(得分:0)

SocketServer是一个简单,独立的一行并运行python TCP服务器。如果你有Python,你已经拥有了它,你可以在本地的另一个线程上运行它。当您有大量工作时,只需将其移动到另一台机器即可。 (它实际上用于django runserver)。 https://docs.python.org/2/library/socketserver.html