Производительность Drupal file_scan_directory/opendir занимает более 500 мс

После профилирования экземпляра drupal7.34 с использованием XHProf я вижу, что функция opendir, вызываемая file_scan_dir, которая возвращается на 15 глубину, занимает много времени. file_scan_dir в свою очередь вызывается drupal_system_listing (3 вызова)

Function   Calls  Ex Wall  Wall %
opendir    1608   500ms    27%
ob_flush   1      270ms    17%
is_dir     10,872 107ms     7%
preg_match 20,597  85ms     5%

Основные настройки

**php.ini (PHP5.3.3)**
memory_limit = 512MB
realpath_cache_size = 1024k
max_execution_time = 90

**apc.ini**
apc.shm_size=192M  (free 100MB after several loads)
apc.stat=1
apc.stat_ctime=0

Файлы drupal находятся в файловой системе NFS, поэтому я ожидаю, что она будет немного медленной. Когда я изменяю apc.stat=0 и перезапускаю apache. Я ожидал, что издержки opendir исчезнут, так как большинство файлов будут считываться из opcache, но эти числа не меняются вообще после многих перезагрузок одной и той же страницы.

Я проверил, что у меня нет отсутствующих модулей, что является известной проблемой с drupal 7. Тем не менее, похоже, что drupal ищет какой-то отсутствующий файл.

Есть идеи, что может быть причиной этой проблемы?

1 ответ

Решение

Я нашел проблему, временно добавив dpm(func_get_args()); в bootstrap.inc, как описано здесь /questions/2187230/pomestite-protsess-v-pesochnitsu-gde-on-mozhet-nanesti-naimenshij-vred/2187245#2187245

Оказалось, что тема AT-Commerce версии 7.x-3.0, которая не проверяет должным образом другие дополнительные модули, вызывает серьезное снижение производительности.

Исправление сэкономило более 900 мс при каждой загрузке страницы, что имеет большое влияние

Я предоставил предлагаемое исправление для модуля drupal https://www.drupal.org/node/2406089 Перечислите его здесь для полноты

  /**
  * Implements hook_css_alter().
  */
 function at_commerce_css_alter(&$css) {
   // Replace all Commerce module CSS files with our own for total control over all        styles.
   // Commerce module uses the BAT CSS file naming convention (base, admin, theme).
   $path = drupal_get_path('theme', 'at_commerce');


   // cart
   if (module_exists('commerce_cart')){
       $cart_theme = drupal_get_path('module', 'commerce_cart') . '/theme/commerce_cart.   theme.css';
       if (isset($css[$cart_theme])) {
         $css[$cart_theme]['data'] = $path . '/css/commerce/commerce_cart.theme.css';
         $css[$cart_theme]['group'] = 1;
       }
   }


   // checkout
   if (module_exists('commerce_checkout')){
       $checkout_base  = drupal_get_path('module', 'commerce_checkout') . '/theme/         commerce_checkout.base.css';
       $checkout_admin = drupal_get_path('module', 'commerce_checkout') . '/theme/         commerce_checkout.admin.css';
       $checkout_theme = drupal_get_path('module', 'commerce_checkout') . '/theme/         commerce_checkout.theme.css';
       if (isset($css[$checkout_base])) {
         $css[$checkout_base]['data'] = $path . '/css/commerce/commerce_checkout.base.     css';
         $css[$checkout_base]['group'] = 1;
       }
       if (isset($css[$checkout_admin])) {
         $css[$checkout_admin]['data'] = $path . '/css/commerce/commerce_checkout.admin.   css';
         $css[$checkout_admin]['group'] = 1;
       }
       if (isset($css[$checkout_theme])) {
         $css[$checkout_theme]['data'] = $path . '/css/commerce/commerce_checkout.theme.   css';
         $css[$checkout_theme]['group'] = 1;
       }
   }


   // customer
   if (module_exists('commerce_customer')){
       $customer_admin = drupal_get_path('module', 'commerce_customer') . '/theme/         commerce_customer.admin.css';
       if (isset($css[$customer_admin])) {
         $css[$customer_admin]['data'] = $path . '/css/commerce/commerce_customer.admin.   css';
         $css[$customer_admin]['group'] = 1;
       }
   }


   // file (contrib)
   if (module_exists('commerce_file')){
       $file_forms = drupal_get_path('module', 'commerce_file') . '/theme/commerce_file.   forms.css';
       if (isset($css[$file_forms])) {
         $css[$file_forms]['data'] = $path . '/css/commerce/commerce_file.forms.css';
         $css[$file_forms]['group'] = 1;
       }
   }


   // line items
   if (module_exists('commerce_line_item')){
       $line_item_admin = drupal_get_path('module', 'commerce_line_item') . '/theme/       commerce_line_item.admin.css';
       $line_item_theme = drupal_get_path('module', 'commerce_line_item') . '/theme/       commerce_line_item.theme.css';
       if (isset($css[$line_item_admin])) {
         $css[$line_item_admin]['data'] = $path . '/css/commerce/commerce_line_item.admin. css';
         $css[$line_item_admin]['group'] = 1;
       }
       if (isset($css[$line_item_theme])) {
         $css[$line_item_theme]['data'] = $path . '/css/commerce/commerce_line_item.theme. css';
         $css[$line_item_theme]['group'] = 1;
       }
   }


   // order
   if (module_exists('commerce_order')){
       $order_admin = drupal_get_path('module', 'commerce_order') . '/theme/               commerce_order.admin.css';
       $order_theme = drupal_get_path('module', 'commerce_order') . '/theme/               commerce_order.theme.css';
       if (isset($css[$order_admin])) {
         $css[$order_admin]['data'] = $path . '/css/commerce/commerce_order.admin.css';
         $css[$order_admin]['group'] = 1;
       }
       if (isset($css[$order_theme])) {
         $css[$order_theme]['data'] = $path . '/css/commerce/commerce_order.theme.css';
         $css[$order_theme]['group'] = 1;
       }
   }


   // payment
   if (module_exists('commerce_payment')){
       $payment_admin = drupal_get_path('module', 'commerce_payment') . '/theme/           commerce_payment.admin.css';
       $payment_theme = drupal_get_path('module', 'commerce_payment') . '/theme/           commerce_payment.theme.css';
       if (isset($css[$payment_admin])) {
         $css[$payment_admin]['data'] = $path . '/css/commerce/commerce_payment.admin.     css';
         $css[$payment_admin]['group'] = 1;
       }
       if (isset($css[$payment_theme])) {
         $css[$payment_theme]['data'] = $path . '/css/commerce/commerce_payment.theme.     css';
         $css[$payment_theme]['group'] = 1;
       }
   }


   // price
   if (module_exists('commerce_price')){
       $price_theme = drupal_get_path('module', 'commerce_price') . '/theme/               commerce_price.theme.css';
       if (isset($css[$price_theme])) {
         $css[$price_theme]['data'] = $path . '/css/commerce/commerce_price.theme.css';
         $css[$price_theme]['group'] = 1;
       }
   }


   // product
   if (module_exists('commerce_product')){
       $product_admin = drupal_get_path('module', 'commerce_product') . '/theme/           commerce_product.admin.css';
       $product_theme = drupal_get_path('module', 'commerce_product') . '/theme/           commerce_product.theme.css';
       if (isset($css[$product_admin])) {
         $css[$product_admin]['data'] = $path . '/css/commerce/commerce_product.admin.     css';
         $css[$product_admin]['group'] = 1;
       }
       if (isset($css[$product_theme])) {
         $css[$product_theme]['data'] = $path . '/css/commerce/commerce_product.theme.     css';
         $css[$product_theme]['group'] = 1;
       }
   }


   // tax
   if (module_exists('commerce_tax')){
       $tax_admin = drupal_get_path('module', 'commerce_tax') . '/theme/commerce_tax.      admin.css';
       $tax_theme = drupal_get_path('module', 'commerce_tax') . '/theme/commerce_tax.      theme.css';
       if (isset($css[$tax_admin])) {
         $css[$tax_admin]['data'] = $path . '/css/commerce/commerce_tax.admin.css';
         $css[$tax_admin]['group'] = 1;
       }
       if (isset($css[$tax_theme])) {
         $css[$tax_theme]['data'] = $path . '/css/commerce/commerce_tax.theme.css';
         $css[$tax_theme]['group'] = 1;
       }
   }
 }
Другие вопросы по тегам