caching 설정 - 전체 페이지 캐싱이 켜진 상태에서 제품 페이지에 동적 블록을 포함하려면 어떻게합니까?




캐시 서버 (5)

제품 페이지에 동적 블록을 추가하고 싶습니다. 문제는 제품 페이지에 전체 페이지 캐싱이 있고 속도 문제로 인해 페이지를 캐싱 할 수 없다는 것입니다. 로그인 한 사용자의 계정을 기반으로 각 제품 페이지에 다른 정보를 표시하려고하며 제품마다 다릅니다.

자체 캐시가있는 별도의 블록을 만들었지 만 이전 제품 페이지와 동일한 블록을 표시합니다. 캐시 방법을 변경하여 이전 제품 페이지의 캐시를 저장하지 않으려 고합니다.

처음 몇 번 제품 페이지로 이동하지만 갑자기 Magento 오류 페이지가 표시되기 시작합니다. " http://www.mycompany.com/productpage.html 을 검색하는 동안 웹 사이트에서 오류가 발생했습니다. 다운되거나 유지 보수가 잘못되거나 잘못 구성되었습니다. "

여기까지 제가 한 일이 있습니다. app / code / local / MyCompany / MyModule / PageCache / etc / config.xml을 작성하여 MyCompany_PageCache_Model을 추가했습니다.

그런 다음 app / code / local / MyCompany / MyModule / PageCache / Model / Container / MyFile.php에서 다음 함수를 사용하여 캐싱을 제어하는 ​​파일을 만들었습니다.

protected function _getCacheId()
{
    return 'CONSTANT_CACHE' . md5($this->_placeholder->getAttribute('cache_id'));
}

protected function _saveCache($data, $id, $tags = array(), $lifetime = null)
{
    return false;
}

protected function _renderBlock()
{
    $blockClass = $this->_placeholder->getAttribute('block');
    $template = $this->_placeholder->getAttribute('template');

    $block = new $blockClass;
    $block->setTemplate($template);
    $block->setLayout(Mage::app()->getLayout());
    return $block->toHtml();
}

나는 또한 CONSTANT_CACHE에 대한 내 자리 표시 자와 함께 Catalog / etc 아래에 cache.xml을 만들었습니다.

위의 구문이 올바르지 않습니까? 아니면 더 쉬운 방법이 있습니까?


Answers

일반적으로 전체 페이지 캐시에 저장하려는 페이지를 개인 설정하려는 경우 사용할 수있는 두 가지 방법이 있습니다.

  1. 역방향 프록시에서 지원하는 경우 ESI (Edge Side Includes)를 사용하여 템플릿을 적절하게 마크 업할 수 있습니다. ESI를 사용하면 생성 된 HTML에 개인화 된 컨텐츠가있는 마커를 삽입 할 수 있습니다. 그러면 프록시는 필요할 때 앱 서버의 적절한 컨트롤러 경로에서 개인화 된 컨텐츠 만 요청합니다. Varnish 사용 중이면 ESI를 사용할 수 있습니다. Magento의 Lightspeed 확장 기능은 " Hole Punching" 기능과 비슷한 기능을합니다.
  2. ESI 또는 구멍 펀칭을 사용할 수없는 경우 다른 옵션은 기본 페이지가 전체 페이지 캐시에 캐시되도록하고 약간의 자바 스크립트를 사용하여 별도의 Ajax 요청을 작성하고 필요한 정보를 가져 오는 것입니다.

개요

대답을하기 위해 나는 약간 설명 할 필요가있다. Magento FPC 프로세스는 네 가지 상태를 알고 있습니다.

  1. 캐시 된 페이지, 동적 블록 없음
  2. 캐시 된 페이지, 동적 블록 캐시 됨
  3. 캐시에있는 페이지, 캐시되지 않은 동적 블록
  4. 캐시에없는 페이지

상태 1과 2는 완전한 Magento 응용 프로그램을 초기화하지 않고 처리됩니다. 상태 3과 4는 응용 프로그램을 초기화하고 라우팅을 처리해야합니다. 따라서 가능한 경우 주 1과 2의 요청을 처리하는 것이 좋습니다. 그렇지 않으면 FPC의 가능한 개선 사항 중 상당 부분을 잃게됩니다.

상태 1

상태 1은 개발자 입장에서 볼 때 지루하고, 할 일이 없으므로 다음으로 넘어갈 수 있습니다.

주 2

상태 2에서 페이지는 동적 블록을 포함합니다. Magento가 완전히 초기화되지 않았습니다 .
FPC 프로세서는 캐시 된 페이지를로드하고 그 안에 동적 블록의 자리 표시자를 찾습니다.
자리 표시자를 분석하여 프로세서는 동적 블록에 대한 컨테이너 클래스를 식별하고 인스턴스화 한 다음 해당 인스턴스에서 applyWithoutApp($content) 를 호출 할 수 있습니다. (메서드의 이름은 지금까지 Magento 응용 프로그램이 초기화되지 않았 음을 나타냅니다.) 그런 다음 컨테이너는 $this->_getCacheId() 메소드에 의해 반환 된 캐시 키를 사용하여 블록 캐시에서 동적 블록 내용을로드하려고합니다.
캐시 키가 반환되고 캐시 항목을로드 할 수 있으면 컨테이너 클래스는 $content 의 자리 표시자를 캐시 된 블록 출력으로 바꾸고 FPC가 완료됩니다.
지금까지 많은 오버 헤드가 발생하지 않았습니다.

상태 3

따라서 상태 2의 applyWithoutApp($content) 는 동적 블록 내용을 가져오고 전달할 수 없으므로 나머지 페이지가 FPC에서 발견 되었더라도 블록 내용을 생성해야합니다.
이 목적을 위해 FPC 모듈은 pagecache/request/process 요청을 설정하고 정기적 인 Magento 응용 프로그램 초기화 및 라우팅이 수행됩니다.
즉, URL 재 작성이 건너 뛰기 때문에 FPC가없는 일반 페이지로드보다 조금 나아졌지만 상태 2에서 훨씬 많은 오버 헤드가 발생합니다.
마지막으로 프론트 컨트롤러와 표준 라우터는 요청을 RequestController::processAction() 메소드에 위임합니다.
이 메소드는 동적 블록에 대해 이전에 인스턴스화 된 컨테이너 클래스를 가져 applyInApp($content) 를 호출합니다.
이 메소드는 $this->_renderBlock() 을 실행하여 실제 블록 클래스를 인스턴스화하고 출력을 리턴합니다. 당신은 이미 당신의 질문에 따라이 방법을 구현했습니다. 이제 FPC는 자리 표시자를 블록 내용으로 대체하고 페이지를 전달할 수 있습니다.
한 가지주의해야 할 점 은 이것이 일반 제품 세부 정보 페이지 요청이 아니라는 것입니다. 예를 들어 Mage::registry('current_product') 를 사용할 수 없습니다! 블록 구현에 따라 동적 블록의 블록 수준 캐싱 또는 컨텐트 생성에 영향을 줄 수 있습니다. 이 문제가 어디서 발생했는지는 의심 스럽지만 좀 더 아래로 해결 방법을 찾아 보겠습니다.

주 4

이 상태에서 FPC는 요청한 페이지에 대한 캐시 레코드를 찾지 못해 Magento가 페이지를 평소처럼 생성합니다. 예를 들어 제품 세부 정보 페이지 출력은 Mage_Catalog_ProductController::viewAction() 의해 생성됩니다.
cache.xml 에 따라 동적으로 구성된 모든 블록은 자리 표시 자 태그에 래핑됩니다.
자리 표시 자 태그에는 나중에 2 단계와 3 단계의 컨테이너 객체에 전달되는 인수가 포함됩니다. 항상 설정되는 유일한 인수는 컨테이너 및 블록 클래스 이름입니다. 하지만 거의 항상 cache_idtemplate 이 설정됩니다.
컨테이너 클래스에서 이러한 값은 컨테이너의 _getCacheId () 메소드에서와 같이 $this->_placeholder->getAttribute('cache_id') 사용하여 액세스 할 수 있습니다.

비록 당신이이 긴 답변의 대부분을 어디에 비추고 있더라도, 이것이 당신에게 흥미로울 수있는 곳입니다. 블록 캐시 ID 또는 블록 출력 (예 : 제품 ID 또는 고객 ID)을 생성하는 데 추가 값이 필요한 경우 이를 플레이스 홀더의 인수로 설정할 수 있습니다 .

그렇게하려면 배열 getCacheKeyInfo() 메소드가 반환 한 배열에 문자열을 배열 키로 설정해야 합니다. 숫자 배열 인덱스를 사용하는 경우에는 자리 표시 자에 인수로 설정되지 않습니다.

public function getCacheKeyInfo() {
    $info = parent::getCacheKeyInfo();
    $info['current_product_id'] = Mage::registry('current_product')->getId();
    $info['customer_id'] = Mage::getSingleton('customer/session')->getCustomerId();
    return $info;
}

이 값은 이제 $this->_placeholder->getAttribute('current_product_id') 사용하여 컨테이너 클래스에서 액세스 할 수 있습니다.

결론

false 를 반환하려면 컨테이너 클래스에서 _saveCache() 를 재정의하고 싶지 않을 것입니다. 대신 _getCacheId() 반환 한 문자열에 고객 ID와 제품 ID를 포함하십시오. 그렇게하면 각 고객은 자신의 캐시 항목을 갖게됩니다. applyWithoutApp() 는 캐시에서 동적 블록을 저장하고로드 할 수 applyWithoutApp() 페이지가 동일한 고객에 의해 두 번 표시되는 경우 applyWithoutApp() 오버 헤드가 줄어 듭니다.

_renderBlock() 에서 블록이 내용을 생성 할 수 있도록 필요한 추가 값을 설정합니다 _renderBlock() 예 :

$block->setProductId($this->_placeholder->getAttribute('current_product_id'));

제품 ID 및 고객 ID를 포함하여 블록 정보 측면에서 캐시 정보 배열에있는 블록은 캐시 된 경우에도 각 고객이 요청한 페이지에 대해 올바른 결과를 얻도록 보장합니다.

분명히 알 수는 없지만 (블록 코드는 제공하지 않음) 사용중인 캐시 ID에 블록의 캐시 레코드를 올바른 제품에 고유하게 매핑하는 데 필요한 모든 인수가 포함되어 있지 않은 것 같습니다. .

이 단계를 사용하고 인수를 동적 블록 컨테이너에 전달하는 방법을 알고 있으면 사용자 정의 동적 블록을 만들 때도 FPC 성능 이득의 대부분을 유지할 수 있습니다. 이 정보가 당신이 설명하고있는 문제를 추적하여 해결할 수 있기를 바랍니다.


다음을 수행 할 필요가 없습니다.

  $info['current_product_id'] = Mage::registry('current_product')->getId();

이 방법을 사용할 수 있습니다 :

$this->_getProductId()

Enterprise_PageCache_Model_Container_Abstract에서 구현 됨


Vinai의 답변에 정말 감사드립니다. 또한, 나는 구멍 뚫기를 지원하는 Gordon Lesti의 FPC 확장을 sugggest 할 것입니다. 너는 그것을 여기에서 얻을 수있다.

이 확장 기능으로 구멍 뚫기가 작동하는 방법에 대한 지침은 이 페이지 를 방문하는 것이 좋습니다 .

개념에 익숙하지 않은 사람에게 도움이되기를 바랍니다.


속도를 높이려면 몇 가지 방법이 있습니다.

  1. CDN을 사용하여,
  2. 캐싱 사용,
  3. 부하 분산 서버를 사용하여,
  4. 압축 사용,
  5. 부트 스트랩 활성화,
  6. 데이터베이스 및 db 드라이버 최적화

다음 서버 가속 방법을 사용할 수 있습니다.

  1. mod_deflacte 활성화
  2. memchached 사용




caching magento