我在创建一个非常简单的Python HTTP服务器时遇到了一些性能问题.关键问题是性能取决于我用来访问它的客户端,服务器和所有客户端在本地计算机上运行的位置.例如,从Python脚本(urllib2.urlopen(' http:// localhost / ').read())发出的GET请求只需要一秒钟就可以完成,考虑到服务器处于空载状态,这似乎很慢.使用MSXML2.ServerXMLHTTP从Excel运行GET请求也感觉很慢.但是,请求数据谷歌Chrome或来自RCurl的卷曲加载项RCurl会产生基本上即时的响应,这正是我所期望的.
更让我感到困惑的是,当我在工作时使用计算机时,我没有遇到任何客户端的性能问题(性能问题出在我的家用计算机上).两个系统都运行Python 2.6,尽管工作计算机运行Windows XP而不是7.
下面是我非常简单的服务器示例,它只是为任何get请求返回'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()
Run Code Online (Sandbox Code Playgroud)
请注意,在MyHandler中,我重写了log_request()和log_message()函数.原因是我读到由这些功能之一执行的完全限定的域名查找可能是服务器速度慢的原因.不幸的是,将它们设置为仅打印静态消息并不能解决我的问题.
另外,请注意我已将print()语句作为MyHandler中do_GET()例程的第一行.在打印此消息之前发生缓慢,这意味着在它之后没有任何东西导致延迟.
小智 27
请求处理程序发出反向名称查找,以便在日志中显示客户端名称.我的Windows 7发出第一个DNS查找失败,没有延迟,接着是HTTP客户端的2个连续NetBIOS名称查询,每个都运行2秒超时= 4秒延迟!!
看看http://www.answermysearches.com/xmlrpc-server-slow-in-python-how-to-fix/2140/
另一个对我有用的修复是BaseHTTPRequestHandler.address_string()
在我的请求处理程序中覆盖不执行名称查找的版本
def address_string(self):
host, port = self.client_address[:2]
#return socket.getfqdn(host)
return host
Run Code Online (Sandbox Code Playgroud)
菲利普
小智 13
这听起来不像代码的问题.对HTTP服务器进行故障排除的一种很好的方法是连接到它以便在端口80上telnet到它.然后你可以输入类似的东西:
GET /index.html HTTP/1.1
host: www.blah.com
<enter> <enter>
Run Code Online (Sandbox Code Playgroud)
并观察服务器的响应.看看你是否因使用这种方法而受到延迟.
您可能还想关闭所有防火墙,看看他们是否应对减速负责.
尝试将127.0.0.1替换为localhost.如果这解决了问题,那么这是一个线索,FQDN查找可能确实是可能的原因.