#python-3.x #load-testing #locust
Вопрос:
У меня есть тестовый случай, в котором мне нужно создать 1000 подключений к websocket и поддерживать разговор по ним с помощью задачи Locust (для подключений к websocket предусмотрен предварительный процесс отправки/получения). Я могу успешно сделать это, выполнив следующую настройку в locust:
Максимальное количество пользователей: 1000 Частота вылупления: 1000
Однако эта настройка открывает 1000 соединений каждую секунду. Даже если я снизлю скорость вывода, наступит время, когда он будет продолжать генерировать 1000 подключений к веб-сайтам в секунду. Есть ли способ мгновенно создать 1000 пользователей и остановить/задержать рой при отправке новых 1000 подключений на довольно долгое время?
Я пытаюсь проверить, может ли мой сервер обрабатывать 1000 пользователей, отправляющих и получающих сообщения с моего сервера через соединение websocket. Я пробовал многопроцессорный подход в python, но мне трудно создавать соединения с Locust так быстро, как я могу.
пользовательское поведение класса(набор задач):
statements = [ "Do you like coffee?", "What's your favorite book?", "Do you invest in crypto?", "Who will host the Superbowl next year?", "Have you listened to the new Adele?", "Coldplay released a new album", "I watched the premiere of Succession season 3 last night", "Who is your favorite team in the NBA?", "I want to buy the new Travis Scott x Jordan shoes", "I want a Lamborghini Urus", "Have you been to the Philippines?", "Did you sign up for a Netflix account?" ] def on_start(self): pass def on_quit(self): pass @task def send_convo(self): end = False ws_url = "ws://xx.xx.xx.xx:8080/websocket" self.ws = create_connection(ws_url) body = json.dumps({"text": "start blender"}) self.ws.send(body) while True: #print("Waiting for response..") response = self.ws.recv() if response != None: if "Sorry, this world closed" in response: end = True break if not end: body = json.dumps({"text": "begin"}) self.ws.send(body) while True: #print("Waiting for response..") response = self.ws.recv() if response != None: # print("[BOT]: ", response) if "Sorry, this world closed" in response: end = True self.ws.close() break if not end: body = json.dumps({"text": random.choice(self.statements)}) start_at = time.time() self.ws.send(body) while True: response = self.ws.recv() if response != None: if "Sorry, this world closed" not in response: response_time = int((time.time() - start_at)*1000) print(f"[BOT]Response: {response}") response_length = len(response) events.request_success.fire( request_type='Websocker Recv', name='test/ws/echo', response_time=response_time, response_length=response_length, ) else: end = True self.ws.close() break if not end: body = json.dumps({"text": "[DONE]"}) self.ws.send(body) while True: response = self.ws.recv() if response != None: if "Sorry, this world closed" in response: end = True self.ws.close() break if not end: time.sleep(1) body = json.dumps({"text": "EXIT"}) self.ws.send(body) time.sleep(1) self.ws.close() class WebsiteUser(HttpUser): tasks = [UserBehavior] wait_time = constant(2) host = "ws://xx.xx.xx.xx:8080/websocket"
Для этого конкретного теста я установил максимальное количество пользователей 1
и скорость вывода 1
, и, очевидно, locust продолжает отправлять 1 запрос в секунду, как видно из следующих ответов:
[BOT]Response: {"text": "No, I don't have a netflix account. I do have a Hulu account, though.", "quick_replies": null} enter code here [BOT]Response: {"text": "I have not, but I would love to go. I have always wanted to visit the Philippines.", "quick_replies": null [BOT]Response: {"text": "No, I don't have a netflix account. I do have a Hulu account, though.", "quick_replies": null} [BOT]Response: {"text": "I think it's going to be New Orleans. _POTENTIALLY_UNSAFE__", "quick_replies": null}
Я ожидаю, что после того, как я установлю максимальное число пользователей равным 1, и скорость штриховки 1, мгновенно возникнет 1 соединение websocket, отправляющее случайное сообщение и получающее 1 основной ответ от сервера websocket. но что происходит, так это то, что он продолжает повторяться task
в секунду, пока я явно не нажму кнопку «Стоп» на панели управления locust.
Комментарии:
1. Пожалуйста, добавьте свой файл locustfile. Помните, что скорость штриховки важна только для увеличения, это не имеет значения, как только все пользователи запущены.
2. Я имею в виду, что если можно установить максимальное количество пользователей на 1000, и саранча отправит сообщение только один раз всем мгновенно и «приостановит» отправку следующей партии из 1000, так как по умолчанию она будет отправлять еще 1000 каждую секунду. Причина, по которой такая настройка, заключается в том, что у меня есть цикл внутри этих сообщений от locust, и я выполняю там некоторые вычисления. Мне нужно проверить, может ли мой сервер обрабатывать 1000 текущих вычислений одновременно. не 1000 вычислений в секунду.
3. Причина, по которой @cyberwiz просит посмотреть код, заключается в том, что количество пользователей должно быть максимальным, когда Саранча появляется, а не в том, что она делает каждую секунду. Пока пользователь продолжает выполнять работу, Саранча не должна порождать другую. Таким образом, в вашем коде может быть что-то, что мешает Саранче думать, что пользователи выполняют непрерывную работу после того, как они появились. Мы не можем помочь с этим, не увидев кода.
4. Спасибо @Solowalker Я обновил вопрос, чтобы опубликовать файл саранчи и проблему, с которой я столкнулся. похоже, что тест на саранчу, который я провожу, повторяет эту задачу каждую секунду. Исходя из вашего комментария, у меня должен был быть один вывод, так как 1 максимальный пользователь с частотой штриховки 1 отправит максимум 1 выполнение задачи.
5. Прочитав это и ваши комментарии еще раз, я отредактировал свой ответ. Если это все еще не то, что вы ищете, пожалуйста, продолжайте уточнять.
Ответ №1:
Я бы отладил вашу логику. Поместите больше print
операторов в каждый if
блок в разных местах и между каждым блоком. Когда имеешь дело с длинным списком решений, легко запутаться.
В этом случае вы хотите этого только sleep
в очень конкретной ситуации, но этого не происходит. Скорее всего, вы настраиваетесь end = True
, когда не ожидаете этого, поэтому вы не спите и сразу же получите нового пользователя.
ПРАВКА: Еще раз просмотрев ваш вопрос и описание проблемы, похоже, вы ожидаете, что Locust отправит один запрос, а затем никогда не отправит другой. Саранча так не работает. Locust запустит код вашей задачи для пользователя. Когда это сделано, этот пользователь уходит и ждет определенное время (похоже, у вас оно установлено на 2 секунды), а затем он порождает другого пользователя и запускает задачу снова. Идея в том, что он будет стараться поддерживать почти постоянное количество пользователей, которым вы его сообщаете. Он не будет запускать только 1000 пользователей, а затем завершит тест по умолчанию.
Если вы хотите, чтобы все 1000 пользователей работали, вам нужно заставить их продолжать выполнять код. Например, вы могли бы поместить все в своей задаче в другой while
цикл с другим способом выхода и завершения. Таким образом, даже после подключения к сокету и отправки единственного сообщения, которое вы ожидаете, пользователь останется в живых в цикле и не закончится, потому что у него закончились дела. Выполнение этого таким образом требует гораздо больше работы и координации, но возможно. Могут возникнуть другие вопросы по SO о различных подходах, если это не совсем то, что вы ищете.
Комментарии:
1. Спасибо, это ответило на мою озабоченность. Я хотел подтвердить, действительно ли Саранча выполняет запрос в секунду, и вы это подтвердили.