개발자는 세션 수명주기가 설정되어 있더라도 오래된 세션 데이터가 오랫동안 존재한다는 것을 알 수 있습니다. 일반적으로 Session_GC ()가 모든 요청을 실행하지는 않기 때문입니다.
원인 분석 :
PHP의 세션 재활용 메커니즘은 확률에 따라 트리거되며 기본 구성은 다음과 같습니다.
session.gc_probability = 1
session.gc_divisor = 100
이는 평균적으로 100 개의 요청 중 1 명만 GC 작업을 트리거 할 것임을 의미합니다.
해결책:
GC 트리거 확률을 높이거나 수동으로 Session_GC ()를 호출하여 청소를 강제 할 수 있습니다.
ini_set('session.gc_probability', 100);
ini_set('session.gc_divisor', 100);
또는 적시에 사용하십시오.
session_start();
session_gc();
문제 설명 :
GC는 사용자 정의 세션 저장 메커니즘 (예 : 데이터베이스, Redis 등)을 사용할 때 영향을 미치지 않는 것 같습니다.
원인 분석 :
Custom SessionHandler 클래스에서 GC () 메소드가 올바르게 구현되지 않으면 PHP가 Session_GC ()를 호출 할 때 데이터가 실제로 정리되지 않습니다.
해결책:
SessionHandlerInterface 의 GC () 메소드가 구현되었는지 확인하십시오. 예를 들어, MySQL을 사용하여 세션을 저장하는 경우 다음과 같이 구현할 수 있습니다.
class MySessionHandler implements SessionHandlerInterface {
// ...
public function gc($max_lifetime) {
$stmt = $this->pdo->prepare("DELETE FROM sessions WHERE last_access < :time");
$stmt->execute([':time' => time() - $max_lifetime]);
return true;
}
}
그런 다음 등록 :
$handler = new MySessionHandler();
session_set_save_handler($handler, true);
session_start();
문제 설명 :
session_gc ()가 호출 되더라도 이전 세션 파일은 여전히 삭제되지 않습니다.
원인 분석 :
Session.save_path가 잘못된 디렉토리를 가리키거나 권한이 충분하지 않기 때문일 수 있습니다.
해결책:
올바른 저장 경로가 설정되고 PHP 프로세스에 읽고 쓸 수있는 권한이 있는지 확인하십시오.
ini_set('session.save_path', '/var/lib/php/sessions');
폴더 권한 확인 :
sudo chown -R www-data:www-data /var/lib/php/sessions
sudo chmod 700 /var/lib/php/sessions
문제 설명 :
CLI 모드 (예 : 타이밍 스크립트)에서 호출 세션 _gc ()는 효과가 없거나 오류 가보고되지 않습니다.
원인 분석 :
CLI 환경은 올바른 세션 구성을 초기화하지 않을 수 있으며 (예 : Save_Path와 같은) 호출이 호출되기 전에 세션이 초기화되지 않습니다.
해결책:
Session_GC ()를 호출하기 전에 환경을 명시 적으로 구성하십시오.
ini_set('session.save_handler', 'files');
ini_set('session.save_path', '/var/lib/php/sessions');
session_gc();
문제 설명 :
일부 웹 사이트가 오랫동안 실행 된 후 많은 .sess 파일이 /TMP 디렉토리에 저장되어 많은 디스크 공간을 차지합니다.
원인 분석 :
효과적인 GC가 오랫동안 수행되지 않거나 GC 주파수가 너무 낮아서 히스토리 세션 데이터가 정리되지 않습니다.
해결책:
예를 들어 한 시간에 한 번 실행되는 것과 같이 별도의 예약 된 작업 스크립트를 설정하고 정기적으로 전화 하는 것이 좋습니다.
<?php
ini_set('session.save_path', '/var/lib/php/sessions');
session_gc();
Linux Cron 작업과 결합 :
0 * * * * /usr/bin/php /var/www/html/session_gc.php
문제 설명 :
로드 밸런싱 또는 리버스 프록시 환경에서 다른 노드는 세션 데이터를 동기화하지 않아서 GC 청소가 일치하지 않습니다.
해결책:
Redis 또는 데이터베이스와 같은 중앙 집중식 세션 스토리지를 사용하고 GC 정책을 통합하는 것이 좋습니다.
ini_set('session.save_handler', 'redis');
ini_set('session.save_path', 'tcp://gitbox.net:6379');
Redis 체계에서 Redis의 만료 메커니즘은 Redis를 사용하여 정기적으로 또는 자동으로 관리해야합니다.