2013年4月19日 星期五

python BaseHTTPServer 速度緩慢的原因

在用 Bottle 的開發模式時, 發覺有時候速度會異常的慢。等到受不了以後, 按下 ctrl+c 看到以下的 backtrace:

Exception happened during processing of request from ('xxx.xxx.xxx.xxx', 37515)
Traceback (most recent call last):
File "/usr/lib/python2.7/SocketServer.py", line 284, in _handle_request_noblock
self.process_request(request, client_address)
File "/usr/lib/python2.7/SocketServer.py", line 310, in process_request
self.finish_request(request, client_address)
File "/usr/lib/python2.7/SocketServer.py", line 323, in finish_request
self.RequestHandlerClass(request, client_address, self)
File "/usr/lib/python2.7/SocketServer.py", line 638, in __init__
self.handle()
File "/usr/lib/python2.7/wsgiref/simple_server.py", line 121, in handle
self.rfile, self.wfile, self.get_stderr(), self.get_environ()
File "/usr/lib/python2.7/wsgiref/simple_server.py", line 85, in get_environ
host = self.address_string()
File "/usr/lib/python2.7/BaseHTTPServer.py", line 498, in address_string
return socket.getfqdn(host)
File "/usr/lib/python2.7/socket.py", line 137, in getfqdn
hostname, aliases, ipaddrs = gethostbyaddr(name)
KeyboardInterrupt

依照過去的經驗, 這個 gethostbyaddr 相當可疑。

作個簡單測試證實問題:

$ python -c 'import socket; print socket.gethostbyaddr("xxx.xxx.xxx.xxx")'
Traceback (most recent call last):
File "<string>", line 1, in <module>
socket.herror: [Errno 2] Host name lookup failure

再來用老招 ltrace 確認問題源頭:

$ ltrace  python -c 'import socket; print 
socket.gethostbyaddr("xxx.xxx.xxx.xxx")' 2>&1 | grep gethost
( ... 略 ... )
gethostbyaddr_r(0x7fffa5bbb834, 4, 2, 0x7fffa5bb77f0, 0x7fffa5bb7830) = 0

由 man gethostbyaddr 得知它會查 /etc/hosts, 最後在 /etc/hosts 加入一筆 "xxx.xxx.xxx.xxx xxx.xxx.xxx.xxx", 就立即有結果了:

$ python -c 'import socket; print socket.gethostbyaddr("xxx.xxx.xxx.xxx")'
('xxx.xxx.xxx.xxx', [], ['xxx.xxx.xxx.xxx'])

沒有留言:

張貼留言

在 Fedora 下裝 id-utils

Fedora 似乎因為執行檔撞名,而沒有提供 id-utils 的套件 ,但這是使用 gj 的必要套件,只好自己編。從官網抓好 tarball ,解開來編譯 (./configure && make)就是了。 但編譯後會遇到錯誤: ./stdio.h:10...