如何让多台gevent服务器永远服务?

时间:2013-08-27 01:21:16

标签: python blocking gevent

目前,我有一个应用程序有两个服务器:第一个处理订单并单独响应,第二个广播结果给其他感兴趣的订阅者。它们需要从不同的端口提供服务。我可以开始()它们两个,但我只能得到一个或另一个到serve_forever(),因为我读到它是一个阻塞函数。我正在寻找有关如何防止服务器退出的想法。缩写代码如下:

def main():
    stacklist = []
    subslist = []
    stacklist.append(CreateStack('stuff'))
    subslist.append(Subscription('stuff'))
    bcastserver = BroadcastServer(subslist) # creates a new server
    tradeserver = TradeServer(stacklist) # creates a new server
    bcastserver.start() # start accepting new connections
    tradeserver.start() # start accepting new connections
    #bcastserver.serve_forever()  #if I do it here, the first one...
    #tradeserver.serve_forever()  #blocks the second one

class TradeServer(StreamServer):
    def __init__(self, stacklist):
        self.stacklist = stacklist
        StreamServer.__init__(self, ('localhost', 12345), self.handle)
        #self.serve_forever()  #If I put it here in both, neither works

    def handle(self, socket, address):
        #handler here

class BroadcastServer(StreamServer):
    def __init__(self, subslist):
        StreamServer.__init__(self, ('localhost', 8000), self.handle)
        self.subslist = subslist
        #self.serve_forever()  #If I put it here in both, neither works

    def handle(self, socket, address):
        #handler here

也许我只是需要一种方法来防止两人退出,但我不确定如何。最后,我希望两台服务器永远监听传入的连接并处理它们。

3 个答案:

答案 0 :(得分:2)

我知道这个问题的答案可以接受,但是有一个更好的答案。我将其添加给像我这样的人,这些人以后可以找到此帖子。

gevent documentation about servers中所述:

  

BaseServer.serve_forever()方法调用BaseServer.start(),然后等待直到被中断或服务器停止。

所以您可以这样做:

def main():
    stacklist = []
    subslist = []
    stacklist.append(CreateStack('stuff'))
    subslist.append(Subscription('stuff'))
    bcastserver = BroadcastServer(subslist) # creates a new server
    tradeserver = TradeServer(stacklist) # creates a new server
    bcastserver.start() # starts accepting bcast connections and returns
    tradeserver.serve_forever() # starts accepting trade connections and blocks until tradeserver stops
    bcastserver.stop() # stops also the bcast server

gevent introduction documentation解释了为什么这样做:

  

与其他网络库不同,尽管其方式与   eventlet,gevent以专用方式隐式启动事件循环   绿色。没有反应堆,您必须调用run()或dispatch()   功能开启。当gevent的API中的函数想要阻止时,它会   获取gevent.hub.Hub实例-运行   事件循环-并切换到该循环(据说Greenlet产生了   控制到集线器)。

serve_forever()阻塞时,它不会阻止任何服务器继续通信。

注意:在上面的代码中,交易服务器是决定整个应用程序何时停止的服务器。如果要由广播服务器决定,则应在start()serve_forever()呼叫中交换它们。

答案 1 :(得分:1)

好的,我能够使用线程和gevent的monkeypatch库来做到这一点:

from gevent import monkey
def main():
    monkey.patch_thread()
# etc, etc
t = threading.Thread(target=bcastserver.serve_forever)
t.setDaemon(True)
t.start()
tradeserver.serve_forever()

答案 2 :(得分:0)

在自己的Python实例中启动每个服务器循环(每个gevent一个控制台)。我从未理解尝试从一个程序运行多个服务器。您可以多次运行同一台服务器,并使用像nginx这样的反向代理来相应地进行负载均衡和路由。