Назад | Перейти на главную страницу

PHP медленнее, чем должен быть

У меня есть сервер с Dual Xeon Quad Core L5420, работающий на частоте 2,5 ГГц. Я оптимизировал свой сервер и пришел к моему последнему узкому месту: PHP.

Мой очень простой скрипт PHP:

./test.php

<?php print_r(posix_getpwuid(posix_getuid()));

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

./benchmark-php

#!/bin/bash
if [ -z $1 ]; then
  LIMIT=10
else
  LIMIT=$1
fi

if [ -z $2 ]; then
  SCRIPT="index.php"
else
  SCRIPT=$2
fi

START=$(date +%s.%N)
COUNT=0
while (( $COUNT < $LIMIT ))
do
  php $SCRIPT > /dev/null
  COUNT=$(echo "$COUNT + 1" | bc)
done
END=$(date +%s.%N)
DIFF=$(echo "$END - $START" | bc)
REQS_PER_SEC=$(echo "scale=2; $COUNT / $DIFF" | bc)
echo $REQS_PER_SEC

./really-benchmark-php

#!/bin/bash
if [ -z $1 ]; then
  LIMIT=10
else
  LIMIT=$1
fi

if [ -z $2 ]; then
  THREADS=16
else
  THREADS=$2
fi

if [ -z $3 ]; then
  SCRIPT="index.php"
else
  SCRIPT=$3
fi

PIDS=""

echo '' > results
for thread in `seq 1 $THREADS`; do
  ./benchmark-php $LIMIT $SCRIPT >> results &
  PIDS="$PIDS $!"
done

for PID in $PIDS; do
  wait $PID
done

RESULTS=`cat results`
MATH="0"
for RESULT in $RESULTS; do
  MATH="$MATH + $RESULT"
done

echo "$MATH" | bc

Результат бега ./really-benchmark-php 100 8 test.php составляет ~ 137 запросов в секунду.

Выполнение того же сценария на экземпляре Drupal на базе sqlite или mysql возвращает ~ 1,5 запросов / с.

У меня установлены APC и mem_cache, и я убедился, что они работают по умолчанию. (Да, APC enable_cli тоже включен.) Кто-нибудь знает волшебный переключатель «заставить PHP выполняться быстрее»?

У меня есть альтернативная конфигурация (FPM / FastCGI), которая обслуживает ~ 140 запросов / с установки MySQL Drupal ... как это может быть возможно, если сам PHP не может даже обслуживать 2 запроса / с из командной строки?

Результат ab инструмент мне кажется таким же низким:

статическая страница: ab -n 1000 -c 100 http://x.x.x.x/ Запросов в секунду: 683.71

тестовый php: ab -n 100 -c 5 http://x.x.x.x/ Запросов в секунду: 41.38

drupal-mysql: ab -n 100 -c 10 http://x.x.x.x/drupal/ Запросов в секунду: 0,24

drupal-sqlite: ab -n 100 -c 10 http://x.x.x.x/drupal-test/ Запросов в секунду: 4.92

Если вы запускаете PHP из командной строки, каждый запуск должен загружать весь интерпретатор PHP, все необходимые библиотеки, файлы и т. Д. Это имеет огромные накладные расходы.

Если ваш веб-сервер настроен на то же самое, то магия «ускорить переключение PHP», вероятно, переключается на использование mod_php, FastCGI или что-то подобное, что позволяет одному интерпретатору PHP обслуживать несколько запросов. (Обратите внимание, что каждый интерпретатор может обслуживать только один запрос одновременно; ответственность за запуск нескольких интерпретаторов PHP лежит на вашем веб-сервере для mod_php или что-то еще, что запускает вашу вещь FastCGI.)