2014-04-23 29 views
0

我的要求是生成hundreds of HTTP POST requests per second。我正在使用urllib2python多进程中进程的限制数

def send(): 
    req = urllib2.Request(url) 
    req.add_data(data) 
    response = urllib2.urlopen(req) 

while datetime.datetime.now() <= ftime: 
    p=Process(target=send, args=[]) 
    p.start() 
    time.sleep(0.001) 

问题是这样的代码sometimes for some iterations抛出以下两种异常:

HTTP 503 Service Unavailable. 
URLError: <urlopen error [Errno -2] Name or service not known> 

我一直在使用requests(HTTP for humans)也试过,但我有这个模块一些代理的问题。看起来像requests即使目标机器位于同一LAN内,也会向代理服务器发送http数据包。我不希望数据包去代理服务器。

+0

如果目标是产生大量的请求,我不会在那样的个别进程中启动这些请求。非常低效。使用扭曲和基于epoll的反应堆:http://twistedmatrix.com/documents/current/web/howto/client.html – agrinh

+0

@agrinh感谢您的回复。你对如何在循环中使用Twisted有任何想法,我只能使用它生成单个请求。你能否提供一些代码片段? –

+0

[多线程Python应用程序和套接字连接问题](http://stackoverflow.com/q/4783735/4279)具有代码示例,显示如何使用各种框架(例如'asyncio','twisted','' gevent'。 – jfs

回答

0

限制并发连接数的最简单的方法是使用一个线程池:

#!/usr/bin/env python 
from itertools import izip, repeat 
from multiprocessing.dummy import Pool # use threads for I/O bound tasks 
from urllib2 import urlopen 

def fetch(url_data): 
    try: 
     return url_data[0], urlopen(*url_data).read(), None 
    except EnvironmentError as e: 
     return url_data[0], None, str(e) 

if __name__=="__main__": 
    pool = Pool(20) # use 20 concurrent connections 
    params = izip(urls, repeat(data)) # use the same data for all urls 
    for url, content, error in pool.imap_unorderred(fetch, params): 
     if error is None: 
      print("done: %s: %d" % (url, len(content))) 
     else: 
      print("error: %s: %s" % (url, error)) 

503 Service Unavailable是一个服务器错误。它可能无法处理负载。

Name or service not known是一个dns错误。如果你需要提出很多请求,安装/启用本地缓存dns服务器。