作者mmis1000 (秋月恋枫)
看板PHP
标题[请益] php档案快取问题
时间Wed Nov 27 02:17:18 2013
各位版友好
小弟最近再做一个自动伺服器状态图的小程式,
但发现每次都重新产生的话,cpu会吃很凶
所以就用档案修改时间当判断,加上快取
和用header产生304减少流量
可是却发生了奇怪的状况
出问题的区段
http://pastebin.com/MrT5ZdjW
完整code
http://goo.gl/b1mlg0
因为第一次产生时有时会传输不全导致破图,
所以我在图片产生完的第一次输出,
并没有加上更新快取纪录的header
可是测试时却发现,图片还是被快取了
请问有人看得出是哪里出错吗?
像是逻辑上的问题之类。
麻烦了
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 140.116.130.56
1F:→ danny8376:如果用Chrome测 没关cache很正常 client端短时间cache 11/27 02:28
2F:→ danny8376:的行为是看浏览器高兴的 你还是让图片一次成功比较实际 11/27 02:29
3F:→ mmis1000:并不是短时间快取,而是长时间快取,得按 ^ F5才能刷新 11/27 02:33
4F:→ mmis1000:不知道图片不全是不是time out造成的 11/27 02:34
5F:→ danny8376:另外 要输出档案我会建议直接用readfile 11/27 02:34
6F:→ mmis1000:图片只会产生一次,第二次传的图片跟第一次是一样的 11/27 02:35
7F:→ danny8376:不过更要建议我会直接用x-sendfile之类的传cache档出去 11/27 02:35
8F:→ danny8376:可能真的是timeout问题吧 你可以试着增加timeout试试? 11/27 02:42
9F:→ mmis1000:刚用firefox开发者去看,明明不含last-modified 11/27 02:44
10F:→ mmis1000:If-Modified-Since 还是被更新了,不知道是不是bug... 11/27 02:44
11F:→ danny8376:这不是BUG Cache本来就不是没Last-Modified就不能做 11/27 02:51
12F:→ mmis1000:那如果把时间标注为0,标为过期呢? 11/27 02:53
13F:→ danny8376:你还是确保图片成功传送比较实际... 11/27 02:57
14F:→ mmis1000:如果无法正确判断header,连送304都会有问题啊... 11/27 03:01
15F:→ danny8376:反正刚刚试了下 我是没遇过破图啦 11/27 03:03
16F:→ danny8376:可能我伺服器太好了(X 11/27 03:03
17F:→ danny8376:我是比较建议你 可以直接PHP输出到cache之後 11/27 03:04
18F:→ danny8376:直接用Location的方式redirect过去 11/27 03:04
19F:→ danny8376:你只要确定那张图还能用 连要不要传304都不用管 11/27 03:05
20F:→ danny8376:反正丢给HTTP Server自己判断去 11/27 03:05
21F:→ danny8376:对了 不要再巧虎头了www 11/27 03:06
22F:→ mmis1000:听说那是firebug的bug,在chrome上测不出这种行为 11/27 03:06
23F:→ mmis1000:firebug好像会造成额外request,但却又没更新cache 11/27 03:07
24F:→ mmis1000:不直接重导向的理由是,要排程更新很麻烦 11/27 03:15
25F:→ mmis1000:而且会把code搞得很复杂,也不好处里未被使用的图 11/27 03:17
26F:→ danny8376:没啊 对外使用php的连结 php里再导去cache 11/27 03:17
27F:→ danny8376:这样还是要先走过php 只是最後输出改成location header 11/27 03:18
28F:→ mmis1000:是指header欧,我以为是mod_rewrite 11/27 03:22
29F:→ mmis1000:其实本来就只是暂时性的做法拉 11/27 03:23
30F:→ mmis1000:多人同时连线会让更新用的socket_client出问题... 11/27 03:24
31F:→ danny8376:其实用rewrite也行www rewrite可以写很复杂的www 11/27 03:26
32F:→ danny8376:我自己是用php放crontab去每分钟跑一次更新资料 11/27 03:27
33F:→ danny8376:然後要显示时才去资料库捞回来给人看 11/27 03:27
35F:→ mmis1000:多了一次无参数request,而且无视快取状态更新纪录 11/27 04:05
36F:推 alog:基本上你要让他图片不要被快取,有个方式 11/27 06:11
37F:→ alog:你至少要输出时的时候 Header 带 Cache-Control 11/27 06:19
38F:→ alog:或伺服端控制图片的 Header 11/27 06:19
39F:→ alog:至少都要有基本的 no-store no-cache private 11/27 06:19
40F:→ alog:另外就是图片的快取设计要改变,不是 Request 进来才产生图 11/27 06:20
41F:→ alog:而是你要用系统排程call你脚本 定时更新图 11/27 06:21
42F:→ alog:这样一来你的CPU占用的机会就会大幅缩小 11/27 06:21
43F:→ alog:再补充,输出完图,直接放在伺服端就可以了 11/27 06:23
44F:→ alog:直接让apache or nginx 直接把图抓出来输出给使用者 11/27 06:23
45F:→ alog:不论是记忆消耗或CPU占用度都会大大减低 11/27 06:24
46F:→ alog:另外就是在某种情况下,session_start 会影响到快取 11/27 06:24
47F:→ alog:因为他会提早告知browser或代理伺服器不要快取产生的网页 11/27 06:25
48F:→ danny8376:session对cache不会有影响 除非中间夹了cache server 11/27 06:52
49F:→ danny8376:有检查cookie差异来决定决定是否cache 11/27 06:53
50F:→ danny8376:不过这也不会影响到client端的cache行为 11/27 06:54
51F:→ danny8376:毕竟session_start唯一做的事只有再找不到SESSION ID时 11/27 06:55
52F:→ danny8376:随机产生SESSION ID塞到Cookie里而已 11/27 06:55
53F:推 alog:我印象走fastcgi就会,cache server是因为遵循http协定设计 11/27 06:55
54F:→ alog:你可以观察 header 输出,很有趣有开没开有差 11/27 06:56
55F:→ alog:我印象php的session start原始码会输出 阻止cache的header 11/27 06:58
56F:→ alog:session本身机制设计,资料不该被任何东西cache到会强制要求 11/27 06:59
57F:→ alog:那些装置或服务不能把资料给储存跟共享 11/27 07:00
58F:→ alog:当然如果那些程式硬要不遵守快取也没办法 11/27 07:01
59F:→ MOONRAKER:不是有一个烂招是图片名称後面带GET参数吗 11/27 10:59
60F:→ MOONRAKER:例如这样 x.jpg?t=38552120793 (用js随便加一个乱数) 11/27 11:00
61F:→ danny8376:楼上没看清楚啊www 他不是要"总是"不cache 11/27 11:35
62F:→ danny8376:而是PHP判定某种状况下才不给cache 11/27 11:35
63F:→ MOONRAKER:OUCH~~ 11/27 11:55
64F:→ MOONRAKER:果然看了半天还是看不懂 :~( 11/27 11:56
65F:→ mmis1000:request进来才确认产生图片的理由是 11/27 16:07
66F:→ mmis1000:因为图片每次更新不一定都会有人看到,如果排程更新 11/27 16:08
67F:→ mmis1000:没被使用到的图片会很浪费资源 11/27 16:08
68F:→ mmis1000:而且也不好处里打错资料造成的无意义请求 11/27 16:09
69F:→ mmis1000:这个函式只是为了简单处理参数/快取而做的 11/27 16:20
70F:→ mmis1000:加入一堆额外判断实在有违本意 11/27 16:20
71F:推 alog:就评估你的成本吧 11/27 17:49
72F:→ alog:,我个人觉得如果要考量到伺服器的状况 11/27 17:51
73F:→ alog:跟你的程式诉求做调整 11/27 17:52
74F:→ mmis1000:这就只是为demo而做,所以最低限度就是能正常运作 11/27 17:54
75F:→ mmis1000:不要造成额外无意义消耗 11/27 17:55
76F:推 alog:负载重一点 你的伺服器节点就产生图这件事情占掉频宽跟cpu 11/27 17:55
77F:→ alog:哦,你觉得无意义就无意义吧,保重 11/27 17:57
78F:→ mmis1000:所以才有快取 本来就只能维持 请求数/消耗资源 的比例 11/27 17:58
79F:→ mmis1000:改变总请求数从来就不是我能决定的阿 11/27 17:59
80F:推 alog:伺服器有上百台吗,我是不懂怎麽变用户一个了 11/27 17:59
81F:→ alog:一张图了,另外我怎麽知道你要弄demo而已,那我早就不回这篇 11/27 18:00
82F:→ mmis1000:那是demo阿,负载平衡...etc本来就不在考虑范围 11/27 18:00
83F:→ alog:似乎你自己就有答案,你自己解吧,有问题去看http协定规则 11/27 18:01
84F:→ alog:不回了 11/27 18:01
85F:→ chrisQQ:这种需求一般都会在前端档一台 varnish 之类的… 11/28 13:15
86F:→ danny8376:务实上确实放varnish比较简单XDD 11/29 00:15