我想为REST webserivce做很多url requets。通常在75-90k之间。但是,我需要限制与Web服务的并发连接数。
我开始以下列方式玩弄问候,但很快就开始咀嚼打开的插座。
concurrent_limit = 30
urllist = buildUrls()
hdrs = {'Host' : 'hostserver'}
g_requests = (grequests.get(url, headers=hdrs) for url in urls)
g_responses = grequests.map(g_requests, size=concurrent_limit)
由于这种情况持续了一分钟左右,我遇到了“达到最大套接字数”错误。 据我所知,grequests中的每个requests.get调用都使用它自己的会话,这意味着为每个请求打开一个新的套接字。
我在github上找到了一条说明,指出如何使用单个会话进行grequest。但这似乎有效地将所有请求瓶颈到一个共享池中。这似乎打败了异步http请求的目的。
s = requests.session()
rs = [grequests.get(url, session=s) for url in urls]
grequests.map(rs)
是否可以以创建多个会话的方式使用grequests或gevent.Pool?
换句话说:如何通过排队或连接池来创建许多并发的http请求?
答案 0 :(得分:6)
我最终没有使用grequests来解决我的问题。我仍然希望它有可能。
我使用了线程:
class MyAwesomeThread(Thread):
"""
Threading wrapper to handle counting and processing of tasks
"""
def __init__(self, session, q):
self.q = q
self.count = 0
self.session = session
self.response = None
Thread.__init__(self)
def run(self):
"""TASK RUN BY THREADING"""
while True:
url, host = self.q.get()
httpHeaders = {'Host' : host}
self.response = session.get(url, headers=httpHeaders)
# handle response here
self.count+= 1
self.q.task_done()
return
q=Queue()
threads = []
for i in range(CONCURRENT):
session = requests.session()
t=MyAwesomeThread(session,q)
t.daemon=True # allows us to send an interrupt
threads.append(t)
## build urls and add them to the Queue
for url in buildurls():
q.put_nowait((url,host))
## start the threads
for t in threads:
t.start()
答案 1 :(得分:3)
这样的事情:
NUM_SESSIONS = 50
sessions = [requests.Session() for i in range(NUM_SESSIONS)]
reqs = []
i = 0
for url in urls:
reqs.append(grequests.get(url, session=sessions[i % NUM_SESSIONS]
i+=1
responses = grequests.map(reqs, size=NUM_SESSIONS*5)
这应该将请求分散到50个不同的会话中。
答案 2 :(得分:2)
rs是一个AsyncRequest list.each AsyncRequest拥有它自己的会话。
rs = [grequests.get(url) for url in urls]
grequests.map(rs)
for ar in rs:
print(ar.session.cookies)