Chrome缓存锁,php非堵塞文件锁无效的问题详解追查

简介: 浏览器对一个资源发起请求前,会先检查本地缓存,此时这个请求对该资源对应的缓存的读写是独占的。此时后续的请求,在请求这个资源的时候,就需要等待拿锁。(在上面这个补丁发布之前,会无限等待,补丁是让等待最多20秒)

写在前面


为什么写下这篇文章 在编写PHP文件锁的时候,非堵塞模式 LOCK_NB 加了却没有效果 预期反应:当前面有请求在执行了,后续的请求马上返回客户端:拿不到锁,执行失败。 现实状况:假设业务逻辑需要执行5s,第一个请求发送后,马上有第二个请求发送,第二个请求会等待第一个请求结束,然后再执行自己本次请求,总共耗时10s


简单说说php写下的锁


为了后面更好地讲解和理解,简单带上php文件锁的几行代码


<?php
$p_file = "index.lock";
$o_file = fopen($p_file, 'w+');
// 非堵塞模型 拿不到锁马上返回false
$lock = flock($o_file, LOCK_EX  LOCK_NB);
if (!$lock) {
  var_dump('被锁了');
}else {
  sleep(5);
  echo "完成";
}


追寻之路


最直观地搜索


PHP LOCK_NB 无效 找文章 找到一篇文章如下:



d222dccd2db7bba01db692e354dfb6a9.png



引用


如果你是在本机测试,你要分两个不同的浏览器测试。 例如一个chrome,一个firefox, chrome先执行,firefox再行,就可以看到效果了,如果你用同一个浏览器会等待的。


确实,我们可以使用两个浏览器来执行,就可以达到预期想要的非堵塞效果。但是原因呢,几乎没有文章讲解。 宣言不会死心,想要坚持找到合适的答案。


猜测有什么会影响


根据不够成熟的经验,简单猜测


  • 服务端导致:可能由于系统等等特殊场景,会导致非堵塞失效。
  • 前端导致:可能由于浏览器处理问题,导致请求堵塞。


这两个排查顺序,首先我检查了PHP手册和其他站点的文章,确保函数和参数的使用正确,也没有在文档中发现比较特别的注意事项。 在Windows和Linux系统上都出现过此问题。所以也排除windows系统不支持的可能。 接下来就只能进行前端的排查,通过开发者面板——>网络请求——>尝试分析请求头/响应头等信息 一开始的猜想是:要么是客户端请求头,要么是服务端响应头,会有一个标识在等待或者转发等等 分析看到大概如下的情况 (请求里的请求头信息很少,很正常,所以看到外面的状态)


267b075db82deb9cc048dcc76b071def.png


此时显示的是Pending 在等待状态。


浏览器Pending状态


想要知道该状态会在什么情况下产生,搜索这方面的文章。。 看到的可能如下:


  • 建议你把浏览器先卸载,用360安全卫士清理系统后重装一下。
  • #现象Chrome打开任何网页都显示“喔唷崩溃啦”。#尝试关于页无法进入,没法升级浏览器;设置页无法进入,没法清除浏览数据或重置浏览器;


等等垃圾答复(机器人或者刷积分的)


但是,也有精品的文章


该文章属于FEX百度团队 《关于请求被挂起页面加载缓慢问题的追查》 在大概2014年的时候,百度团队追查前端偶发的缓慢请求(可能一两分钟)的一篇技术文章


涉及面非常专业,排查思路非常值得学习!赞!!


也是从中得到本篇文章想要的知识点 下面会陆续引用文章中的一小段内容


神秘的CACHE LOCK


稳重提到,在Stackoverflow上找到一问题,跟FEX面临的问题有些类似点:


  • 偶发,并不是必然出现的。这里我们的问题也是偶发,很难复现,需要反复刷。
  • 也是请求被Pending了很久,从请求的时间线来看,体现在Stalled上。


在问题中,有提供以下报错 ERR_CACHE_LOCK_TIMEOUT 20秒


t=33627 [st= 5] HTTP_CACHE_ADD_TO_ENTRY [dt=20001] –> net_error = -409 (ERR_CACHE_LOCK_TIMEOUT)


同时还有一段这样子的描述


The error message refers to a patch added to Chrome six months ago (https://codereview.chromium.org/345643003), which implements a 20-second timeout when the same resource is requested multiple times. In fact, one of the bugs the patch tries to fix (bug number 46104) refers to a similar situation, and the patch is meant to reduce the time spent waiting.


核心句子: 这是Chormeium发布的一个补丁:它在多次请求同一资源时实现20秒的超时。 也从中得知了浏览器有缓存锁的知识。


浏览器对一个资源发起请求前,会先检查本地缓存,此时这个请求对该资源对应的缓存的读写是独占的。此时后续的请求,在请求这个资源的时候,就需要等待拿锁。(在上面这个补丁发布之前,会无限等待,补丁是让等待最多20秒)


那么如何让浏览器不使用缓存锁呢


  • 对请求加个时间戳或者参数等让请求变得唯一
  • 或者服务器响应头设置为无缓存


嗯,先简单尝试一下,在Chrome中,打开文章一开始的php脚本,但是此时有一个请求带上参数 index.php?t=1index.php 顺利实现预期效果:一个执行5秒,一个马上返回拿锁失败的消息。


测试CACHE LOCK的超时时间


再简单修改sleep的时间为30,目的是测试上文补丁中说的,最长等待时间是20s。 第二个请求出现以下状况,完全符合。20秒后,拿不到该资源的本地缓存锁,则发送请求执行。


62cd6392c6874d3bd5672f0112f1de8f.png


总结


  • Chrome浏览器有缓存锁概念(其他浏览器还未测试)
  • PHP LOCK_NB没有失效,表面现象是因为前端特性导致的
  • Chrome的缓存锁超时时间是20s
  • 可以通过不同参数或者由服务端响应头来控制浏览器不缓存文件,也就不会去检查拿本地缓存锁。
目录
相关文章
|
3月前
|
缓存 NoSQL 网络安全
【Azure Redis 缓存】Azure Redis服务开启了SSL(6380端口), PHP如何访问缓存呢?
【Azure Redis 缓存】Azure Redis服务开启了SSL(6380端口), PHP如何访问缓存呢?
|
6月前
|
存储 缓存 自然语言处理
深入PHP内核:理解Opcode缓存与性能优化
【5月更文挑战第14天】 在动态语言的世界里,PHP一直因其高性能的执行效率和广泛的社区支持而备受青睐。随着Web应用的复杂性增加,对性能的要求也越来越高。本文将探讨PHP的Opcode缓存机制,解析其对性能提升的贡献,并展示如何通过配置和使用不同的Opcode缓存方案来进一步优化PHP应用的性能。我们将深入到PHP的核心,了解Opcode是如何生成的,以及它如何影响最终的执行效率。
|
1月前
|
缓存 NoSQL 数据处理
原生php实现redis缓存配置和使用方法
通过上述步骤,你可以在PHP项目中配置并使用Redis作为高性能的缓存解决方案。合理利用Redis的各种数据结构和特性,可以有效提升应用的响应速度和数据处理效率。记得在实际应用中根据具体需求选择合适的缓存策略,如设置合理的过期时间,以避免内存过度消耗。
50 0
|
3月前
|
缓存 NoSQL Java
SpringBoot整合Redis、以及缓存穿透、缓存雪崩、缓存击穿的理解、如何添加锁解决缓存击穿问题?分布式情况下如何添加分布式锁
这篇文章介绍了如何在SpringBoot项目中整合Redis,并探讨了缓存穿透、缓存雪崩和缓存击穿的问题以及解决方法。文章还提供了解决缓存击穿问题的加锁示例代码,包括存在问题和问题解决后的版本,并指出了本地锁在分布式情况下的局限性,引出了分布式锁的概念。
SpringBoot整合Redis、以及缓存穿透、缓存雪崩、缓存击穿的理解、如何添加锁解决缓存击穿问题?分布式情况下如何添加分布式锁
|
3月前
|
存储 缓存 自然语言处理
|
6月前
|
存储 缓存 PHP
深入PHP内核:理解Zend Engine与Opcode缓存
【5月更文挑战第30天】 在PHP的开发世界中,性能优化是一个永恒的话题。随着现代Web应用的复杂性日益增加,仅仅依靠代码层面的优化已经远远不够。本文将深入探讨PHP的执行心脏——Zend Engine,以及如何通过Opcode缓存机制提升PHP应用的执行效率。我们将透过对Zend Engine工作原理的分析,了解Opcode缓存的实现原理,并通过实例来展示其对性能提升的显著影响。
|
6月前
|
存储 缓存 自然语言处理
深入PHP内核:探索Opcode缓存机制
【5月更文挑战第1天】 在动态语言如PHP的执行过程中,每次脚本被请求时都需要经过一系列复杂的解析和编译步骤。为了优化这一过程并提高性能,PHP引入了Opcode缓存机制。本文将详细探讨Opcode的概念、作用以及它如何显著提升PHP应用的执行效率。我们将从缓存原理出发,分析几种常见的Opcode缓存工具,并通过实例说明如何在实际项目中实现和优化缓存策略。
|
6月前
|
存储 缓存 自然语言处理
深入PHP内核:探索Opcode缓存对性能的影响
【4月更文挑战第30天】 在动态内容生成的Web开发领域,PHP一直是广受欢迎的脚本语言之一。然而,由于其每次请求都需要经过解释执行的特性,性能上往往受到质疑。随着现代PHP引擎如Zend和Facebook的HipHop Virtual Bytecode (HPHPc)的出现,引入了Opcode(操作码)缓存机制来提升PHP的性能。本文将深入探讨Opcode缓存技术是如何工作的,以及它对PHP应用程序性能的具体影响。我们将通过实验数据与分析,揭示Opcode缓存在不同场景下的优势和局限性,并提出优化策略。
|
6月前
|
缓存 NoSQL PHP
【PHP 开发专栏】Redis 作为 PHP 缓存的解决方案
【4月更文挑战第30天】本文探讨了Redis作为PHP缓存的优势,如高性能、丰富数据结构、数据持久化和分布式支持。通过安装配置Redis、选择PHP客户端、执行读写操作及制定缓存策略实现缓存。应用场景包括页面、数据和会话缓存。但需注意数据一致性、过期时间、容量和安全问题,以确保应用稳定和安全。Redis能有效提升PHP应用响应速度和处理能力。
149 2
|
6月前
|
存储 缓存 自然语言处理
深入PHP内核:Opcode缓存与性能优化
【5月更文挑战第31天】 在提升PHP应用性能的众多策略中,Opcode缓存技术以其显著的性能提升效果而广受关注。本文旨在深入探讨PHP的Opcode缓存机制,解析其对性能提升的影响,并讨论如何通过配置和优化实践来充分利用Opcode缓存。文章将首先介绍Opcode的概念及其在PHP执行过程中的作用,然后分析几种流行的Opcode缓存解决方案,最后提供针对性的优化建议,帮助开发者实现高效的PHP应用。