Как мне обрабатывать файлы сеансов, которых становится слишком много?


Я выступаю в качестве системного администратора для нескольких серверов, на которых размещены сайты Magento, и иногда они заполняются файлами сеансов.

Мне сказали, что управление этими файлами не является чем-то, что можно сделать из Magento, и я предполагаю, что их временное использование означает, что их нельзя просто отключить, но кажется странным, что Magento не может справиться с удалением этих файлов?

Мое решение - это ночной кронтаб, который выполняет что-то вроде этого find /path/to/magento/sessions/ -name "sess*" -type f -delete но это, мягко говоря, неэлегантно.

Как лучше всего с этим справиться?

Author: David Manners, 2013-01-22

12 answers

Помимо удаления файлов сеанса с помощью find, используя пользовательское время изменения, как упоминалось другими, вы также можете:

  • Сохраните сеансы в своей базе данных . Конечно, это увеличит нагрузку на вашу базу данных, и это не самый быстрый способ, но таким образом вы сможете обрабатывать гораздо больше сеансов и обмениваться сеансами между несколькими интерфейсными серверами. Вы можете изменить настройку в app/etc/local.xml, переключив

    <session_save><![CDATA[files]]></session_save>
    

    До

    <session_save><![CDATA[db]]></session_save>
    
  • Использовать memcached в качестве хранилища сеансов. Magento также поддерживает это по умолчанию. Взгляните на app/etc/local.xml.additional для конфигурации. Я никогда не использовал его в производстве, но слышал, что это может быть немного сложно.

  • Обрабатывайте сеансы в Redis с помощью блестящего расширения Колина Молленхура Cm_RedisSession. Настройка Redis не должна занимать слишком много времени, также может использоваться для кэширования (см. cm_cache_backend_redis) и объединяет кэш оперативной памяти с сохраняемость на диске (в отличие от memcached, дисков оперативной памяти или тому подобного), Которая всегда присутствует в случае сбоя вашего сервера.

 39
Author: Matthias Zeis, 2013-01-23 17:01:42

При сеансах на основе файлов они будут автоматически обрезаны хроном очистки сеансов PHP, поэтому файлы, скорее всего, будут удалены в течение ~7200 секунд после создания. Таким образом, даже на загруженном сайте (30 тыс. единиц в день) обычно в файле ./var/session содержится всего около 4000 файлов сеансов, что ничего не значит даже для низкоуровневого сервера Linux.

Однако очистка фактически зависит от работы cron, которая обычно не отображается в каталоге ./var/session Magento. Поэтому вам следует создать новая система cron

/usr/bin/find /home/myuser/public_html/var/session -mindepth 1 -maxdepth 1 -type f -cmin +$(/usr/lib/php5/maxlifetime) -print0 -exec rm {} \; >/dev/null 2>&1

Период очистки по умолчанию для сеансов составляет 7200 секунд, что должно быть более чем достаточно, хотя вы можете изменить вышеуказанное в соответствии с требованиями.

При сеансах Memcache TCP/IP является единственной накладной, которая при развертывании на одном сервере будет работать медленнее, чем на основе файлов. Таким образом, вместо этого вы бы использовали сокет unix, который устраняет эти накладные расходы и обеспечивает лучшую безопасность. Но даже в этом случае ваши сеансы с клиентами будут сокращены/ограничены в отношении количества Оперативную память вы можете выделить. Средний сеанс Magento составляет 4 КБ, поэтому вы сможете поддерживать 256 активных сеансов на каждый выделенный вами МБ. Поэтому обязательно установите соответствующий лимит, чтобы клиенты случайно не потеряли корзину/сеанс. А также имейте в виду, перезапуск демона Memcache уничтожит все существующие сеансы (ПЛОХО!).

С Redis (не родной, но доступный через расширение) вы получаете такой же уровень поддержки, как и Memcache, но с дополнительными преимуществами сохраняемости (если вы хотите его использовать). С расширением Cm_Redis вы также сможете воспользоваться преимуществами сжатия сеанса. Мы обнаружили, что это расширение очень хорошо работает как в развертываниях CE, так и в EE.

В случае с БД, значение по умолчанию для истечения срока действия обрезки составляет 1 неделю, поэтому с приведенным выше размером хранилища в качестве примера (30 тыс. единиц в день) вы будете смотреть на размер таблицы БД для core_cache_session около 7 ГБ – что приведет к полной остановке вашего магазина почти для каждого сеанса на основе операция.

Исходя из опыта размещения как крупных (230 тыс. уникальных посетителей в день), так и небольших (

Файлы развертывания на одном сервере

Многосерверное развертывание - Redis (с использованием отдельной базы данных из основного кэша Magento)

Я написал здесь несколько действительно подробных ответов http://magebase.com/magento-tutorials/magento-session-storage-which-to-choose-and-why/comment-page-1/#comment-1980

 29
Author: Ben Lessani - Sonassi, 2013-01-31 14:52:34

Некоторое время назад я задал связанный с этим вопрос:

Https://stackoverflow.com/questions/7828975/php-garbage-collection-clarification

Чего я так и не узнал (я оставил эту работу для новой, и первоначальная проблема стала чьей-то другой), так это будут ли сеансы Magento соблюдать эти настройки или они реализуют обработку своих сеансов с помощью Zend (и, предположительно, какой-то конфигурационный файл zend.ini).

Настройки php для просмотра по адресу:

session.gc_maxlifetime session.gc_probability session.gc_divisor

Http://php.net/manual/en/session.configuration.php#ini.session.gc-probability

 13
Author: pspahn, 2017-05-23 12:37:13

Обычно достаточно задания cron, но вот несколько вещей, которые следует иметь в виду:

1) Установите продолжительность сеанса не более session.gc_maxlifetime (php -i | grep session.gc_maxlifetime) секунд (это настроит истекшие сеансы, которые будут подготовлены для сборки мусора php.ini или .htaccess)

2) Возможно, вы захотите сохранить сеансы в базе данных см. здесь для получения дополнительной информации о том, как это сделать (этой опцией может быть проще управлять с помощью пользовательского модуля magento)

3) Другой вариант учтите, что Memcached witch также может ускорить работу серверов (хотя и не полностью связан с вопросом, я думаю, что об этом полезно знать)

Смотрите этот вопрос для получения дополнительной информации: https://stackoverflow.com/questions/4353875/how-long-do-the-magento-session-files-need-to-be-kept

 7
Author: pzirkind, 2019-02-22 04:13:17

На всех наших установках у нас есть maintenance.php файл, который время от времени выполняет очистку журналов и каталога var. Поскольку сеансы должны быть сохранены либо в базе данных, либо в файловой системе, этот файл обслуживания очистит их оба. (См. Код ниже).

Вы можете выполнить следующую команду в качестве задания cron для очистки журналов:

php maintenance.php clean=log

Приведенная выше команда приведет к следующему результату:

catalogindex_aggregation has been truncated
catalogindex_aggregation_tag has been truncated
catalogindex_aggregation_to_tag has been truncated
catalog_compare_item has been truncated
dataflow_batch_export has been truncated
dataflow_batch_import has been truncated
log_customer has been truncated
log_quote has been truncated
log_summary has been truncated
log_summary_type has been truncated
log_url has been truncated
log_url_info has been truncated
log_visitor has been truncated
log_visitor_info has been truncated
log_visitor_online has been truncated
report_compared_product_index has been truncated
report_event has been truncated
report_viewed_product_index has been truncated

Ты можешь выполните следующую команду в качестве задания cron, чтобы очистить папку var:

php maintenance.php clean=var

Приведенная выше команда приведет к следующему результату:

downloader/.cache/* has been emptied
downloader/pearlib/cache/* has been emptied
downloader/pearlib/download/* has been emptied
var/cache/ has been emptied
var/locks/ has been emptied
var/log/ has been emptied
var/report/ has been emptied
var/session/ has been emptied
var/tmp/ has been emptied

Фактический код (не забудьте настроить путь к вашему local.xml файл):

<?php
$xml = simplexml_load_file('./app/etc/local.xml', NULL, LIBXML_NOCDATA);

$db['host'] = $xml->global->resources->default_setup->connection->host;
$db['name'] = $xml->global->resources->default_setup->connection->dbname;
$db['user'] = $xml->global->resources->default_setup->connection->username;
$db['pass'] = $xml->global->resources->default_setup->connection->password;
$db['pref'] = $xml->global->resources->db->table_prefix;

if (!isset($argv[1]) || !stristr($argv[1], 'clean=')) {
    echo 'Please use one of the commands below:' . PHP_EOL;
    echo 'php maintenance.php clean=log' . PHP_EOL;
    echo 'php maintenance.php clean=var' . PHP_EOL;
    die;
}

$method = str_replace('clean=', '', $argv[1]);

switch ($method) {
case 'log':
    clean_log_tables();
    break;
case 'var':
    clean_var_directory();
    break;
default:
    echo 'Please use one of the commands below:' . PHP_EOL;
    echo 'php maintenance.php clean=log' . PHP_EOL;
    echo 'php maintenance.php clean=var' . PHP_EOL;
    break;
}

function clean_log_tables() {
    global $db;

    $tables = array(
        'catalogindex_aggregation',
        'catalogindex_aggregation_tag',
        'catalogindex_aggregation_to_tag',
        'catalog_compare_item',
        'dataflow_batch_export',
        'dataflow_batch_import',
        'log_customer',
        'log_quote',
        'log_summary',
        'log_summary_type',
        'log_url',
        'log_url_info',
        'log_visitor',
        'log_visitor_info',
        'log_visitor_online',
        'report_compared_product_index',
        'report_event',
        'report_viewed_product_index'
    );

    mysql_connect($db['host'], $db['user'], $db['pass']) or die(mysql_error());
    mysql_select_db($db['name']) or die(mysql_error());

    foreach($tables as $v => $k) {
        @mysql_query('TRUNCATE `'.$db['pref'].$k.'`');
        echo $db['pref'] . $k . ' has been truncated' . PHP_EOL;
    }
}

function clean_var_directory() {
    $dirs = array(
        'downloader/.cache/*',
        'downloader/pearlib/cache/*',
        'downloader/pearlib/download/*',
        'var/cache/',
        'var/locks/',
        'var/log/',
        'var/report/',
        'var/session/',
        'var/tmp/'
    );

    foreach($dirs as $v => $k) {
        exec('rm -rf '.$k);
        echo $k . ' has been emptied' . PHP_EOL;
    }
}
 5
Author: Kenny, 2013-01-23 08:14:27

Для CMS Magento и тому подобного (которые не очищают старые сеансы) я просто использую задания cron на основе настроек php.ini.

PHP5/Убунту 14.04/Debian

Системный cron.d установка для php5 не очищает Magento./var/сеанс (или что-либо, кроме папки сеанса по умолчанию (/var/lib/php5 для Ubuntu и /var/lib/php5/сеансы или /tmp/ для большинства других дистрибутивов Linux).

Но вы все равно можете использовать "sessionclean" и "maxlifetime" в соответствии с системой php5/Debian по умолчанию крон:

Пример, который вы можете попробовать из командной строки:

# sudo /usr/lib/php5/sessionclean /var/www/{yoursite}/var/session $(/usr/lib/php5/maxlifetime)

Поэтому просто включите это в системную/корневую кронтаб или кронтаб пользователя, у которого есть разрешение на чтение/запись файлов сеанса:

$ sudo crontab -e

Добавьте это, если вы хотите, чтобы это выглядело похоже на системный php cron:

20,40 * * * * [ -x /usr/lib/php5/maxlifetime ] && [ -x /usr/lib/php5/sessionclean ] && [ -d /var/www/*/var/session ] && /usr/lib/php5/sessionclean /var/www/{yoursite}/var/session $(/usr/lib/php5/maxlifetime)

Или - поскольку мы знаем, что эти файлы/каталоги существуют:

20,40 * * * * /usr/lib/php5/sessionclean /var/www/*/var/session $(/usr/lib/php5/maxlifetime)

Теперь у меня есть управляемое количество сеансов, и оно поддерживается в чистоте с помощью сборки мусора/времени жизни по умолчанию через php.ini (cli) настройки.

( Вы можете оставить подстановочный знак выше или заменить на имя сайта.)

РЕДАКТИРОВАТЬ (PHP7/Ubuntu 16.xx/Debian):

Сценарий 'sessionclean' изменился, и сценарий maxlifetime был удален. Для задания cron system/php теперь это один скрипт. Вы больше не можете использовать это, так как вызовы файлов теперь статичны для сценария.

Более старый скрипт php5 sessionclean все еще может работать для вас, если система не очищается. Что вы можете сделать, так это взять более старый пакет Debian php5 и извлечь sessionclean из него. Или вы можете просто скопировать это в свою область сценариев (предоставив соответствующие разрешения /var/www/(сайт)/права собственности):

#!/bin/sh

# first find all used files and touch them (hope it's not massive amount of files)
[ -x /usr/bin/lsof ] && /usr/bin/lsof -w -l +d "${1}" | awk -- '{ if (NR > 1) { print $9; } }' | xargs -i touch -c {}

# find all files older then maxlifetime
find "${1}" -depth -mindepth 1 -maxdepth 1 -ignore_readdir_race -type f -cmin "+${2}" -delete

Я также рекомендую переименовать его, чтобы его не путали с новым заданием php 'sessionclean' cronjob. Затем вы можете подключить свой собственный номер "maxlifetime" следующим образом:

     20,40 * * * * /home/-username-/scripts/MySessionClean /var/www/*/var/session 61

(61 - возраст примера (в минутах), а "Mysessionclean" - это загруженный или скопированный переименованный скрипт php5 сверху).

Таким образом, мы полностью избегаем вызовов php.ini/env.

(ПРАВКА 13DEC2016: Обновлена ССЫЛКА НА РЕПОЗИТОРИЙ АРХИВА DEBIAN)

 5
Author: bshea, 2016-12-13 22:36:44

Я регулярно очищал базу данных от всех этих старых файлов сеансов. Это была раздражающая ручная работа, пока я не установил Оптимизатор Magento, который делает всю эту рутинную работу для меня. Кроме того, мой кэш постоянно обновляется, и я не делаю это вручную после смены продуктов и статических блоков. О, да, отчеты об ошибках и брошенные тележки также очищаются.

 3
Author: James, 2014-03-05 15:25:54

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

  1. Создайте имя файла"clean_session.sh "в вашей папке magento.
  2. Вставьте эти строки.

#!/bin/bash
# delete session files older than 14 days
find /home/DOMAIN/public_html/var/session -name 'sess_*' -type f -mtime +14 -exec rm {} \;

  1. Затем вы можете запланировать еженедельное выполнение cronjob для очистки.

1 1 * * 6 /bin/sh /home/DOMAIN/public_html/clean_session.sh

  1. Не забудьте сделать файл исполняемым как

chmod u+x clean_session.sh

  1. И вы также можете запустить его как

sh clean_session.sh

 3
Author: Anil, 2015-12-15 03:16:28

В моем случае я запускаю этот скрипт, помещенный в каталог magento/var/ для удаления файлов сеансов более одной недели (-mtime +7):

#!/bin/sh
# Place this script in magento/var/ directory

for n in `seq 0 9`
  do
    for u in `seq 0 9`
    do
      for m in `seq 0 9`
        do
          name="sess_"$n$u$m*
          echo $name
          find session/ -name $name -type f -mtime +7 -delete
          echo $name ok
      done
      for m in {a..z}
        do
          name="sess_"$n$u$m*
          echo $name
          find session/ -name $name -type f -mtime +7 -delete
          echo $name ok
      done
    done
      for u in {a..z}
      do
        for m in `seq 0 9`
          do
            name="sess_"$n$u$m*
            echo $name
            find session/ -name $name -type f -mtime +7 -delete
            echo $name ok
        done
        for m in {a..z}
          do
            name="sess_"$n$u$m*
            echo $name
            find session/ -name $name -type f -mtime +7 -delete
            echo $name ok
        done
    done
done

for n in {a..z}
  do
    for u in `seq 0 9`
      do
        for m in `seq 0 9`
          do
            name="sess_"$n$u$m*
            echo $name
            find session/ -name $name -type f -mtime +7 -delete
            echo $name ok
        done
        for m in {a..z}
          do
            name="sess_"$n$u$m*
            echo $name
            find session/ -name $name -type f -mtime +7 -delete
            echo $name ok
        done
    done
    for u in {a..z}
      do
        for m in `seq 0 9`
          do
            name="sess_"$n$u$m*
            echo $name
            find session/ -name $name -type f -mtime +7 -delete
            echo $name ok
        done
        for m in {a..z}
          do
            name="sess_"$n$u$m*
            echo $name
            find session/ -name $name -type f -mtime +7 -delete
            echo $name ok
        done
    done
done

Это мой первый сценарий bash (версия 2), и я думаю, что его можно оптимизировать в нескольких аспектах. Я открыт для любых предложений по оптимизации.

Этот скрипт можно получить по адресу: https://gist.github.com/Nolwennig/a75dc2f8628be2864bb2

 3
Author: Nolwennig, 2016-09-09 10:14:02

Я создал скрипт, который очищает каталог var/session. Вы можете добавить его в задание cron для запуска один раз в день, которого должно быть достаточно, и настроить по мере необходимости. Вы заметите, что когда ваш каталог сеансов будет заполнен, невозможно удалить файлы через cpanel или ssh, этот скрипт сделает все возможное, просто разместив их в корневом каталоге magento.

<?php
function adjustSessionFiles($dir, $pattern = "*")
{
    $files = glob($dir . "/$pattern");
    foreach ($files as $file) {
        if (is_dir($file) and !in_array($file, array('..', '.')))  {
            adjustSessionFiles($file, $pattern);
        }else if(is_file($file) and ($file != __FILE__)) {
            unlink($file);
        }
    }
}
$dir = __DIR__ . DIRECTORY_SEPARATOR . 'var' . DIRECTORY_SEPARATOR . 'session';
adjustSessionFiles($dir);
 0
Author: Lawrence Farbman, 2017-05-09 14:43:32

Файлы сеанса должны быть удалены php с помощью настроек из вашего файла php.ini.

Вероятно, у вас есть session.gc_probability = 0, настроенный в вашем файле php.ini. Это означает, что 0 из каждых посетителей $session.gc_divisor вызовут сборщик мусора.

Вы можете:

A) Измените session.gc_probability на 1, чтобы php выполнял очистку за вас

Б) Вы можете создать один php-файл и добавить его в свой cron (рекомендуется для производства) - см. Официальный пример PHP

Быть осознавая: Решение А проще, но...

Решение A подойдет, если вы знаете, сколько посетителей у вашего сайта, поэтому его очень легко реализовать. Однако, если вы очищаете сеанс слишком часто или очень часто, это может стать проблемой. Вот почему рекомендуется решение B.

 0
Author: Ricardo Martins, 2020-06-15 08:30:17

Рабочее Решение...

Вы можете удалить, написав простую команду Linux на cron

find /var/lib/php/session -type f -cmin +$(echo "`/opt/php/bin/php -i|grep -i session.gc_maxlifetime|cut -d' ' -f3`"/60|bc) -exec rm -f {} \;

Где

/var/lib/php/session - это ваш абсолютный путь к каталогу сеанса
/opt/php/bin/php - это путь PHP на сервере 60 [Минута] - Срок службы файла больше, чем (Означает Все файлы, которые не изменялись с последних 60 минут)

 0
Author: Kaushal Sachan, 2020-09-16 07:05:35