草庐IT

api - Magento 2 Rest Api 在产品更新时过于频繁地清除缓存

coder 2023-07-18 原文

Magento 2 的 Api 关于全页缓存和来 self 们 ERP 系统的其余 API 的更新存在问题。 ERP 不断地通过 API 推送库存、库存和产品更新,这反过来会刷新每次产品更新的缓存,从而形成一个始终没有缓存的网站。我们试图环绕 FlushCacheByTags 类以防止剩余调用刷新缓存。这似乎受到了打击,但缓存仍在清除中。这是类覆盖:

<?php
/**
 *
 * Copyright © 2016 Magento. All rights reserved.
 * See COPYING.txt for license details.
 */
namespace Namespace\Module\Magento\Framework\App\Cache;

/**
* Automatic cache cleaner plugin
*/
class FlushCacheByTags extends 
\Magento\Framework\App\Cache\FlushCacheByTags
{

/**
 * @var \Psr\Log\LoggerInterface
 */
protected $_logger;

/**
 * FlushCacheByTags constructor.
 * @param \Magento\Framework\App\Cache\Type\FrontendPool $cachePool
 * @param \Magento\Framework\App\Cache\StateInterface $cacheState
 * @param array $cacheList
 * @param null $tagResolver
 * @param \Psr\Log\LoggerInterface $_logger
 */
public function __construct(
    \Magento\Framework\App\Cache\Type\FrontendPool $cachePool,
    \Magento\Framework\App\Cache\StateInterface $cacheState,
    array $cacheList,
    \Psr\Log\LoggerInterface $_logger,
    $tagResolver = null

)
{
    parent::__construct($cachePool, $cacheState, $cacheList, $tagResolver);
    $this->_logger = $_logger;
}

/**
 * Clean cache on save object
 *
 * @param \Magento\Framework\Model\ResourceModel\AbstractResource $subject
 * @param \Closure $proceed
 * @param \Magento\Framework\Model\AbstractModel $object
 * @return \Magento\Framework\Model\ResourceModel\AbstractResource
 * @SuppressWarnings(PHPMD.UnusedFormalParameter)
 */
public function aroundSave(
    \Magento\Framework\Model\ResourceModel\AbstractResource $subject,
    \Closure $proceed,
    \Magento\Framework\Model\AbstractModel $object
) {
    $this->_logger->debug('CACHE SAVE - instance of: '. print_r(get_class($object),true));

    if (
            // is instance of
            /* @var $object \Magento\Catalog\Model\Product */
            $object instanceof \Magento\Catalog\Model\Product
        && (
            // is rest api request
            isset($_SERVER['REQUEST_URI']) && strpos($_SERVER['REQUEST_URI'],'/rest') === 0
            )
        && (
            // has data
            !empty($object->getData())
        )
    ) {
        $this->_logger->debug('Cache NOT flushed from API SKU#: '.print_r($object->getSku(),true));
        return $proceed($object);
    }

    return parent::aroundSave($subject, $proceed, $object);
}

/**
 * Clean cache on delete object
 *
 * @param \Magento\Framework\Model\ResourceModel\AbstractResource $subject
 * @param \Closure $proceed
 * @param \Magento\Framework\Model\AbstractModel $object
 * @return \Magento\Framework\Model\ResourceModel\AbstractResource
 * @SuppressWarnings(PHPMD.UnusedFormalParameter)
 */
public function aroundDelete(
    \Magento\Framework\Model\ResourceModel\AbstractResource $subject,
    \Closure $proceed,
    \Magento\Framework\Model\AbstractModel $object
) {
    $this->_logger->debug('CACHE DELETE - instance of: '. print_r(get_class($object),true));

    if (
        // is instance of
        /* @var $object \Magento\Catalog\Model\Product */
        $object instanceof \Magento\Catalog\Model\Product
        && (
            // is rest api request

            isset($_SERVER['REQUEST_URI']) && strpos($_SERVER['REQUEST_URI'],'/rest') === 0
        )
    ){
        $this->_logger->debug('Cache NOT flushed from API SKU#: '.print_r($object->getSku(),true));
        return $proceed($object);
    }
    return parent::aroundDelete($subject, $proceed, $object);
}
}

我们是否遗漏了什么?我们希望能够通过 API 将数据推送到数据库并自行处理刷新,而不是每次通过 API 更新产品。我们已经实现了缓存预热器来尝试抵消刷新,但它跟不上缓存刷新的频率。

这是我在 API 产品更新日志中看到的内容

[2017-06-09 21:26:05] report.DEBUG: CACHE SAVE - instance of: 
Magento\Catalog\Model\Product\Interceptor {"is_exception":false} []

[2017-06-09 21:26:05] report.DEBUG: Cache NOT flushed from API SKU#: 
270876 {"is_exception":false} []

[2017-06-09 21:26:05] report.DEBUG: cache_invalidate {"method":"PUT","url":"https://obscuredforsecurity.com/rest/all/V1/products/270876","invalidateInfo":{"tags":["catalog_product_0"],"mode":"matchingAnyTag"},"is_exception":false} []

最佳答案

为了解决这个问题,我们为 \Magento\PageCache\Observer\FlushCacheByTags

这是执行方法的基础知识。我们遇到了一个问题,在某些情况下我们确实希望 API 刷新缓存,因此我们实现了一个“FlushNow” header ,如果在请求中设置了该 header ,我们将允许缓存正常刷新。此外,我们还必须实现类似的功能,以防止在管理员中保存类别和产品时自动刷新缓存和 acl 以阻止营销部门访问整个页面缓存:)。

** 我们使用 Mirasvits 缓存预热扩展来预热我们的缓存,他们还在其扩展中实现了类似的功能,以防止缓存从管理员(非 API)中刷新。 https://mirasvit.com/magento-2-extensions/full-page-cache-warmer.html

    /**
 * overide for \Magento\PageCache\Observer\FlushCacheByTags
 * Log calls to cache instead of clearing it
 *
 * @param Observer $observer
 * @return void
 */
public function execute(Observer $observer)
{
    if ($this->_config->getType() == Config::BUILT_IN && $this->_config->isEnabled()) {
        /** @noinspection PhpUndefinedMethodInspection */
        $object = $observer->getEvent()->getObject();
        if (!is_object($object)) {
            return;
        }
        $tags = $this->_tagResolver->getTags($object);
        $flush = $this->request->getHeaders('flushNow');
        $flush = $flush ? $flush->getFieldValue() : false;

        if (!empty($tags)) {
            if (
                $flush == false && (
                    (bool) $this->_scopeConfig->getValue(self::BLOCK_ALL)
                    || (
                        (bool) $this->_scopeConfig->getValue(self::BLOCK_API_CRON)
                        && (
                            !isset($_SERVER['REQUEST_URI'])
                            || preg_match('/^\/rest\/all\/V1/', $_SERVER['REQUEST_URI'])
                        )
                    )
                )
            ) {
                // Blocked entirely, Magento cron, or API request - Don't flush
                if ((bool) $this->_scopeConfig->getValue(self::DEBUG_LOG)) {
                    $this->writeToLog($tags);
                }
            }  else {
                if($flush){
                    $this->eventLogger->saveLog('cache_management','clean',json_encode($tags),true, 'api_cache_flush', true);
                }
                $this->_fullPageCache->clean(\Zend_Cache::CLEANING_MODE_MATCHING_ANY_TAG, array_unique($tags));
            }
        }
    }
}

关于api - Magento 2 Rest Api 在产品更新时过于频繁地清除缓存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44466898/

有关api - Magento 2 Rest Api 在产品更新时过于频繁地清除缓存的更多相关文章

  1. ruby-on-rails - ActionController::RoutingError: 未初始化常量 Api::V1::ApiController - 2

    我有用于控制用户任务的Rails5API项目,我有以下错误,但并非总是针对相同的Controller和路由。ActionController::RoutingError:uninitializedconstantApi::V1::ApiController我向您描述了一些我的项目,以更详细地解释错误。应用结构路线scopemodule:'api'donamespace:v1do#=>Loginroutesscopemodule:'login'domatch'login',to:'sessions#login',as:'login',via::postend#=>Teamroutessc

  2. 【鸿蒙应用开发系列】- 获取系统设备信息以及版本API兼容调用方式 - 2

    在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList​()Obt

  3. ruby-on-rails - Mandrill API 模板 - 2

    我正在使用Mandrill的RubyAPIGem并使用以下简单的测试模板:testastic按照Heroku指南中的示例,我有以下Ruby代码:require'mandrill'm=Mandrill::API.newrendered=m.templates.render'test-template',[{:header=>'someheadertext',:main_section=>'Themaincontentblock',:footer=>'asdf'}]mail(:to=>"JaysonLane",:subject=>"TestEmail")do|format|format.h

  4. 神州数码无线产品(AC+AP)配置 - 2

    注意:本文主要掌握DCN自研无线产品的基本配置方法和注意事项,能够进行一般的项目实施、调试与运维AP基本配置命令AP登录用户名和密码均为:adminAP默认IP地址为:192.168.1.10AP默认情况下DHCP开启AP静态地址配置:setmanagementstatic-ip192.168.10.1AP开启/关闭DHCP功能:setmanagementdhcp-statusup/downAP设置默认网关:setstatic-ip-routegeteway192.168.10.254查看AP基本信息:getsystemgetmanagementgetmanaged-apgetrouteAP配

  5. 阿里云RDS——产品系列概述 - 2

    基础版云数据库RDS的产品系列包括基础版、高可用版、集群版、三节点企业版,本文介绍基础版实例的相关信息。RDS基础版实例也称为单机版实例,只有单个数据库节点,计算与存储分离,性价比超高。说明RDS基础版实例只有一个数据库节点,没有备节点作为热备份,因此当该节点意外宕机或者执行重启实例、变更配置、版本升级等任务时,会出现较长时间的不可用。如果业务对数据库的可用性要求较高,不建议使用基础版实例,可选择其他系列(如高可用版),部分基础版实例也支持升级为高可用版。基础版与高可用版的对比拓扑图如下所示。优势 性能由于不提供备节点,主节点不会因为实时的数据库复制而产生额外的性能开销,因此基础版的性能相对于

  6. ruby-on-rails - 在 Ruby (on Rails) 中使用 imgur API 获取图像 - 2

    我正在尝试使用Ruby2.0.0和Rails4.0.0提供的API从imgur中提取图像。我已尝试按照Ruby2.0.0文档中列出的各种方式构建http请求,但均无济于事。代码如下:require'net/http'require'net/https'defimgurheaders={"Authorization"=>"Client-ID"+my_client_id}path="/3/gallery/image/#{img_id}.json"uri=URI("https://api.imgur.com"+path)request,data=Net::HTTP::Get.new(path

  7. ruby-on-rails - 使用 HTTParty 的非常基本的 Rails 4.1 API 调用 - 2

    Rails相对较新。我正在尝试调用一个API,它应该向我返回一个唯一的URL。我的应用程序中捆绑了HTTParty。我已经创建了一个UniqueNumberController,并且我已经阅读了几个HTTParty指南,直到我想要什么,但也许我只是有点迷路,真的不知道该怎么做。基本上,我需要做的就是调用API,获取它返回的URL,然后将该URL插入到用户的数据库中。谁能给我指出正确的方向或与我分享一些代码? 最佳答案 假设API为JSON格式并返回如下数据:{"url":"http://example.com/unique-url"

  8. ruby-on-rails - 是否使用 API - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我的公司有一个巨大的数据库,该数据库接收来自多个来源的(许多)事件,用于监控和报告目的。到目前为止,数据中的每个新仪表板或图形都是一个新的Rails应用程序,在巨大的数据库中有额外的表,并且可以完全访问数据库内容。最近,有一个想法让外部(不是我们公司,而是姊妹公司)客户访问我们的数据,并且决定我们应该公开一个只读的RESTfulAPI来查询我们的数据。我的观点是-我们是否也应该为我们的自己

  9. ruby - Ruby 中的必应搜索 API - 2

    我读了"BingSearchAPI-QuickStart"但我不知道如何在Ruby中发出这个http请求(Weary)如何在Ruby中翻译“Stream_context_create()”?这是什么意思?"BingSearchAPI-QuickStart"我想使用RubySDK,但我发现那些已被弃用前(Rbing)https://github.com/mikedemers/rbing您知道Bing搜索API的最新包装器(仅限Web的结果)吗? 最佳答案 好吧,经过一个小时的挫折,我想出了一个办法来做到这一点。这段代码很糟糕,因为它是

  10. python - 用于 Python 或 Ruby 的 Amazon Book API? - 2

    这个问题在这里已经有了答案:关闭10年前。PossibleDuplicate:AmazonAPIlibraryforPython?我正在寻找一个AmazonAPI,它可以让我:按书名或作者查找书籍显示书籍封面获取有关每本书的信息(价格、评级、评论数、格式、页数等)Python或Ruby库都可以(我只想要最容易使用的库)。有什么建议么?我知道在SO上还有其他一些关于此的帖子,但这些API似乎很快就过时了。[几个月前我尝试了几个建议的Ruby库,但无法让它们中的任何一个工作。]

随机推荐