使用python运行多个服务器

时间:2018-08-28 13:43:31

标签: python server

我基本上是试图使用一个简单的脚本来运行两个服务器。我使用了herethere和其他解决方案。 例如,在下面的示例中,我尝试在端口8000和8001中托管两个目录。

import http.server
import socketserver
import os
import multiprocessing


def run_webserver(path, PORT):
    os.chdir(path)
    Handler = http.server.SimpleHTTPRequestHandler
    httpd = socketserver.TCPServer(('0.0.0.0', PORT), Handler)

    httpd.serve_forever()

    return


if __name__ == '__main__':

    # Define "services" directories and ports to use to host them
    server_details = [
        ("path/to/directory1", 8000),
        ("path/to/directory2", 8001)
    ]

    # Run servers
    servers = []
    for s in server_details: 
        p = multiprocessing.Process(
            target=run_webserver, 
            args=(s[0], s[1])
            )
        servers.append(p)  

    for server in servers:
        server.start()

    for server in servers:
        server.join()

一旦执行下面的代码,一切都可以正常工作,并且可以使用http://localhost:8000http://localhost:8001访问两个目录。但是,当我使用 Ctrl + C 退出脚本,然后尝试再次运行该脚本时,出现以下错误:

 Traceback (most recent call last):                                                                                     
 "/home/user/anaconda3/lib/python3.6/multiprocessing/process.py", line 258, in _bootstrap           
        self.run()                                                                                                         
      File "/home/user/anaconda3/lib/python3.6/multiprocessing/process.py", line 93, in run                   
        self._target(*self._args, **self._kwargs)                                                                          
      File "repos/scripts/webhosts.py", line 12, in run_webserver                                                          
      File "/home/user/anaconda3/lib/python3.6/socketserver.py", line 453, in __init__                        
        self.server_bind()                                                                                                 
      File "/home/user/anaconda3/lib/python3.6/socketserver.py", line 467, in server_bind                     
        self.socket.bind(self.server_address)                                                                              
    OSError: [Errno 98] Address already in use 

仅当我在运行时实际访问服务器时,才会弹出此错误。如果无法访问该脚本,则可以重新运行该脚本...从错误消息看来,键入lsof -n -i4TCP:8000lsof -n -i4TCP:8001时仍然有某些内容正在访问服务器任何东西……一段时间后,此错误停止出现,我实际上可以运行该脚本了。

2 个答案:

答案 0 :(得分:2)

在启动服务器之前,添加:

socketserver.TCPServer.allow_reuse_address = True

或在调用serve_forever()之前再次更改实例的属性:

htttp.allow_reuse_address = True

Documentation reference

  

BaseServer.allow_reuse_address

     

服务器是否将允许地址的重用。默认为False,可以在子类中设置以更改策略。

答案 1 :(得分:0)

扩大我的评论:

在先前的编辑中,OP注册了退出处理程序atexit.register(exit_handler)。问题是,这是否会清理您的系统资源(也就是打开的套接字)?

如果您的程序在没有关闭套接字的情况下退出(因为您用Ctrl + C中断了它),则操作系统需要花费一些时间来清理套接字(因为它们处于TIME_WAIT状态),您可以阅读有关TIME_WAIT以及有关方法的信息。避免在here中使用它。

使用退出处理程序是避免这种情况的好方法

import atexit
atexit.register(clean_sockets)

def clean_sockets():
    mysocket.server_close() #