Создавайте новые TCP-соединения для каждого HTTP-запроса в python

Для моего проекта в колледже я пытаюсь разработать генератор трафика на основе Python. Я создал 2 машины CentOS на vmware, и я использую 1 в качестве моего клиента и 1 в качестве моей серверной машины. Я использовал метод псевдонимов IP, чтобы увеличить количество клиентов и серверов, используя только одну машину клиент/сервер. До сих пор я создал 50 псевдонимов IP на моей клиентской машине и 10 псевдонимов IP на моей серверной машине. Я также использую многопроцессорный модуль для одновременной генерации трафика со всех 50 клиентов на все 10 серверов. Я также разработал несколько профилей (1 КБ, 10 КБ, 50 КБ, 100 КБ, 500 КБ, 1 МБ) на своем сервере (в каталоге /var/www/html, так как я использую Apache Server), и я использую urllib2 для отправки запроса на эти профили из моя клиентская машина. Здесь при запуске моих сценариев, когда я отслеживаю количество TCP-соединений, оно всегда составляет ‹50. Я хочу увеличить его до 10000. Как мне этого добиться? Я подумал, что если для каждого нового http-запроса устанавливается новое TCP-соединение, то эта цель может быть достигнута. Я на правильном пути? Если не любезно указать мне правильный путь.

        '''
Traffic Generator Script:

 Here I have used IP Aliasing to create multiple clients on single vm machine. 
 Same I have done on server side to create multiple servers. I have around 50 clients and 10 servers
'''
import multiprocessing
import urllib2
import random
import myurllist    #list of all destination urls for all 10 servers
import time
import socbindtry   #script that binds various virtual/aliased client ips to the script
response_time=[]    #some shared variables
error_count=multiprocessing.Value('i',0)
def send_request3():    #function to send requests from alias client ip 1
    opener=urllib2.build_opener(socbindtry.BindableHTTPHandler3)    #bind to alias client ip1
    try:
    tstart=time.time()
    for i in range(myurllist.url):
    x=random.choice(myurllist.url[i])
    opener.open(x).read()
    print "file downloaded:",x
    response_time.append(time.time()-tstart)
    except urllib2.URLError, e:
    error_count.value=error_count.value+1
def send_request4():    #function to send requests from alias client ip 2
    opener=urllib2.build_opener(socbindtry.BindableHTTPHandler4)    #bind to alias client ip2
    try:
    tstart=time.time()
    for i in range(myurllist.url):
    x=random.choice(myurllist.url[i])
    opener.open(x).read()
    print "file downloaded:",x
    response_time.append(time.time()-tstart)
    except urllib2.URLError, e:
    error_count.value=error_count.value+1
#50 such functions are defined here for 50 clients
process=[]
def func():
    global process
    process.append(multiprocessing.Process(target=send_request3))
    process.append(multiprocessing.Process(target=send_request4))
    process.append(multiprocessing.Process(target=send_request5))
    process.append(multiprocessing.Process(target=send_request6))
#append 50 functions here
    for i in range(len(process)):
     process[i].start()
    for i in range(len(process)):
     process[i].join()
    print"All work Done..!!"
     return
start=float(time.time())
func()
end=float(time.time())-start
print end

person Bhoomika Sheth    schedule 27.03.2015    source источник
comment
Вы действительно написали (почти) один и тот же код 50 раз?   -  person Klaus D.    schedule 27.03.2015
comment
Код неполный (отступ...), но насколько я могу судить, вы создаете 50 процессов, каждый из которых выполняет 1 загрузку за раз. Если это так, очевидно, что у вас только N‹50 одновременных загрузок.   -  person Sylvain Leroux    schedule 27.03.2015
comment
И просто добавлю: есть такие инструменты, как httperf [ http://www.hpl.hp.com/research/linux/httperf/ ] для этой цели.   -  person Klaus D.    schedule 27.03.2015
comment
@Клаус Д. да, мне пришлось... потому что каждый раз, когда я использую другой IP для отправки запроса. и я не могу показать httpref как мой проект колледжа   -  person Bhoomika Sheth    schedule 27.03.2015
comment
@SylvainLeroux да, вы сказали правильно. но я как-то хочу увеличить TCP-соединения.   -  person Bhoomika Sheth    schedule 27.03.2015


Ответы (1)


Для такого рода вещей вам, вероятно, потребуется создать пул рабочих процессов. Я не знаю, будет ли жизнеспособным пул из 10000 процессов в вашем случае использования (это очень амбициозная цель), но вы должны окончательно изучить эту идею.


Основная идея пула заключается в том, что у вас есть M задач, при этом одновременно может выполняться не более N задач. Когда один из рабочих завершил свою задачу, он готов работать над другим до тех пор, пока все не будут выполнены. Одним из основных преимуществ является то, что если какое-то количество задач требует много времени для выполнения, они не будут блокировать общий ход работы (пока количество «медленных» процессов равно ‹ N).

Вдоль строк, вот основная структура вашей программы. Использование Pool:

from multiprocessing import Pool

import time
import random

def send_request(some_parameter):
    print("Do send_request", some_parameter)

    time.sleep(random.randint(1,10)) # simulate randomly long process

if __name__ == '__main__':
    pool = Pool(processes=100)

    for i in range(200):
        pool.apply_async(send_request, [i])


    print("Waiting")
    pool.close()
    pool.join()
    print("Done")

В моей системе выполнение этого примера программы заняло около 19 секунд (в реальном времени). В моей системе Debian мне удалось создать чуть более 1000 процессов за раз, прежде чем я достиг максимального количества открытых файлов (учитывая стандартное ulimit -n из 1024). Вам придется как-то поднять этот лимит, если вам нужно такое огромное количество рабочих потоков. И даже если это так, как я уже сказал, 10000 одновременных процессов, вероятно, довольно амбициозны (по крайней мере, с использованием Python).

person Sylvain Leroux    schedule 27.03.2015
comment
Но использование пула позволяет мне запускать одну и ту же функцию несколько раз, верно? здесь я хочу выполнять разные функции (все используют разные ips, хотя и выполняют одну и ту же задачу) одновременно. поэтому я избегал использования пула. Могу ли я использовать пул для выполнения различных функций? - person Bhoomika Sheth; 27.03.2015
comment
@BhoomikaSheth Пожалуйста, внимательно посмотрите на пример: вы можете передать один или несколько параметров в вызываемую функцию. Например, IP-адрес вашего хоста, или URL-адрес, или в основном все, что вы хотите. - person Sylvain Leroux; 27.03.2015
comment
Я получаю одну ошибку RuntimeError: синхронизированные объекты должны использоваться только между процессами посредством наследования при выполнении моих сценариев. - person Bhoomika Sheth; 27.03.2015
comment
если я не передам какой-либо параметр функции, то она отлично работает - person Bhoomika Sheth; 27.03.2015
comment
@Bhoomika Поскольку это явно другая проблема, вам обязательно следует задать другой вопрос, чтобы привлечь достаточно внимания и получить полезные ответы. - person Sylvain Leroux; 27.03.2015
comment
@Sylvian Leroux Я задал еще один вопрос, касающийся моей проблемы с ошибкой времени выполнения. Можете взглянуть на это один раз и направить меня дальше в правильном направлении? [stackoverflow.com/questions/29430355/ - person Bhoomika Sheth; 03.04.2015