Webdriver в тяжелых условиях / java.net.BindException

Хей гайз
Я пишу на java приложение, которое использует webdriver для того чтобы сидеть на сайте со многих аккаунтов сразу. Для каждого аккаунта используется отдельный экземпляр chromedriver’а, который сидит онлайн и с очень небольшим интервалом (100-500 мс) опрашивает целевую страницу.

Вначале я использовал для каждого аккаунта отдельный экземпляр хромдрайвера, как только количество аккаунтов (драйверов) увеличилось до 5-7, производительности стало не хватать, хромдрайвер начинал сыпать эксепшны.

Я перешел на ChromeDriverService, и это позволило увеличить количество одновременно работающих драйверов до 10-15. Но через время (~10 мин) ChromeDriverService тоже сыпет экспешены. Чаще всего вот такой:

java.net.BindException caught when processing request to {}->http://localhost:15849: Address already in use: connect

Судя по всему ексепшены сыпятся из-за того что ChromeDriverService не может хендлить так много запросов, хотя машина загружена на 60% а не на 90-100

Если перевести приложение на Selenium Grid, позволит ли это решить проблему производительности?

Кто-нибудь сталкивался с похожими проблемами?

Зачем вам для этой задачи Selenium?
Почему бы просто не воспользоваться прямыми HTTP запросами?

3 лайка

Потому что там ко всему прочему ещё нужно вебкамеру стримить через флеш-плагин

Это говорит этом что порт занят. Сделайте try. catch для переконекта и все будет норм. Ещепопробуйте рандомно указывать порт из выделенного пула.

1 лайк

ChromeDriverService использует один порт, о чем сообщает при старте, и все экземпляры драйвера, которые через него создаются, используют этот же порт.
Давайте проиллюстриуем процесс подробнее:

//создаём экземпляр драйвер-сервиса
ChromeDriverService chromeService = new ChromeDriverService.Builder().usingChromeDriverExecutable(new File(getChromeLocation())).usingAnyFreePort().build();
chromeService.start();

после вызова метода start() в консоли появляется стандатный месседж запуска драйвера:
типа такого: Starting ChromeDriver 2.27.440174 (…) on port 31409

Теперь у нас в системе стартовал экземпляр хромдрайвера (chromedriver.exe), в диспетчере его видно. Далее мы из сервиса делаем экземпляры объектов-драйверов:

WebDriver driver = new ChromeDriver(chromeDriverService,options);

После вызова такого метода создаётся браузер. При этом, дополнительные экзепляры chromedriver.exe в системе не стартуют. Таких объектов можно делать множество, все они будут использовать один процесс chromedriver.exe. На основании этого я предполагаю, что порт тоже используется один.

В контексте всего вышеперечисленного, не совсем понимаю о каком порте идёт речь, когда мы предполагаем, что порт занят, как он может быть занят для самого себя?

Ко всему прочему, эксепшен выдаётся не джавой, а самим хромдрайвером, который просто показывает его в том же потоке stderr, поэтому try {} catch его не детектит и я пока не знаю как его можно отловить.

ChromeDriver работает с Chrome, скорее всего тоже, через сокет. скорее всего проблема там, для каждого экземпляра хрома свой коннект. (Я не уверен на 100%) Не смог найти именно про хром, там драйвера для браузеров везде по разному работают. JsonWireProtocol

1 лайк

Очень хитрая задача!

Боюсь по теме я не могу ответить, но очень хочется спросить были ли попытки запускать браузеры в гриде? Например можно попытатся даже задокеризировать все?

Мне кажется для дальнейшего масштабирования без грида не обойтись - ресурсы любого тазика не безграничны

1 лайк

Сергей,
не сочтите за троллинг, но у меня для вас вот такой ответ:

Серьёзно. 15 сессий? С вебкамерой? Стримингом видео?

Зачем вам всё это???

Займитесь чем-нибудь полезным!

5 лайков

Кстати да, зачем эта война с камерами, юзерами, браузерами?

Я на своем проекте включил эту заглушку и горя не знал ( через capabilities )
https://blog.andyet.com/2014/09/29/testing-webrtc-applications/

To get around all that manual testing, we want to run these tests on servers and machines that don’t have any webcams and microphones attached. Fortunately, this is pretty easy to achieve because the browser manufacturers provide special ways to simulate webcams and microphones for testing purposes. In Chrome, this is done by adding --use-fake-device-for-media-stream as a command line argument when starting the browser. In Firefox, a special fake:true variable in the getUserMedia calls needs to be set (as explained here).

Since we don’t want user interaction, we also need to do something similar for skipping the security prompt. In Chrome, that is achieved with the --use-fake-ui-for-media-stream flag; in Firefox, this is done with by setting a preference of media.navigator.permission.disabled:true.

1 лайк

лол
господа спасибо за поддержку, но я уже упоминал что:

пишу на java приложение, которое использует webdriver для того чтобы сидеть на сайте со многих аккаунтов сразу

а ерунда это или нет, смогу сказать разве что после релиза

Оу, оу.
Разве человек, строящий дом, не должен изначально понимать, что он строит?
Разве человек, наматывающий бинт, не должен изначально понимать, зачем он его наматывает?
Разве повар, смешивающий соль и воду, не должен изначально понимать, зачем он их смешивает?

То есть вы тратите бесценные часы, дни и месяцы своей жизни, даже не знаю, ерунда это или нет???

Серьёзно. 15 сессий? С вебкамерой? Стримингом видео?

Абсолютно серьезно и даже не бесплатно трачу свои бесценные часы на разработку подобного софта, спасибо.

Боюсь по теме я не могу ответить, но очень хочется спросить были ли попытки запускать браузеры в гриде?

Пока не было, но на днях планировал провести тест грида.

Кстати да, зачем эта война с камерами, юзерами, браузерами?

Это задача не из области QA а в целом по автоматизации, дальше уже не расскажу из-за NDA.

Ну без грида вам не обойтись, с ним вам будет чуть проще держать много браузеров “онлайн”… дичь конечно этот род деятельности, но всё же походу реально надо)))

Воу Воу Андрей, полехче)) ещё пара таких фраз и я работу пойду менять))

:slight_smile:

На любой другой работе будет точно такая же проблема.