添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

本地主机上的Python HTTP服务器很慢

20 人关注

我在创建一个非常简单的Python HTTP服务器时遇到了一些性能问题。关键问题是,性能取决于我用哪个客户端来访问它,其中服务器和所有客户端都在本地机器上运行。例如,从一个Python脚本发出的GET请求(urllib2.urlopen(' http://localhost/ ').read())需要一秒多的时间来完成,考虑到服务器没有负载,这似乎很慢。使用MSXML2.ServerXMLHTTP从Excel运行GET请求也感觉很慢。然而,从谷歌浏览器或RCurl(R的curl插件)中请求数据,基本上可以得到即时的响应,这是我所期望的。

让我更加困惑的是,当我在工作的电脑上时,我没有遇到任何客户端的性能问题(性能问题是在我家里的电脑上)。两个系统都运行Python 2.6,尽管工作电脑运行Windows XP而不是7。

下面是我非常简单的服务器例子,它对任何获取请求都简单地返回 "Hello world"。

from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
class MyHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        print("Just received a GET request")
        self.send_response(200)
        self.send_header("Content-type", "text/html")
        self.end_headers()
        self.wfile.write('Hello world')
        return
    def log_request(self, code=None, size=None):
        print('Request')
    def log_message(self, format, *args):
        print('Message')
if __name__ == "__main__":
        server = HTTPServer(('localhost', 80), MyHandler)
        print('Started http server')
        server.serve_forever()
    except KeyboardInterrupt:
        print('^C received, shutting down server')
        server.socket.close()

请注意,在MyHandler中我覆盖了log_request()和log_message()函数。原因是我读到,由这些函数之一执行的全称域名查询可能是导致服务器缓慢的一个原因。不幸的是,将它们设置为只打印一条静态信息并没有解决我的问题。

另外,注意到我在MyHandler的do_GET()例程的第一行加入了print()语句。缓慢发生在这个信息被打印之前,这意味着在它之后的东西都没有造成延迟。

python
Abiel
Abiel
发布于 2010-04-11
3 个回答
Philippe
Philippe
发布于 2022-09-08
已采纳
0 人赞同

请求处理程序发出一个反向的名称查询,以便在日志中显示客户名称。我的Windows 7发出的第一个DNS查询失败了,没有延迟,接着是2个连续的NetBIOS名称查询到HTTP客户端,每一个都运行到2秒的超时=4秒的延迟!

请看一下 https://bugs.python.org/issue6085

另一个对我有效的修复方法是,在我的请求处理程序中覆盖 BaseHTTPRequestHandler.address_string() ,使其不执行名称查询的版本。

def address_string(self):
    host, port = self.client_address[:2]
    #return socket.getfqdn(host)
    return host

Philippe

伟大的发现!你拯救了我的生命,否则我还在等着想知道为什么我的服务器在Win7和8下会爆炸的数量级。谢谢你!
这是我在使用IronPython 2.7.4时遇到的问题,删除这一行后,速度提高了100倍
老问题了,但绝对让我大开眼界!谢谢你的帮助!
user235859
user235859
发布于 2022-09-08
0 人赞同

这听起来不像是代码的问题。 排除HTTP服务器故障的一个巧妙方法是连接到它,在80端口telnet到它。 然后你可以输入类似的内容。

GET /index.html HTTP/1.1
host: www.blah.com
<enter> <enter>

并观察服务器的反应。 看看你使用这种方法是否会出现延迟。