2012-12-07 24 views
20

माईस साइट बहुत धीरे-धीरे काम करती है (और मुझे इसके बारे में कोई जानकारी नहीं थी)। यह ज़ेंड एप्लिकेशन पर आधारित है, मैं इस तरह की साइटों के बारे में दसियों का उपयोग करता था, इसलिए मुझे यकीन है कि मेरा कोड ठीक है।session_start() बहुत लंबा समय लेता है

मैंने सर्वर पर xdebugger स्थापित किया, इसे प्रोफाइल करने का प्रयास किया और अनुमान लगाया? php :: session_start() ने 48.675 सेकेंड लिया। चौथी आठ और आधा सेकेंड! ये अविश्वसनीय है! इसका कारण क्या हो सकता है? यह आम ऑपरेशन है, यह इतनी देर क्यों निष्पादित कर सकता है? ऐसे व्यवहार को कैसे ठीक करें, जो संपादित करने के लिए कॉन्फ़िगर करता है? Google पर खोजे, लेकिन कोई अच्छा जवाब नहीं मिला (लगभग हर जगह एक सवाल है, लेकिन कोई जवाब नहीं है)। पहले में धन्यवाद!

xdebugger profiling results

+1

एक सत्र शुरू करने के लिए 48 सेकंड ?? यह पागलपन है! सत्र में कितना और डेटा है? क्या आप किसी भी सत्र हैंडलिंग पुस्तकालयों का उपयोग कर रहे हैं? सत्रों को एक असामान्य स्थान पर सहेजना? डेटाबेस (अपनी अनुक्रमणिका जांचें)? गैर-स्थानीय फाइल सिस्टम? यह किस प्रकार का सर्वर चल रहा है? क्या आपके पास php.ini या .htaccess में कोई सत्र कॉन्फ़िगरेशन है? – Spudley

उत्तर

18

मेरा अनुमान है कचरा संग्रहण दिनचर्या है, जो देशी session_start() समारोह के अंदर चलाने हो जाता होगा। हो सकता है कि आपने ऐसा कुछ किया है जो कई पुरानी सत्र फ़ाइलों को आसपास रखता है, जैसे अधिकतम जीवनकाल बदलना? या हो सकता है कि आपने फैसला किया है कि उन्हें डेटाबेस में स्टोर करना अच्छा विचार होगा, लेकिन एक उपयुक्त अनुक्रमणिका बनाने के लिए भूल गए? समाप्ति की जांच के लिए मूल जीसी रूटीन स्टेट() की प्रत्येक एकल फ़ाइल फ़ाइल। यदि बहुत सारी फाइलें बनाई गई हैं तो यह समय लेने वाला है।

संपादित: केवल डीबगिंग के लिए आप मदद करने के लिए, को निष्क्रिय कचरा संग्रहण अस्थायी रूप से session.gc-probability की स्थापना द्वारा:

session.gc-probability = 0 

यकीन है कि सेटिंग के बने, मैं नहीं जानता कि क्या Zend फ्रेमवर्क कर रहा हो सकता है बनाओ यहाँ।

पीएस कारण जानने के बिना एक फिक्स का सुझाव देना मुश्किल है। मेरा जवाब आपको कारण की पहचान करने के लिए मार्गदर्शन करने के लिए है।

17

session_start (फ़ाइलों में संग्रहीत सत्रों के साथ) PHP में अवरुद्ध हो रहा है, इसलिए यदि आप एक ही ब्राउज़र सत्र (AJAX या एकाधिक ब्राउज़र टैब/विंडोज़) के लिए कई सर्वर सत्र शुरू करने का प्रयास करते हैं तो यह समस्या दिखाई देगी। प्रत्येक session_start अन्य सत्र बंद होने तक प्रतीक्षा करेगा।

यहाँ देखें: http://konrness.com/php5/how-to-prevent-blocking-php-requests/

फाइलों से सत्र के डेटाबेस भंडारण के लिए बदलने का प्रयास करें।

+0

धन्यवाद, यह था। [session_write_close] (http://php.net/manual/en/function.session-write-close.php) ने मेरी मदद की। – Curious

+0

धन्यवाद, लंबी पूलिंग के साथ एक ही समस्या, इसलिए यदि कोई स्क्रिप्ट प्रतीक्षा कर रही है, तो प्रतीक्षा करें/नींद से पहले session_write_close, और जागने पर सत्र_स्टार्ट फिर से करें। – KyleK

1

एक अन्य दृष्टिकोण यह हो सकता है कि आपने PHP.ini में एक बड़ा memory_limit सेट किया हो।

मैंने PHPMyAdmin में विशाल mysql डंप अपलोड करने के लिए ऐसा किया था और लोड समय बढ़ाया गया था, शायद (जैसा कि ऊपर बताया गया है) कई सत्र फाइलें अब ढेर हुई हैं कि PHP को छोड़ने के लिए कमरा था। डिफ़ॉल्ट लगता है 128M, मुझे लगता है। मैंने चौगुनी हो गई थी।

4

मुझे यह समस्या है और मुझे आश्चर्य है कि किसी ने भी इस विशिष्ट प्रतिक्रिया को पोस्ट नहीं किया है। यह नहीं हो सकता है लेकिन यह जांच के लायक है।

PHP पृष्ठ को संसाधित करते समय सत्र फ़ाइल लॉक करता है, ताकि पृष्ठ पर इसका विशेष पहुंच हो। इसके बारे में सोचें, sess_184c9aciqoc फ़ाइल डेटाबेस नहीं है, इसलिए एक ही सत्र में दो कॉल एक साथ नहीं पहुंच सकते हैं। तो यदि आपके पास बहुत सारे AJAX कॉल हैं, तो आप "ट्रैफिक जाम" प्राप्त कर सकते हैं। एक बार जब आप उन्नत स्क्रिप्टिंग करना शुरू कर देते हैं तो यह एक गेटचा से सावधान रहना है। वैसे, टाइमस्टैम्प की एक सरणी स्टोर करने के लिए यहां एक फ़ंक्शन है।मैं प्रयोग किया जाता है इस यह पता लगाने की सत्र शुरू होने से अपराधी था:

//time function for benchmarking 
if(function_exists('gmicrotime')){ 
    function gmicrotime($n=''){ 
     #version 1.1, 2007-05-09 
     //store array of all calls 
     global $mT; 
     list($usec, $sec) = explode(' ',microtime()); 
     if(!isset($mT['_base_']))$mT['_base_']=$sec; 
    $t=round((float)$usec + (float)(substr($sec,-4)),6); 
    $mT['all'][]=$t; 
    if($n){ 
     if(isset($mT['indexed'][$n])){ 
      //store repeated calls with same index. If in a loop, add a $i if needed 
      if(is_array($mT['indexed'][$n])){ 
       $mT['indexed'][$n][]=$t; 
      }else{ 
       $mT['indexed'][$n]=array($mT['indexed'][$n],$t); 
      } 
     }else $mT['indexed'][$n]=$t;  
    } 
    //return elapsed since last call (in the local array) 
    $u=$mT['all']; 
    if(count($u)>1){ 
     $mT['_total_']=$u[count($u)-1] - $u[0]; 
     return round(1000*($u[count($u)-1]-$u[count($u)-2]),6); 
    } 
} 
gmicrotime('pageStart'); 
} 

तो मैं फोन इस प्रकार है:

gmicrotime('beforeSessionStart'); 
session_start(); 
gmicrotime('afterSessionStart'); 

do_something_slow(); 
gmicrotime('afterSlowProcess'); 
//etc.. 
echo '<pre>'; 
print_r($mT); 

इस आशा उपयोगी है!

0

इस समस्या से बचने का एक तरीका है PHP को फ़ाइलों के बजाय डेटाबेस तालिका में सत्रों को स्टोर करने के लिए कहना।

सबसे पहले, मैं तुम्हें इस समाधान के लिए वास्तविक क्रेडिट के रूप में कुछ लिंक दे देंगे:

http://www.tonymarston.net/php-mysql/session-handler.html

http://shiflett.org/articles/storing-sessions-in-a-database

http://culttt.com/2013/02/04/how-to-save-php-sessions-to-a-database/

फिर एक कोड कार्यान्वयन मैं इन रीडिंग से ली गई:

<?php 

class TLB_Sessions_in_Database 
{ 
    private $debug; 
    private $dbc; 

    function __construct() 
    { 
     $this->debug = false; 

     session_set_save_handler(
      array($this, '_open'), 
      array($this, '_close'), 
      array($this, '_read'), 
      array($this, '_write'), 
      array($this, '_destroy'), 
      array($this, '_clean') 
     ); 
    } 

    function _open() 
    { 
     if($this->debug) echo '_open:'.PHP_EOL; 

     if(($this->dbc = mysql_connect(DB_HOST, DB_USER, DB_PASSWORD)) !== false) 
     { 
      $select_db = mysql_select_db(DB_NAME, $this->dbc); 
      $set_charset = mysql_set_charset(DB_CHARSET, $this->dbc); 

      if($this->debug) echo '- return: '.(($select_db && $set_charset) ? 'true' : 'false').PHP_EOL; 

      return($select_db && $set_charset); 
     } 
     else 
     { 
      if($this->debug) echo '- error: '.mysql_error($this->dbc).PHP_EOL; 
     } 

     return(false); 
    } 

    function _close() 
    { 
     if($this->debug) echo '_close:'.PHP_EOL; 

     return(mysql_close($this->dbc)); 
    } 

    function _read($session_id) 
    { 
     if($this->debug) echo '_read:'.PHP_EOL; 

     $session_id = mysql_real_escape_string($session_id); 

     $sql = "SELECT `session_data` FROM `".DB_NAME."`.`php_sessions` WHERE `session_id` = '".$session_id."'"; 

     if($this->debug) echo '- query: '.$sql.PHP_EOL; 

     if(($result = mysql_query($sql, $this->dbc)) !== false) 
     { 
      if(!in_array(mysql_num_rows($result), array(0, false), true)) 
      { 
       $record = mysql_fetch_assoc($result); 

       return($record['session_data']); 
      } 
     } 
     else 
     { 
      if($this->debug) echo '- error: '.mysql_error($this->dbc).PHP_EOL; 
     } 

     return(''); 
    } 

    function _write($session_id, $session_data) 
    { 
     if($this->debug) echo '_write:'.PHP_EOL; 

     $session_id = mysql_real_escape_string($session_id); 
     $session_data = mysql_real_escape_string($session_data); 

     //$sql = "REPLACE INTO `php_sessions` (`session_id`, `last_updated`, `session_data`) VALUES ('".$session_id."', '".time()."', '".$session_data."')"; 
     $sql = "INSERT INTO `".DB_NAME."`.`php_sessions` (`session_id`, `date_created`, `session_data`) VALUES ('".$session_id."', NOW(), '".$session_data."') ON DUPLICATE KEY UPDATE `last_updated` = NOW(), `session_data` = '".$session_data."'"; 

     if(($result = mysql_query($sql, $this->dbc)) === false) 
     { 
      if($this->debug) echo '- error: '.mysql_error($this->dbc).PHP_EOL; 
     } 

     return($result); 
    } 

    function _destroy($session_id) 
    { 
     if($this->debug) echo '_destroy:'.PHP_EOL; 

     $session_id = mysql_real_escape_string($session_id); 

     $sql = "DELETE FROM `".DB_NAME."`.`php_sessions` WHERE `session_id` = '".$session_id."'"; 

     if(($result = mysql_query($sql, $this->dbc)) === false) 
     { 
      if($this->debug) echo '- error: '.mysql_error($this->dbc).PHP_EOL; 
     } 

     return($result); 
    } 

    function _clean($max) 
    { 
     if($this->debug) echo '_clean:'.PHP_EOL; 

     $sql = 'DELETE FROM `'.DB_NAME.'`.`php_sessions` WHERE `last_updated` < DATE_SUB(NOW(), INTERVAL '.$max.' SECOND)'; 

     if(($result = mysql_query($sql, $this->dbc)) === false) 
     { 
      if($this->debug) echo '- error: '.mysql_error($this->dbc).PHP_EOL; 
     } 

     return($result); 
    } 
} 

new TLB_Sessions_in_Database(); 

ईएनडी।

0

यदि आपके पास एक ही पृष्ठ पर एकाधिक समवर्ती AJAX कॉल हैं तो यह स्थिति आपकी समस्या का कारण बन सकती है।

0

मेरे मामले में यह /etc/php.d/memcached.ini Here में गलत मेम्कैश सर्वर सेटिंग्स था मेम्कैश गुण और here के बारे में जानकारी कैसे मेम्कैश में सेटअप भंडारण के लिए किया जाता है।

+0

यह एक बुरा जवाब है क्योंकि यह नहीं बताता कि गलत, या सही, सेटिंग्स क्या थीं। –

+0

@kikosoftware memcached सेटिंग्स आप जो हासिल करने की कोशिश कर रहे हैं उसके साथ बदल सकते हैं। आप इस बारे में और अधिक सीख सकते हैं [यहां] (http://php.net/manual/en/memcached.configuration.php)। मेरे मामले में 'एक्सटेंशन' सेटिंग elasticache लाइब्रेरी को इंगित करने के लिए अनुपलब्ध थी। डाउनवोट – vikramaditya234

+0

को हटाने के लिए अनुरोध करें कि वह जानकारी जोड़ने के लिए धन्यवाद। मुझे आपके द्वारा लिंक किए गए PHP मैन्युअल पृष्ठ पर 'एक्सटेंशन' सेटिंग दिखाई नहीं दे रही है। क्या आपका मतलब 'memcached.serializer' है? फिलहाल मैं अपना डाउनवोट नहीं हटा सकता: "आपने कल आखिरी बार इस जवाब पर मतदान किया था। आपका वोट अब लॉक हो गया है जब तक कि यह जवाब संपादित नहीं किया जाता है।" यह सही समझ में आता है। –

0

मुझे बस यह समस्या थी। session_start लगभग 5sec ले रहा था।

मेरा मुद्दा था कि मैंने इसके ऊपर कुछ चर घोषित किए थे।

मैंने सत्र_स्टार्ट को शीर्ष पर ले जाया और अब कुछ मिलीसेकंड लेते हैं।

संबंधित मुद्दे