ipadm
@ipadm

IIS, php, w3wp.exe, cmd.exe и многопоточность? заставить не залипать процессы?

Хабрасообщесту Хабрапривет!


Возникла проблема при реализации довольно простой задачи. На сайте из PHP генерируется PDF из разных файлов, в том числе и созданных на лету с помощью TCPDF. Все эти файлы соединяются в разном порядке и отправляются на разные почтовые ящики. Операции объединения выполняются через passthru() вызов PDFTK.


Все замечательно работает если вызывать (обращаться к странице) один раз.


Но если происходит одновременное обращение двух и более пользователей к странице, то процесс cmd.exe залипает и не завершает свою работу. Точнее он выполняет все что должен, но просто не завершается и так и висит в памяти, не давая продолжить выполнение PHP скрипта. Таким образом в памяти может залипнуть несколько процессов:


w3wp.exe

cmd.exe

pdftk.exe

cmd.exe

pdftk.exe

cmd.exe

pdftk.exe

cmd.exe

pdftk.exe

cmd.exe

pdftk.exe



cmd.exe

pdftk.exe


убить которые можно только убив процесс w3wp.exe. Такая картина наблюдается только в Windows (а конкретно Win2003k server). Под Linux тот же скрипт выполняется с нагрузкой до 100 одновременных вызовов без проблем (больше нагрузку не пробовал, т.к. больше не ожидается по ТЗ).


К сожалению я привязан к использованию PDFTK т.к. чистых PHP классов, которые бы не убивали ссылки внутри PDF обнаружить не удалось.


Прошу помочь любым советом.
  • Вопрос задан
  • 5692 просмотра
Пригласить эксперта
Ответы на вопрос 4
Altimar
@Altimar
Если не страшно, что в PDF в углу первой страницы будет буква P (которая не видна при печати) — переезжайте с TCPDF на PrinceXML ( www.princexml.com/ ). Из всех рассмотренных мной генерилок PDF эта оказалась самой правильной. Он же склеивает несколько HTML в один PDF. И памяти жрет очень скромно в сравнении с остальными.
Раньше на винде крутилось — проблем не было.

Возможно проблема в реализации pdftk.exe, который пытаясь одновременно считать из 2 одинаковых файлов где-то лочится
Ответ написан
foxmuldercp
@foxmuldercp
Системный администратор, программист, фотограф
Первое — я бы попробовал отдебажить процесс воткнув где только можно вывод отладочной инфрмации с привязкой к сеансу клиента (клиент а, клиент б, клиент с) и времени выполнения команды и времени, которое эта команда выполнялась, может это поможет разобраться.

Второе — перейти с cmd на powershell не составит большого труда, а писать скрипты на нём — одно удовольствие объектного .Net языка с широкими возможностями отладки.
С PHP не подскажу, да, я в нём не силён, но что-то мне подсказывает что проблема не в нём.

Если так уже нужен сайт под Win в принципе при наличии ТЗ его можно реализовать нс C# + Asp.Net и MVC, нативно и без геморроя, с этим я тоже могу попробовать помочь, в общем.
Ответ написан
@rPman
Выглядит, как будто процессы где то обращаются к общему ресурсу и ждут его освобождения (какой-нибудь кривой метод реализации очереди), выше уже посоветовали тщательно отладить и выявить где именно в коде образуется затык, обычным подробным логированием.

Переложить весь код генерации в отдельный процесс, запускаемый вне сессии IIS (отдельным сервисом или даже standalone приложением) на том же php через какую-либо простенькую очередь, а вебсерверу оставить задачу — поместить задание в очередь, ждать его завершения, отдать результат.

Достоинство такого разделения — более полный контроль над нагрузкой (процесс, обрабатывающий задания в очереди может быть многопотоковым) и самое главное, он будет запускаться в контексте обычного приложения без каких-либо внутренних особенностей и глюков, которые порождает IIS (ведь вы же сами показали что только под IIS возникает проблема).

И главное, переписывать ничего не придется, фактически только добавить очередь задач и ее обработку.
Ответ написан
Denisio
@Denisio
Генерируйте PDF в отдельном сервисе. Запускать внешний софт из внутренностей IIS — очень плохая идея.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы