Çok fazla olan oturum dosyalarını nasıl yönetmeliyim?


43

Magento sitelerini barındıran birkaç sunucu için sysadmin olarak görev yapıyorum ve bazen oturum dosyalarını dolduruyorlar.

Bana bu dosyaları yönetmenin Magento'dan yapılabilecek bir şey olmadığı söylendi ve geçici kullanımlarının sadece kapatılamayacakları anlamına geldiğini sanıyordum, ancak Magento'nun bu dosyaların kaldırılması için hiçbir yolu bulunmaması garip görünüyor Dosyalar?

Benim çözümüm, bunun gibi bir şeyi yapan bir gece crontabıdır, find /path/to/magento/sessions/ -name "sess*" -type f -deleteancak en azından söylenenin inelegant olduğunu hisseder.

Bunları ele almanın en iyi yolu nedir?

Yanıtlar:


37

findBaşkalarının belirttiği şekilde özel bir değişiklik zamanı kullanarak oturum dosyalarını silmenin yanı sıra, şunları da yapabilirsiniz:

  • Kaydet veritabanınızda oturumları . Elbette bu, veritabanınıza yük getirecek ve en hızlı yol değil, ancak bu şekilde daha çok sayıda oturum açabilir ve birden çok ön uç sunucusu arasında oturumları paylaşabilirsiniz. app/etc/local.xmlArasında geçiş yaparak ayarı değiştirebilirsiniz.

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

    için

    <session_save><![CDATA[db]]></session_save>
  • Oturum depolama alanınız olarak memcached kullanın . Magento da bunu varsayılan olarak desteklemektedir. app/etc/local.xml.additionalYapılandırma için bir göz atın . Üretimde hiç kullanmadım ama bunun biraz zor olabileceğini duydum.

  • Kulp REDIS oturumları Colin Mollenhours parlak uzatma kullanarak Cm_RedisSession . Kurulum Redis çok uzun sürmemelidir , ayrıca önbellekleme için de kullanılabilir (bkz. Cm_Cache_Backend_Redis ) ve bir RAM önbelleğini diskte kalıcılığa (memcached yerine, RAM disklerine veya benzerlerine) dayanarak birleştirir kilitlenen.


1
Oturumları veritabanında kaydetmek de daha güvenlidir. .Htaccess dosyanız orada değilse (birisi var klasörünü sildiği için), oturum dosyalarınıza dışarıdan erişilemez.
Erfan

8
Veritabanındaki oturumları kaydetmek A Bad Idea. Bu amaç için tasarlanmamıştır ve MySQL oturumu depolamak için çok zayıf bir araç olarak hizmet eder, kilitleme kilit bir meseledir - tasfiye için hiçbir dahili destek söz etmez.
Ben Lessani - Sonassi,

28

Dosya tabanlı oturumlarda, PHP oturumu temizleme cronu tarafından otomatik olarak budanır. Bu nedenle, dosyalar oluşturulduktan yaklaşık ~ 7200 saniye içinde silinir. Bu yüzden yoğun bir sitede bile (günde 30k benzersiz), genellikle ./var/session'da yaklaşık 4,000 oturum dosyası var - bu da düşük seviye bir Linux sunucusu için bile bir şey değil.

Bununla birlikte, temizlik aslında cron çalışmasına dayanır - bu normalde Magento'nun ./var/session dizinine bakmaz. Yani yeni bir sistem cronu kurmalısınız

/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

Oturumlar için varsayılan temizleme süresi, yukarıdakileri uygun şekilde değiştirebilmenize rağmen, yeterli olandan fazla olması gereken 7200 saniyedir.

Memcache oturumlarında, TCP / IP, yalnızca bir sunucu dağıtımı için dosyayı temel alandan daha yavaş hale getirecek tek ek yüktür. Öyleyse, bunun yerine bir unix soketi kullanırsınız; bu, ek yükü giderir ve daha iyi güvenlik sağlar. Ancak yine de, müşteri oturumlarınız tahsis edebileceğiniz RAM miktarına göre kesilir / sınırlanır. Ortalama Magento oturumu 4Kb - yani ayırdığınız MB başına 256 aktif oturumu destekleyebileceksiniz. Bu nedenle, müşterilerin rastgele bir şekilde araba / oturum kaybetmesini önlemek için uygun bir limit belirlediğinizden emin olun. Ayrıca, bir Memcache arka plan programı yeniden başlatması varolan tüm oturumları silecektir (BAD!).

Redis ile (yerel değil, ancak bir uzantı aracılığıyla edinilebilir), Memcache ile aynı düzeyde destek alırsınız, ancak kalıcılık ek avantajları vardır (kullanmak isterseniz). Cm_Redis uzantısı ile oturum sıkıştırmasından da yararlanabilirsiniz. Bu uzantının hem CE hem de EE dağıtımlarında çok iyi çalıştığını gördük.

DB ile, varsayılan erik son kullanma süresi ayarı 1 hafta kadar güçlüdür, bu nedenle yukarıdaki mağaza boyutuyla bir örnek olarak (günde 30 k benzersiz), yaklaşık 7GB'lık bir core_cache_session için bir DB tablo boyutuna bakıyor olacaksınız; Mağazanız hemen hemen her oturuma dayalı işlem için tam durur.

Hem büyük (günde 230 k benzersiz ziyaretçi) hem de küçük (günde <1k benzersiz ziyaretçi) mağaza barındırma deneyiminden yola çıkarak tavsiyemiz:

Tek sunucu dağıtımı - dosyalar

Çoklu sunucu dağıtımı - Redis (ana Magento önbelleğinden ayrı bir veritabanı kullanarak)

Burada gerçekten bazı kapsamlı cevaplar yazdım http://magebase.com/magento-tutorials/magento-session-storage-which-to-choose-and-why/comment-page-1/#comment-1980


2
Temizleme cronunun oturumları temizlemesi gerekiyorsa, neden başarısız olur ve etrafta çalışmak gibi hissettiren yeni bir cron oluşturmak yerine bu sorun nasıl çözülebilir?
Kaz

12

Bir süre önce ilgili bir soru sordum:

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

Asla öğrenemediğim şey (bu işi yeni bir işe bıraktım ve asıl sorun başkasının oldu), eğer Magento'nun oturumları bu ayarları onurlandırırsa ya da Zend (ve muhtemelen bir çeşit zend.ini kullanarak oturum işlemlerini gerçekleştiriyorlarsa) yapılandırma dosyası).

Bakılması gereken php ayarları:

session.gc_maxlifetime session.gc_probability session.gc_divisor

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


Bunu kendim bilmek isterim, deneyimlerime göre Magento bu ayarları onurlandırmıyor (GB'nin oturum dosyalarının değerine sahip olduğumu düşünürsek, bir noktada GC'nin tetikleyeceğini varsaymak güvenli olurdu). Bu yüzden, Ben tarafından önerilen senaryoyu güvenli olması için bir cron işi olarak ayarladım.
Javier Villanueva,

7

Genellikle bir cron işi yeterlidir, ancak burada akılda tutulması gereken birkaç şey var:

1) Oturumu session.gc_maxlifetime( php -i | grep session.gc_maxlifetime) saniyeden daha uzun sürmeyecek şekilde ayarlayın (bu işlem php.ini veya .htaccess tarafından çöp toplama işlemi için hazırlanacak süresi dolmuş oturumları ayarlar)

2) Oturumları veritabanında saklamak isteyebilirsiniz , bunun nasıl yapılacağı hakkında daha fazla bilgi için buraya bakın (bu seçenek özel magento modülü ile yönetilmesi daha kolay olabilir)

3) Dikkate alınması gereken bir diğer seçenek de Memcached cadı sunucularını da hızlandırabilir (tamamen soruya bağlı olmasa da, hakkında bilmek yararlı olduğunu düşünüyorum)

Daha fazla bilgi için bu soruya bakın: https://stackoverflow.com/questions/4353875/how-long-do-the-magento-session-files-need-to-be-kept


2
Tüm oturum dosyalarını kaldırmak için bir cronjob kullanmak kabul edilemez. Bir cron çalıştırılmadan 10 dakika önce bir kullanıcı sepetine malzeme eklerse ne olur? Onların arabası temiz silinir! PHP'nin çöp toplama işlemi çalışmıyorsa, bunun çözülmesi gerekir.
davidalger

1 @davidalger iyi bir noktaya, ben sadece süresi dolmuş oturumları cronjob yoluyla silinen ediliyordu ki (yanlış) varsayımı altında idi
pzirkind

1
@davidalger - PHP'nin kendi çöp koleksiyonu cron üzerinden çalışır. Sadece findtüm dosyalardan daha eskidir sess.gc_maxlifetimeve bunları siler. Oturumları cron aracılığıyla silmek normal, güvenli ve kabul edilebilir bir davranıştır.
Ben Lessani - Sonassi,

1
Aslında hayır, değil. Oturum çöp toplama işlemi, bir PHP komut dosyası yürütme sırasında oturum başlangıcı gerçekleştiğinde yapılır. Ne sıklıkta çöp toplama çalıştırılır değerlerine bağlıdır session.gc_probabilityve session.gc_divisor. Farklı komut dosyalarının farklı değerlere session.gc_maxlifetimesahip olması durumunda, en düşük değere sahip bir değer için oturum depolaması genel olduğundan ve bu komut dosyasının yürütmesinin diğer komut dosyası oturumları nesnelerini temizleyeceğinden, ne kadar süreyle takılacağını belirler.
davidalger

5

Tüm kurulumlarımızda ara sıra logların ve var dizininin temizlenmesini önleyen bir maintenance.php dosyasına sahibiz. Oturumlar veritabanına veya dosya sistemine kaydedilmek zorunda olduğundan, bu bakım dosyası her ikisini de temizler. (Aşağıdaki koda bakınız).

Günlükleri temizlemek için aşağıdaki komutu bir cron işi olarak çalıştırabilirsiniz:

php maintenance.php clean=log

Yukarıdaki komut aşağıdaki çıktıyı üretecektir:

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

Var klasörünü temizlemek için aşağıdaki komutu bir cron işi olarak çalıştırabilirsiniz:

php maintenance.php clean=var

Yukarıdaki komut aşağıdaki çıktıyı üretecektir:

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

Gerçek kod (local.xml dosyanızın yolunu ayarlamayı unutmayın):

<?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

Magento CMS ve benzerleri için (eski oturumları temizlemiyor), sadece php.ini ayarlarına göre cron işleri kullanıyorum.

PHP5 / Ubuntu 14.04 / Debian

Php5 için sistem cron.d kurulumu Magento ./var/session (ya da varsayılan oturum klasörü dışında herhangi bir şeyi temizlemez) (Ubuntu için / var / lib / php5 ve diğer birçok Linux için / var / lib / php5 / sessions veya / tmp / dists).

Ancak hala php5 / Debian sistem cronu varsayılanına göre "sessionclean" ve "maxlifetime" kullanabilirsiniz:

Komut satırından deneyebileceğiniz örnek:

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

Bu nedenle, bunu yalnızca bir sistem / kök crontab dosyasına veya oturum dosyaları için okuma / yazma iznine sahip bir kullanıcı crontabına ekleyin:

$ sudo crontab -e

Eklediğiniz sistem php cron'una benzemesini istiyorsanız:

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)

veya - bu dosyaların / dirlerin var olduğunu bildiğimiz için:

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

Şimdi yönetilebilir miktarda oturumum var ve php.ini (cli) ayarları ile varsayılan çöp toplama / kullanım süresi boyunca temiz tutuluyor.

(Joker karakteri yukarıda bırakabilir veya site adıyla değiştirebilirsiniz.)

EDIT (PHP7 / Ubuntu 16.xx / Debian):

'Sessionclean' betiği değişti ve maxlifetime betiği kaldırıldı. Sistem / php cron işi için şimdi bir betik. Dosya çağrıları artık komut dosyası için statik olduğundan, artık bunu gerçekten kullanamazsınız.

Sistem temizlenmezse eski php5 sessionclean betiği hala sizin için çalışabilir. Yapabileceğin şey eski Debian php5 Paketini kapmak ve sessioncleanondan çıkarmak . Ya da bunu komut dosyası alanınıza kopyalayabilirsiniz (uygun / var / www / (site) izinleri / sahiplik vererek):

#!/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

Ben de yeniden adlandırmanızı öneririz, bu yüzden yeni php 'sessionclean' cronjob ile karıştırılmaz. Daha sonra kendi "maksimum kullanım süresi" numaranızı şöyle ekleyebilirsiniz:

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

(61 yaşın (dakika olarak) olması ve 'MySessionClean', yukardan indirilen veya kopyalanan yeniden adlandırılan php5 betiğidir).

Bu şekilde php.ini / env çağrılarından tamamen kaçınırız.

(EDIT 13DEC2016: DEBIAN ARCHIVE REPO LINK güncellendi)


3

Tüm bu eski oturum dosyalarından DB'yi düzenli olarak temizledim. Tüm bu rutin işleri benim için yapan Magento Optimizer'ı yüklemedene kadar elle rahatsız edici bir işti . Ayrıca, önbelleğim sürekli yenileniyor ve ürünlerimi ve statik blokları değiştirdikten sonra manuel olarak kullanmıyorum. Evet, hata raporları ve terkedilmiş arabaları da temizlenir.


3

Yukarıdaki tüm Yorumlar arasında, bunun kolay bir çözüm olduğunu düşünüyorum ve eski komut dosyalarını yönetmek ve yeni oturum dosyalarını saklamak için üçüncü taraf uzantılarını yüklemek ve uzun komut dosyalarından daha iyi olacağını umuyorum.

  1. Klasörünüzün altında "clean_session.sh" bir dosya adı oluşturun magento.
  2. Bu satırları yapıştırın.

#!/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. Sonra temizlik yapmak için haftalık cronjob zamanlayabilirsiniz.

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

  1. Dosyayı çalıştırılabilir hale getirmeyi unutmayın

chmod u+x clean_session.sh

  1. Ve ayrıca olarak çalıştırabilirsiniz

sh clean_session.sh


3

Benim durumumda, bu betiği magento/var/bir haftadan uzun süren oturum dosyalarını silmek için dizine yerleştirdim -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

Bu benim ilk bash betiğim (revizyon 2) ve birkaç yönden optimize edilebileceğini düşünüyorum. Herhangi bir optimizasyon önerisi için açığım.

Bu komut dosyası şu adreste bulunabilir: https://gist.github.com/Nolwennig/a75dc2f8628be2864bb2


0

Var / session dizinini boşaltan bir script yarattım. Bir cron işine günde bir kez çalıştırmak yeterli ve gereken şekilde ayarlanması gerektiğini ekleyebilirsiniz. Oturum dizininin ne zaman dolduğunu fark edeceksiniz, cpanel veya ssh ile dosyaları silmek imkansız, bu betiğin sadece magento kök dizinindeki yerini alması gerekiyor.

<?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);

Bu senaryodaki sorun, yalnızca eskileri değil tüm oturumları silmesidir. Böylece hiç kimse bir günden daha uzun süre giriş yapamaz (bunu günlük olarak çalıştırırsanız) ve bu işlem yapıldıktan sonra tüm arabaları boş bırakacaktır (böylece hiçbir araba bir günden daha uzun süre dayanmayacaktır).
simonthesorcerer
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.