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

新手上路,请多包涵

我在创建一个非常简单的 Python HTTP 服务器时遇到了一些性能问题。关键问题是性能会有所不同,具体取决于我用来访问它的客户端,服务器和所有客户端都在本地计算机上运行的位置。例如,从 Python 脚本 (urllib2.urlopen(’ http://localhost/ ‘).read()) 发出的 GET 请求只需要一秒多一点的时间即可完成,考虑到服务器没有负载,这似乎很慢。使用 MSXML2.ServerXMLHTTP 从 Excel 运行 GET 请求也感觉很慢。但是,从 Google Chrome 或 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__":
    try:
        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 中将 print() 语句作为 do_GET() 例程的第一行。缓慢发生在打印此消息之前,这意味着它之后的任何内容都不会导致延迟。

原文由 Abiel 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 562
2 个回答

这听起来不像是代码的问题。对 HTTP 服务器进行故障排除的一个绝妙方法是连接到它以在端口 80 上远程登录到它。然后你可以键入如下内容:

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

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

您可能还想关闭所有防火墙,看看它们是否是造成速度下降的原因。

尝试将 127.0.0.1 替换为本地主机。如果这解决了问题,则表明 FQDN 查找可能确实是可能的原因。

原文由 user235859 发布,翻译遵循 CC BY-SA 2.5 许可协议

请求处理程序发出反向名称查找,以便在日志中显示客户端名称。我的 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 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏