2013-07-30 4 views
3

Я работаю над скриптом python 2.7, который должен проверить репозиторий Fedora Commons на наличие некоторых данных в 20'000 объектах. В основном это означает отправку 20'000 HTTP-запросов на 20 000 разных URL-адресов в репозитории (который работает на сервере Tomcat).python, отправить много HTTP-запросов через одно сетевое подключение

Я написал сценарий, который выполняет задание, но администратор системы предупредил, что он открывает слишком много сетевых подключений, что вызывает некоторые проблемы.

Мой скрипт использует до сих пор urllib2 для создания HTTP-запросов.

response   = urllib2.urlopen(url) 
response_content = response.read() 

И на самом деле этот код открывает одно новое сетевое соединение для каждого запроса.

Я попытался использовать другие библиотеки для выполнения запросов, но не смог найти способ повторного использования одного и того же соединения для всех запросов. Оба решения ниже по-прежнему открывают много сетевых подключений, даже если их количество действительно ниже (на самом деле оба решения, похоже, открывают одно соединение для 100 HTTP-запросов, что в моем случае по-прежнему составляет около 200 подключений).

HTTPLIB:

url  = "http://localhost:8080/fedora/objects/test:1234?test=" 
url_infos = urlparse(url) 
conn  = httplib.HTTPConnection(url_infos.hostname + ":" + str(url_infos.port)) 

for x in range(0, 20000): 
    myurl = url + str(x) 
    conn.request("GET", myurl) 
    r = conn.getresponse() 
    response_content = r.read() 
    print x, "\t", myurl, "\t", r.status 

запросы:

url = "http://localhost:8080/fedora/objects/test:1234?test=" 
s = requests.Session() 

for x in range(0, 20000):  
    myurl = url + str(x) 
    r = s.get(myurl) 
    response_content = r.content 
    print x, "\t", myurl, "\t", r.status_code 

Даже если число подключений намного лучше, в идеале я хотел бы использовать один или очень мало соединений для всех запросов. Возможно ли это? Является ли это число 100 запросов на соединение, связанных с системой или сервером? Кстати, я также пытался сделать запросы, указывающие на сервер Apache, и результат был таким же.

+1

Мое лучшее предположение, что это связано с сервером, а не с кодом Python. Оба решения используют 'httlib.HTTPConnection' (запросы используют это под капотом), но этот класс не имеет магического номера 100 в нем. Я обвиняю серверы. – Lukasa

+0

Какую версию запросов вы используете? Из текущей версии docs: 'благодаря urllib3, keep-alive на 100% автоматический в течение сеанса! ' – brechin

ответ

3

Тот факт, что оба решения поделились каким-то кодом, как сказал Lukasa, и тот факт, что оба результата были эквивалентными, когда запрос Apache или Tomcat заставил меня сначала подумать, что он был связан с кодом Python. Но на самом деле это было связано с конфигурациями серверов.

Фокус в том, что и Apache, и Tomcat используют параметр, который указывает, сколько HTTP-запросов может быть выполнено в одном и том же TCP-соединении. И оба имеют значение по умолчанию 100.

Tomcat:

maxKeepAliveRequests: 

    The maximum number of HTTP requests which can be pipelined until the connection is closed by the server. 
    If not specified, this attribute is set to 100. 

Посмотреть http://tomcat.apache.org/tomcat-7.0-doc/config/http.html#Standard_Implementation

Apache:

MaxKeepAliveRequests: 

    The MaxKeepAliveRequests directive limits the number of requests allowed per connection when KeepAlive is on 
    Default: MaxKeepAliveRequests 100 

См http://httpd.apache.org/docs/2.2/en/mod/core.html#maxkeepaliverequests

Изменяя эти значения только очень несколько соединений могут быть созданы indee d