Общие / объединенные подключения к внутренним службам в PHP

#php #performance #web-services #caching #connection-pooling

#php #Производительность #веб-сервисы #кэширование #объединение в пул соединений

Вопрос:

Я пытаюсь найти наилучший способ минимизировать использование ресурсов, когда PHP взаимодействует с различными внутренними службами (например, Amazon S3 или любыми другими случайными веб-службами — я бы хотел общее решение). В идеале я хотел бы иметь одно постоянное соединение с серверной частью (или, возможно, небольшой пул постоянных соединений) с некоторым кэшированием, а затем, чтобы все задачи PHP совместно использовали его. Мы можем рассматривать все это только для чтения для целей этого вопроса. Для меня не очевидно, как это сделать в PHP. Есть специфичный для базы данных материал, такой как mysql_connect(), но на самом деле это не подходит для меня.

У меня появилась одна идея, которая кажется несколько неоптимальной (но все же лучше, чем заставлять каждый отдельный запрос создавать и уничтожать новое соединение), — использовать локальный кэширующий прокси (в отдельном процессе), который эффективно выполнял бы объединение в пул и кэширование. PHP по-прежнему будет открывать и закрывать соединение для каждого запроса, но, по крайней мере, это будет связано с локальным процессом, так что это должно быть немного быстрее (и это снизило бы нагрузку на серверные части). Но не похоже, что такое сумасшествие должно быть необходимым. Должен быть способ получше. Это легко сделать на других языках. Пожалуйста, скажите мне, чего мне не хватает!

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

1. Спасибо за ответы. Хотя я, возможно, не получу огромной выгоды от кэширования соединения, я думаю, что я все еще могу извлечь выгоду из кэширования данных. Мое приложение состоит из веб-страницы, на которой отображается регулярно обновляемый список событий, которые были записаны во внутреннем хранилище (будь то S3, MySQL или что-то еще). Каждый клиент будет регулярно получать доступ к веб-серверу для получения последних событий. Представьте 10 серверов с 1000 клиентами на каждом. Без кэширования это приведет к 10 тыс. запросов при каждом их обновлении. При кэшировании это приводит к 10 запросам. Мне кажется, это большая разница.

Ответ №1:

Существует большой идеологический разрыв между различными веб-технологиями. Некоторые из них, по сути, являются демонами, которые работают полный рабочий день в фоновом режиме и обрабатывают запросы, передаваемые самостоятельно. Поскольку процесс всегда запущен, у вас может быть пул уже открытых существующих рабочих подключений.

В PHP (и обычных CGI-скриптах) нет демона за кулисами. Каждый раз, когда поступает запрос, интерпретатор PHP запускается с чистого листа, компилирует скрипты и запускает байт-код. Постоянства нет. Функции базы данных PHP, которые поддерживают постоянные соединения, устанавливают соединение на дочернем уровне веб-сервера (т.е. mod_php, подключенный к процессу Apache). Это не совсем пул соединений, поскольку вы можете видеть только постоянное соединение, подключенное к вашему собственному процессу.

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

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

Прежде чем вы подумаете о написании собственного демона на основе PHP для обработки подобных вещей, имейте в виду, что это, возможно, уже решаемая проблема. Python придумал нечто, называемое WSGI, с аналогичной реализацией в Ruby под названием Rack. В Perl также есть что-то удивительно похожее, но я не могу вспомнить его название сразу. Быстрый просмотр Google не показал никаких реализаций WSGI на PHP, но это не значит, что их не существует…

Ответ №2:

Поскольку S3 и другие веб-сервисы используют HTTP в качестве своего транспорта, вы не получите значительной выгоды от кэширования соединения.

  • Хотя вы можете использовать API, который, по-видимому, выполняет аутентификацию в качестве первого шага, глядя на документацию S3, аутентификация выполняется с каждым запросом, поэтому нет никакой пользы в однократной аутентификации и повторном использовании соединения
  • Запросы веб-службы по протоколу HTTP являются легковесными и обычно не имеют состояния. После того, как на ваш запрос получен ответ, никакие ресурсы (соединение или состояние сеанса) на сервере не используются. Это позволяет разработчику веб-службы использовать множество компьютеров для ответа на ваш запрос, не привязывая ресурсы к определенному серверу