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

2024-02-27

我们对 Magento 2 的 Api 存在一个问题,涉及全页缓存以及来自 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”标头,如果在请求中设置了该标头,那么我们就允许正常刷新缓存。此外,我们还必须实现类似的功能,以防止在管理中保存类别和产品自动刷新缓存和 acl,以阻止营销部门访问全页缓存:)。

** 我们使用 Mirasvits 缓存预热扩展来预热我们的缓存,他们还在其扩展中实现了类似的功能,以防止管理员(而非 API)刷新缓存。https://mirasvit.com/magento-2-extensions/full-page-cache-warmer.html 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));
            }
        }
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

  • 在 MVC 应用程序中配置 NHibernate 二级缓存

    我有一个使用 NHibernate 的 MVC3 应用程序 一切都很顺利 直到我开始尝试添加二级缓存 浏览网页几个小时后 我终于找到了我认为正确的 dll NHibernate Caches SysCache2 dll 并将其添加到我的项目
  • 具有 .net core 后端和 .net 身份的 React SPA 应用程序

    我基本上有与这里详细说明的相同的问题 使用 asp Core 2 0 和 React 进行登录重定向 https stackoverflow com questions 48337368 但那个帖子从未得到答复 我已经搜索了很多 几乎我的问
  • 在 Spring Boot 中重新加载/刷新缓存

    我正在使用 Spring Boot 对于缓存 我使用 Ehcache 到目前为止一切正常 但现在我必须重新加载 刷新 那么我该如何执行此操作 以便我的应用程序不会出现任何停机时间 我在Spring Ehcache中尝试了很多方法 但它不起作
  • Zend_Cache_Backend_Sqlite 与 Zend_Cache_Backend_File

    目前我正在使用 Zend Cache Backend File 来缓存我的项目 尤其是来自外部 Web 服务的响应 我在想是否能找到将结构迁移到 Zend Cache Backend Sqlite 的一些好处 可能的优点是 文件系统有序 缓
  • RESt api:根据身份验证对资源和内容进行识别

    我正在设计一个遵循 HATEOAS REST 原则的 API 但我不确定这个基本点 资源识别 假设这个网址 images它公开了用户 向该用户 上传的所有图像 假设我使用 oauth 访问令牌进行身份验证 images 的内容将根据授权标头
  • Spring Data Redis 覆盖默认序列化器

    我正在尝试创建一个RedisTemplatebean 将具有更新的值序列化器来序列化对象JSONredis 中的格式 Configuration class RedisConfig Bean name redisTemplate Prima
  • 使用启用了两步身份验证的 python 脚本从 nextcloud 下载文件

    我设置了一个 nextcloud 实例 我想使用 python 脚本从那里下载文件 我的 nextcloud 实例对所有用户强制执行两步身份验证 我希望它保持这种状态 我梦想的场景是使用requests库 因此请按照此处的文档进行操作htt
  • 你可以拥有你的 API 并在 Laravel 中使用它吗?

    我制作了一个在 Laravel 中返 回 json 的 API 路线 api php 现在我想在我的内部使用所述APIweb项目的一侧 路线 web php 包括中间件 刀片视图 etc 我当前的解决方案是这样的 public functi
  • 如何通过Grape API获取路由

    我使用 gem grape 作为 api 我尝试通过命令获取 api urlrake grape routes namespace grape do desc routes task routes gt environment do API
  • 使用 AFNetworking 的 setImageWithURL 时如何配置缓存

    我在用着setImageWithURL在我的应用程序中下载一些图像 是否可以 指定此图像必须在缓存中保存多长时间 例如 1 周 指定缓存的最大总大小有多大 例如 200 兆 查看图像缓存中有什么 清除缓存 文档 http engineeri
  • ASP.NET MVC3 IIS7.5:Cache-Control maxage 始终为 0(不利于客户端缓存)

    我正在使用 Fiddler 测试我的网站 并注意到网络服务器总是返回 Cache Control private s maxage 0 用于动态内容 MVC 操作 这可以防止页面在客户端缓存 不知道是MVC还是IIS的问题 我该如何修复它
  • 使用 RSpec 进行 Rails 片段缓存测试

    我觉得这是一个没有太多记录的主题 至少我在这里找到最佳实践时遇到了很多麻烦 我使用 cache key 在视图中进行片段缓存 tbody employees each do employee cache employee do tr emp
  • 将代码保存在 L1 缓存中

    我一直在阅读维基百科关于 K 编程语言的文章 http en wikipedia org wiki K programming language Performance characteristics这就是我所看到的 解释器的小尺寸和语言的
  • 如果单个 POST 请求创建多个资源,是否被认为是 RESTful?

    我们有客户 API 它采用 customer name customer mobile customer email 并在数据库中创建客户 我们还有接受 productId customer name customer mobile cus
  • Web API 缓存 - 如何使用分布式缓存实现失效

    我有一个 API 目前不使用任何缓存 我确实有一个正在使用的中间件 它可以生成缓存标头 Cache Control Expires ETag Last Modified 使用https github com KevinDockx HttpC
  • Twitch API - 无法使用 PHP 获取身份验证令牌

    stackoverflow 的成员们大家好 我不是一个喜欢寻求帮助的人 但在这种情况下 我认为这是解决我的问题的唯一方法 谷歌并没有给我太大帮助 所以 我的问题 我想使用 Twitch API 获取一些数据 听起来很容易 我希望是这样 下面
  • 文件缓存:查询字符串与上次修改时间?

    我正在研究缓存网站资源的方法 并注意到大多数与我类似的网站都使用查询字符串来覆盖缓存 例如 css style css v 124942823 后来 我注意到每当我保存 style css 文件时 最后修改的标头都会 更新 使得查询字符串变
  • Mathematica 中的数据缓存

    有一个非常耗时的操作在我的包中生成数据集 我想保存此数据集 并仅在我手动删除缓存文件时才让包重建它 这是我的方法作为包的一部分 myDataset Module fname data fname cached data mx If File
  • 为我的网站构建 API 哪个更好:MVC 或 Ado.net 数据服务?

    我有一个用MVC构建的网站 现在我想为这个网站构建一个API 让用户使用这个API来实现不同的网站 Web服务 插件和浏览器扩展 我经历过这个article http weblogs asp net cibrax archive 2010
  • axios响应不显示数据

    我正在学习使用 Axios 但输出如图所示 当我使用 fetch 时 输出正常 我该如何修复 Axios const axios require axios default const url https jsonplaceholder t

随机推荐

  • 如何修复 strcpy 以便检测重叠字符串

    在一次采访中 我被要求编写一个实现strcpy https en cppreference com w c string byte strcpy然后修复它 以便它正确处理重叠的字符串 我的实现如下 非常幼稚 我该如何修复它 以便 它检测重叠
  • 如何使用特定版本的 ChromeDriver,同时 Chrome 浏览器通过 Python selenium 自动更新

    我是 Selenium 的新手 现在我可以使用 selenium 和 Chromedriver 进行基本的自动测试 代码工作正常 但问题是 Chrome 浏览器总是在后端自动更新 并且 Chrome 更新后代码总是无法运行 我知道我需要下载
  • 如何避免JFrame EXIT_ON_CLOSE操作退出整个应用程序?

    我有一个可以启动其他应用程序的应用程序 例如扩展坞 问题是 如果我正在启动的应用程序 JFrame 有EXIT ON CLOSE它还将关闭我的主应用程序 我无法控制我正在启动的应用程序 也就是说 我不能期望应用程序具有良好的行为和使用DIS
  • JQuery 的黄色淡入淡出效果

    我想实现类似的东西37Signals 的黄色淡出效果 http www 37signals com svn archives 000558 php 我正在使用 Jquery 1 3 2 代码 function fn yellowFade f
  • CRC-CCITT (0xFFFF) 功能?

    有人可以帮我用 Delphi 实现 CRC CCITT 0xFFFF 已经获得 Java 版本 但对如何将其移植到 Delphi 感到困惑 public static int CRC16CCITT byte bytes int crc 0x
  • C++ 可能的空指针取消引用

    我对一些代码运行了 cppcheck 以查找可能的运行时错误 在以下情况下 它报告可能存在空指针取消引用 Foo x defined somewhere Foo y x possible null pointer dereference 编
  • 使用 std::for_each 改变对象可以吗?

    for each 接受 InputIterators from c standard template
  • Team Foundation 服务 签入时的强制性评论

    我正在使用 Microsoft 的新 Team Foundation Service http tfs visualstudio com http tfs visualstudio com 我想知道是否可以在办理入住时强制提出评论 例如如果
  • 如何使用用户栏进行交易?

    我得到了使用 sqlalchemy continuum 的建议 它似乎可以立即完成我想要的功能 默认情况下 ORM 假定存在一个用户列 我确实想保存编辑的发起者 但是只说 这就是指定 User 类的方式 而没有说明实际使用版本化表时如何指定
  • 将 HTML 转换为 Word 文件?

    如何将 ruby 文件转换为 word 文件 即 docx 文件 对于pdf 大家宝石大虾 但是有没有word文件的gem 我正在尝试将我的html文件转换为word文件 以便用户也可以编辑它 这种情况应该怎么办 我本来打算将该文件转换为w
  • 白线出现在特定浏览器宽度的渐变填充 div 的末尾

    我有一个带有 id 的 div gradient div with a background image set to linear gradient 我在线性渐变的末尾和 div 的末尾之间发现了间隙 gradient div仅在某些浏览
  • 如何动态访问 Django 模型字段详细名称?

    我想访问我的模型字段 verbose name 我可以通过这样的字段索引来获取它 model meta fields 2 verbose name 但我需要动态获取它 理想情况下应该是这样的 model meta fields locati
  • 使用 Spring Data 从 RDBMS 刷新 ElasticSearch 索引

    我有以下设置 Mysql RDBMS 服务器 弹性搜索服务器 我的要求是定期从 MYSQL RDBMS 复制数据并用它更新弹性服务器 目前我正在遵循以下方法 使用 Spring Data Jpa 从 MYSQL 读取所有数据的批处理作业 然
  • 如何在 Rust 中创建参数化测试?

    我想编写依赖于参数的测试用例 我的测试用例应该针对每个参数执行 我想看看每个参数是否成功或失败 我习惯用Java编写这样的东西 RunWith Parameterized class public class FibonacciTest P
  • STL容器的二进制兼容性

    假设我用 C 编写了一个 DLL 并且想要导出一个采用 std vector 参数的方法 我可以希望不同的 STL 版本之间有二进制兼容性吗 我不知道版本之间的兼容性有任何保证 甚至同一编译器上的发布和调试之间也没有保证 一种解决方案是为向
  • SQL:找出每个组每个 ID 的所有可能的年份组合

    我正在使用 Netezza SQL 我有以下关于学生 2010 2015 年 的数据集 my table 他们当前就读的学位专业 参加考试的日期以及考试结果 student id current major year exam result
  • Cakephp 导入控制器

    我是 cakephp 的新手 我想在我的控制器中导入控制器 所以我使用以下语法 这是我导入用户控制器的控制器 用户控制器 php function api work data this gt User gt find all this gt
  • 半角和全角字符的用途是什么?

    半角字符和全角字符的用途是什么 它们之间有什么区别 我很好奇是因为验证器 js https github com chriso validator js 一个开源字符串验证库 有几个函数可以评估form http en wikipedia
  • Pandas 用组值填充 NA [重复]

    这个问题在这里已经有答案了 给定以下数据框 import pandas as pd import numpy as np df pd DataFrame Site A A A B B B C C C Value np nan 1 np na
  • Magento 2 Rest Api 在产品更新时过于频繁地清除缓存

    我们对 Magento 2 的 Api 存在一个问题 涉及全页缓存以及来自 ERP 系统的其余 API 的更新 ERP 不断通过 API 推送库存 库存和产品更新 进而刷新每次产品更新的缓存 从而形成始终不缓存的网站 我们尝试包装 Flus