5 August 2014

Сессии в PHP — подводный камушек при асинхронных запросах

AjaxPHPJavaScript
Небольшая предыстория.

У меня есть хобби-проект трекер.ру
Алгоритм такой: пользователь вводит поисковый запрос, этот запрос «на лету» ищет торренты на сторонних трекерах (рутор, рутрекер, tfile и тд).
Для параллельного поиска идет одновременно несколько аякс запросов, которые должны обработаться асинхронно.
Однако, запросы выполнялись синхронно. Если какой-то трекер долго не отдавал ответ, то остальные запросы подвисали и ждали ответа от подвисшего трекера. Общее время выполнение запросов равнялось сумме всех запросов. Хотя, по моим планам общее время должно было равняться самому долгому запросу.
Долго ломал голову, почему так. Грешил на HTTP pipelining. Но, причина оказалась намного банальней. Все дело в сессиях. Дело в том, что сессии в php консистентны и php не даст обратиться другому процессу к уже занятой сессии.

Потыкать и полюбоваться результатом можно тут. Посмотрите на общее время с сессиями и без.

Чем это плохо:

Если сайт тормозит, то при открытии нескольких вкладок этого сайта, вкладки будут загружаться по очереди.
Если у вас контент подгружается множеством ajax запросов — то они будут выполняться тоже по очереди.

Как лечить?

Изменение хандлеров сессии не поможет. в комментах поправили, что это не так.
Как вариант — (об этом уже писали на хабре) в быстром участке кода воспользоваться сессией, а потом выполнить session_write_close();
Tags:php sessionphpjavascriptajaxsession_write_close
Hubs: Ajax PHP JavaScript
+9
19.1k 159
Comments 21