PHP 세션 핸들러에 의해 잠금이 설정되어 있기 때문에 문제가 발생합니다. 따라서 Magento가 명시 적으로 무언가를 잠그고 관리자 요청을 차단하려고 시도하지는 않지만 파일 기반 세션 저장소의 부작용은 거의 없습니다.
초기 (장기 실행) 요청으로 세션 데이터 파일을 열면 세션 데이터 파일에 쓰기 잠금이 설정되어 호출 할 때 잠금이 해제 될 때까지 두 번째 요청이 차단 session_start
됩니다.Mage_Core_Model_Session_Abstract_Varien::start
이것은 100 % 재현 가능합니다. 나는를 추가, 당신이했던 것과 같은 방법을 사용 sleep(30)
의 정상에Mage_Adminhtml_IndexController::globalSearchAction
DB 세션 스토리지를 사용하는 경우이를 재현 할 수 없습니다. 근본 원인을 찾은 후 샌드 박스를 db 세션 스토리지로 설정하여 더 이상 문제를 재현 할 수 없었습니다. 따라서 DB 세션 핸들러 Magento는 행 수준 잠금을 사용하여 세션 쓰기를 잠그지 않은 것 같습니다. 응용 프로그램이 동일한 세션에 쓰는 여러 스레드를 분명히 고려하지 않기 때문에 세션 데이터 손실 가능성이 있기 때문에이 흥미로운 것을 발견했습니다. 독자를위한 참고 사항 : 프로덕션에서 db 세션 저장소를 사용 하여이 문제를 해결하려고 시도하지는 않습니다 .MySql 데이터베이스를 오버로드하는 경우에만 좋습니다.
Redis와 같은 메모리 기반 세션 스토리지 시스템을 사용하여 동작을 재현하려고 시도하지 않았지만 세션 저장소의 레코드 잠금이 아마도 간과되었을 것입니다.
session_write_close
장기 실행 작업을 시작하기 전에 잠금을 해제하는 데 사용 하는 것과 같이이를 피하기 위해 사용할 수있는 기술이 있습니다 . 그러나 이것은 방금 세션을 닫았으므로 세션에 글을 쓰지 못하게합니다. 따라서 Magento의 전반에 걸쳐 쉽게 구현되지는 않지만 특정 경로 / 제어기에서 구현 될 수 있습니다.
근본 원인으로 이것을 고정시키는 나의 기술은 Xdebug 프로파일 러를 활성화하고 "cachegrind"파일을 검사하는 것입니다. 두 번째 요청이 완료되면 출력 파일 (~ 25MB 로그)을 MacCallGrind에로드 하고 포함 시간이 28 초 이상인 통화 경로에 따라 추적으로 드릴 다운했습니다. 이로 인해 session_start
약 28 초가 걸렸으며 연구에 큰 도움이되었습니다.
편집 : 관심을 끌기 위해 MacCallGrind에서 볼 수있는 "cachegrind"파일 의 스크린 샷 을 Twitter에 게시했습니다.