개발 Q&A

제목 세션 Expired와 가비지 컬렉터 질문
글쓴이 2전산2 작성시각 2014/01/17 02:33:04
댓글 : 2 추천 : 0 스크랩 : 0 조회수 : 16185   RSS
[php 버전 : 5.4.21, apach 2.4, CI 2.1.4 입니다.]

안녕하세요? 메일 보기만 하다가 처음으로 질문 올리네요^^

다름이 아니라, 현재 운영하고 있는 사이트에서 특정 시간이 지나거나 또는 꽤 높은 확률로 ajax 실패시 또는

http 요청시 세션이 사라져서, 로그인이 끊기는 현상이 간헐적으로 발생하고 있습니다.

그래서 의심되는 부분을 여쭤보려고 합니다.

아래 코드는 CI_Session 클래스의 일부분인데요~

constructor 에서 매번 $this->_sess_gc(); 하는 것을 확인할 수 있는데요.

_sess_gc 함수에서는 디비세션을 사용할 경우 5%의 확률(페이지 요청 시)로 오래된 디비세션을 제거하는

쿼리를 수행하고 있습니다.

동접자가 꽤 있을 경우 이런식으로 세션을 처리하게 되면 접속한지 오래되지 않은 사용자라도 상대적으로 세션이

날아갈  수 있는 확률이 있지 않나요? 이 부분의 의심되어 한참 들여다 보고 있는데 디버깅이 쉽지가 않네요..

많은 조언 부탁 드립니다. ^^

class CI_Session {

 var $sess_encrypt_cookie  = FALSE;
 var $sess_use_database   = FALSE;
 var $sess_table_name   = '';
 var $sess_expiration   = 7200;
 var $sess_expire_on_close  = FALSE;

             중략....

        public function __construct($params = array())
        {
             중략....
             $this->_sess_gc();
        }


         /**
  * Garbage collection
  *
  * This deletes expired session rows from database
  * if the probability percentage is met
  *
  * @access public
  * @return void
  */
 function _sess_gc()
 {
     if ($this->sess_use_database != TRUE)
     {
        return;
     }

     srand(time());
     if ((rand() % 100) < $this->gc_probability)
     {
        $expire = $this->now - $this->sess_expiration;
        $this->CI->db->where("last_activity < {$expire}");
        $this->CI->db->delete($this->sess_table_name);
        log_message('debug', 'Session garbage collection performed.');
     }
  }
}
 
 다음글 인트라넷 도메인? (1)
 이전글 AWS 인스턴스에 svn을 구축 중입니다 (3)

댓글

2전산2 / 2014/01/17 02:39:37 / 추천 0
세션 관련 설정은 다음과 같이 되어 있습니다.
$config['sess_cookie_name'] = 'test';
$config['sess_expiration'] = 7200;
$config['sess_expire_on_close'] = TRUE;
$config['sess_encrypt_cookie'] = TRUE;
$config['sess_use_database'] = TRUE;
$config['sess_table_name'] = 'test';
$config['sess_match_ip'] = FALSE;
$config['sess_match_useragent'] = FALSE;
$config['sess_time_to_update'] = 600;
pwrlove / 2016/09/11 00:41:35 / 추천 0

너무 오래전 질문이긴한데, 아무도 답을 달지 않아서....,

_sess_gc();는 세션 객체가 생성될때마다 계속 호출되는 것은 맞습니다.

근데, 아무리 많이 호출되어도, 실제 계산된 $expire값을 이용해 세션 테이블값을 조회해서

last_activity값이 7200초가 넘은 값은 모두 삭제하도록 되어 있어서 실제 세션레코드는 호출되는 횟수와는

상관이 없어 보입니다.

sess_update() 가 적당히 호출되어서 

$expire = $this->now - $this->sess_expiration;

$this->CI->db->where("last_activity < {$expire}");

last_activity 값이 갱신되어서 위의 조건에 걸리지 않으면 테이블에서 삭제되지 않을 겁니다.

그런데, 종종 아무때나 세션이 삭제되는 것 같이 보이긴 하던데 이건 버그일까요?