Когда следует использовать один экземпляр сеанса для запросов? - PullRequest
0 голосов
/ 12 ноября 2018

Из aiohttp документов:

[An aiohttp.ClientSession] инкапсулирует пул соединений (экземпляр соединителя) и поддерживает сообщения активности по умолчанию. Если вы не подключаетесь к большому, неизвестному количеству различных серверов в течение срока службы вашего приложения, рекомендуется использовать один сеанс в течение всего срока службы вашего приложения, чтобы воспользоваться пулами соединений.

Я почти всегда использовал практику хранения одного экземпляра ClientSession (с включенными файлами cookie и настраиваемым соединителем / адаптером *) для любого размера или контейнера URL-адресов, независимо от того, насколько неоднородны эти URL-адреса или сколько их имеются. Я хотел бы знать, есть ли недостатки этого подхода.

Я надеюсь получить более детальное, контекстуальное определение того, что "большое, неизвестное количество различных серверов" составляет на практике. Каковы лучшие практики для случаев, подобных представленному ниже? Должен ли ClientSession выделяться каждому netloc, а не одному экземпляру для всего набора? ** Решение о том, использовать ли один сеанс клиента, определяется исключительно временем ответа?

Часто бывает, что у меня есть "партии" конечных точек; netloc для каждой партии однороден, но netloc между партиями разные. Например,

urls = {
    'https://aiohttp.readthedocs.io/en/stable/index.html',
    'https://aiohttp.readthedocs.io/en/stable/client_reference.html',
    'https://aiohttp.readthedocs.io/en/stable/web_advanced.html#aiohttp-web-middlewares',

    'https://www.thesaurus.com/',
    'https://www.thesaurus.com/browse/encapsulate',
    'https://www.thesaurus.com/browse/connection?s=t',

    'https://httpbin.org/',
    'https://httpbin.org/#/HTTP_Methods',
    'https://httpbin.org/status/200'
}

Чтобы обозначить число, в действительности каждая партия, вероятно, имеет длину 25-50.


* Что я сделал сейчас, так это ограничил количество открытых соединений для любого отдельного хоста, передав экземпляр соединителя в ClientSession, то есть aiohttp.TCPConnector(limit_per_host=10).

** В частности, {'www.thesaurus.com', 'aiohttp.readthedocs.io', 'httpbin.org'}, т.е. set(urllib.parse.urlsplit(u).netloc for u in urls).

1 Ответ

0 голосов
/ 12 ноября 2018

Вы хотите использовать выделенный сеанс со своим собственным соединителем, когда

  1. Вы хотите настроить параметры соединителя для набора соединений (скажем, изменить ограничение для каждого хоста или изменитьКонфигурация SSL или установка других тайм-аутов).
  2. Вы бы выполнили ограничение в 100 соединений по умолчанию, при котором кэшированные соединения с существующими хостами с такой же вероятностью были бы перезапущены, как и все еще открытыми.

Последний сценарий - это то, на что намекает документация.Скажем, у вас есть большее количество уникальных хостов для подключения (где уникальный хост представляет собой уникальную комбинацию имени хоста, номера порта и того, используется ли SSL), но с некоторыми из этих хостов связываются большечасто, чем другие.Если это «большое число»> 100, то есть вероятность, что вам придется продолжать открывать новые соединения для «частых» хостов, к которым вы уже подключались ранее, потому что пул должен был закрыть их, чтобы создать соединение для хоста, который в данный момент не подключен.бассейн.Это ухудшит производительность.

Но если вы создали отдельный пул для «частых» хостов, то вы можете держать эти соединения хоста открытыми гораздо дольше.Им не нужно конкурировать за бесплатные соединения из пула «общего пользования» со всеми этими нечастыми соединениями с хостами.

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

Для сравнения, библиотека requests (синхронный HTTP API) обрабатывает это немного по-другому, где вы можете зарегистрировать отдельные транспортные адаптеры для каждого префикса URL .

...