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
  • 可以通过不同参数或者由服务端响应头来控制浏览器不缓存文件,也就不会去检查拿本地缓存锁。
目录
相关文章
|
2天前
|
存储 缓存 自然语言处理
深入PHP内核:理解Opcode缓存对性能的影响
【4月更文挑战第25天】 在提升PHP应用性能的众多策略中,Opcode缓存技术因其显著的效果和较低的复杂度而备受开发者青睐。本文将深入探讨Opcode缓存机制,解析其对PHP执行效率的提升原理,并通过实验数据展示启用Opcode缓存前后的性能差异。我们还将讨论几种流行的Opcode缓存工具,如APC、OpCache与APCu,并评估它们的优劣及适用场景,帮助开发者根据不同的项目需求做出合适的选择。通过本文,读者不仅能够了解Opcode缓存的工作原理,还能学会如何在实际项目中应用这一技术以优化PHP应用程序的性能。
|
19天前
|
缓存 NoSQL 数据库
关于高并发下缓存失效的问题(本地锁 && 分布式锁 && Redission 详解)
关于高并发下缓存失效的问题(本地锁 && 分布式锁 && Redission 详解)
30 0
|
5月前
|
缓存 NoSQL 安全
Redis缓存雪崩、击穿、穿透解释及解决方法,缓存预热,布隆过滤器 ,互斥锁
Redis缓存雪崩、击穿、穿透解释及解决方法,缓存预热,布隆过滤器 ,互斥锁
185 5
|
3月前
|
缓存 安全 Java
ReadWriteLock 读写锁实现一个缓存
ReadWriteLock 读写锁实现一个缓存
34 0
|
3月前
|
存储 缓存 PHP
|
9月前
|
存储 SQL 缓存
MySQL高级第三篇(共四篇)之应用优化、查询缓存优化、内存管理优化、MySQL锁问题、常用SQL技巧(二)
锁是计算机协调多个进程或线程并发访问某一资源的机制(避免争抢)。 在数据库中,除传统的计算资源(如 CPU、RAM、I/O 等)的争用以外,数据也是一种供许多用户共享的资源。如何保证数据并发访问的一致性、有效性是所有数据库必须解决的一个问题,锁冲突也是影响数据库并发访问性能的一个重要因素。从这个角度来说,锁对数据库而言显得尤其重要,也更加复杂。
369 0
|
9月前
|
存储 缓存 JSON
php开发实战分析(6):配置文件或缓存文件的生成与调用
php开发实战分析(6):配置文件或缓存文件的生成与调用
104 0
|
存储 缓存 负载均衡
PHP的分布式缓存是干什么的?具体如何实现?底层原理是什么?
PHP的分布式缓存是干什么的?具体如何实现?底层原理是什么?
145 0
|
存储 缓存 NoSQL
PHP 自带的缓存机制是什么?底层原理是什么?
PHP 自带的缓存机制是什么?底层原理是什么?
191 0

热门文章

最新文章