Какую библиотеку Python мне следует использовать? SocketServer или Asyncio?

#python #python-asyncio #socketserver

#python #python-asyncio #socketserver

Вопрос:

Я собираюсь создать веб-сервер, который мог бы получать много подключений. Эти 10000 подключенных пользователей отправят на сервер номера, и сервер вернет эти квадратные числа пользователям обратно. 10000 подключений — это слишком много, и здесь уместен асинхронный подход. Я нашел две библиотеки для Python 3.4, которые могут помочь:

socketserver и asyncio

С библиотекой socketserver мы можем использовать классы ThreadingMixIn и ForkingMixIn в качестве асинхронных обработчиков. Но это ограничено количеством ядер. С другой стороны, у нас есть библиотека asyncio. И я не понимаю, как именно это работает. Какую из них мне следует использовать? И могут ли эти две библиотеки работать вместе?

Ответ №1:

Существуют разные подходы к асинхронному программированию.

Первый подход заключается в мониторинге операций ввода-вывода с использованием потоков и управлении этими операциями неблокирующим образом. Это то, что SocketServer делает.

Второй подход заключается в мониторинге операций ввода-вывода в главном потоке с использованием цикла событий и селектора. Обычно это то, что люди имеют в виду, когда говорят об асинхронном программировании, и именно это asyncio , twisted и gevent делают.

Однопоточный подход имеет два преимущества:

  • это ограничивает риск состояния гонки, поскольку обратные вызовы выполняются в том же потоке
  • это избавляет от накладных расходов на создание одного потока для каждого клиента (см. Проблему 10K)

Вот пример сервера asyncio TCP. В вашем случае просто замените handle_echo сопрограмму своей собственной реализацией:

 async def handle_client(reader, writer):
    data = await reader.readline()
    result = int(data.decode().strip()) ** 2
    writer.write(str(result)).encode())
    writer.close()
  

Она должна легко справляться с тысячами клиентов.

Комментарии:

1. Вы упомянули модуль selectors . В чем преимущество использования селекторов непосредственно для сервера сокетов, как в примере, который они показывают по ссылке?

2. @Jay Упомянутый вами пример интересен в том смысле, что он показывает, как можно написать TCP-сервер, который обслуживает несколько клиентов одновременно в одном потоке, используя селектор и некоторые обратные вызовы. На практике гораздо проще использовать asyncio, как показано в этом другом примере TCP-сервера .

3. Итак, asyncio реализует что-то подобное под капотом? Означает ли это, что selectors работает быстрее, поскольку он находится на более низком уровне абстракции?

4. @Jay Да, это так . Но подход с использованием простого селектора не обязательно быстрее для таких программ, поскольку большая часть времени обычно тратится на ожидание ввода-вывода. Кроме того, вы все еще можете подключить uvloop к asyncio для повышения производительности.