[請益] php檔案快取問題

看板PHP作者 (秋月戀楓)時間11年前 (2013/11/27 02:17), 編輯推噓5(5081)
留言86則, 5人參與, 最新討論串1/1
各位版友好 小弟最近再做一個自動伺服器狀態圖的小程式, 但發現每次都重新產生的話,cpu會吃很兇 所以就用檔案修改時間當判斷,加上快取 和用header產生304減少流量 可是卻發生了奇怪的狀況 出問題的區段 http://pastebin.com/MrT5ZdjW 完整code http://goo.gl/b1mlg0 因為第一次產生時有時會傳輸不全導致破圖, 所以我在圖片產生完的第一次輸出, 並沒有加上更新快取紀錄的header 可是測試時卻發現,圖片還是被快取了 請問有人看得出是哪裡出錯嗎? 像是邏輯上的問題之類。 麻煩了 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 140.116.130.56

11/27 02:28, , 1F
如果用Chrome測 沒關cache很正常 client端短時間cache
11/27 02:28, 1F

11/27 02:29, , 2F
的行為是看瀏覽器高興的 你還是讓圖片一次成功比較實際
11/27 02:29, 2F

11/27 02:33, , 3F
並不是短時間快取,而是長時間快取,得按 ^ F5才能刷新
11/27 02:33, 3F

11/27 02:34, , 4F
不知道圖片不全是不是time out造成的
11/27 02:34, 4F

11/27 02:34, , 5F
另外 要輸出檔案我會建議直接用readfile
11/27 02:34, 5F

11/27 02:35, , 6F
圖片只會產生一次,第二次傳的圖片跟第一次是一樣的
11/27 02:35, 6F

11/27 02:35, , 7F
不過更要建議我會直接用x-sendfile之類的傳cache檔出去
11/27 02:35, 7F

11/27 02:42, , 8F
可能真的是timeout問題吧 你可以試著增加timeout試試?
11/27 02:42, 8F

11/27 02:44, , 9F
剛用firefox開發者去看,明明不含last-modified
11/27 02:44, 9F

11/27 02:44, , 10F
If-Modified-Since 還是被更新了,不知道是不是bug...
11/27 02:44, 10F

11/27 02:51, , 11F
這不是BUG Cache本來就不是沒Last-Modified就不能做
11/27 02:51, 11F

11/27 02:53, , 12F
那如果把時間標註為0,標為過期呢?
11/27 02:53, 12F

11/27 02:57, , 13F
你還是確保圖片成功傳送比較實際...
11/27 02:57, 13F

11/27 03:01, , 14F
如果無法正確判斷header,連送304都會有問題啊...
11/27 03:01, 14F

11/27 03:03, , 15F
反正剛剛試了下 我是沒遇過破圖啦
11/27 03:03, 15F

11/27 03:03, , 16F
可能我伺服器太好了(X
11/27 03:03, 16F

11/27 03:04, , 17F
我是比較建議你 可以直接PHP輸出到cache之後
11/27 03:04, 17F

11/27 03:04, , 18F
直接用Location的方式redirect過去
11/27 03:04, 18F

11/27 03:05, , 19F
你只要確定那張圖還能用 連要不要傳304都不用管
11/27 03:05, 19F

11/27 03:05, , 20F
反正丟給HTTP Server自己判斷去
11/27 03:05, 20F

11/27 03:06, , 21F
對了 不要再巧虎頭了www
11/27 03:06, 21F

11/27 03:06, , 22F
聽說那是firebug的bug,在chrome上測不出這種行為
11/27 03:06, 22F

11/27 03:07, , 23F
firebug好像會造成額外request,但卻又沒更新cache
11/27 03:07, 23F

11/27 03:15, , 24F
不直接重導向的理由是,要排程更新很麻煩
11/27 03:15, 24F

11/27 03:17, , 25F
而且會把code搞得很複雜,也不好處裡未被使用的圖
11/27 03:17, 25F

11/27 03:17, , 26F
沒啊 對外使用php的連結 php裡再導去cache
11/27 03:17, 26F

11/27 03:18, , 27F
這樣還是要先走過php 只是最後輸出改成location header
11/27 03:18, 27F

11/27 03:22, , 28F
是指header歐,我以為是mod_rewrite
11/27 03:22, 28F

11/27 03:23, , 29F
其實本來就只是暫時性的做法拉
11/27 03:23, 29F

11/27 03:24, , 30F
多人同時連線會讓更新用的socket_client出問題...
11/27 03:24, 30F

11/27 03:26, , 31F
其實用rewrite也行www rewrite可以寫很複雜的www
11/27 03:26, 31F

11/27 03:27, , 32F
我自己是用php放crontab去每分鐘跑一次更新資料
11/27 03:27, 32F

11/27 03:27, , 33F
然後要顯示時才去資料庫撈回來給人看
11/27 03:27, 33F

11/27 04:04, , 34F
結果是ff的bug阿...http://pastebin.com/6TYuvGNi
11/27 04:04, 34F

11/27 04:05, , 35F
多了一次無參數request,而且無視快取狀態更新紀錄
11/27 04:05, 35F

11/27 06:11, , 36F
基本上你要讓他圖片不要被快取,有個方式
11/27 06:11, 36F

11/27 06:19, , 37F
你至少要輸出時的時候 Header 帶 Cache-Control
11/27 06:19, 37F

11/27 06:19, , 38F
或伺服端控制圖片的 Header
11/27 06:19, 38F

11/27 06:19, , 39F
至少都要有基本的 no-store no-cache private
11/27 06:19, 39F

11/27 06:20, , 40F
另外就是圖片的快取設計要改變,不是 Request 進來才產生圖
11/27 06:20, 40F

11/27 06:21, , 41F
而是你要用系統排程call你腳本 定時更新圖
11/27 06:21, 41F

11/27 06:21, , 42F
這樣一來你的CPU占用的機會就會大幅縮小
11/27 06:21, 42F

11/27 06:23, , 43F
再補充,輸出完圖,直接放在伺服端就可以了
11/27 06:23, 43F

11/27 06:23, , 44F
直接讓apache or nginx 直接把圖抓出來輸出給使用者
11/27 06:23, 44F

11/27 06:24, , 45F
不論是記憶消耗或CPU佔用度都會大大減低
11/27 06:24, 45F

11/27 06:24, , 46F
另外就是在某種情況下,session_start 會影響到快取
11/27 06:24, 46F

11/27 06:25, , 47F
因為他會提早告知browser或代理伺服器不要快取產生的網頁
11/27 06:25, 47F

11/27 06:52, , 48F
session對cache不會有影響 除非中間夾了cache server
11/27 06:52, 48F

11/27 06:53, , 49F
有檢查cookie差異來決定決定是否cache
11/27 06:53, 49F

11/27 06:54, , 50F
不過這也不會影響到client端的cache行為
11/27 06:54, 50F

11/27 06:55, , 51F
畢竟session_start唯一做的事只有再找不到SESSION ID時
11/27 06:55, 51F

11/27 06:55, , 52F
隨機產生SESSION ID塞到Cookie裡而已
11/27 06:55, 52F

11/27 06:55, , 53F
我印象走fastcgi就會,cache server是因為遵循http協定設計
11/27 06:55, 53F

11/27 06:56, , 54F
你可以觀察 header 輸出,很有趣有開沒開有差
11/27 06:56, 54F

11/27 06:58, , 55F
我印象php的session start原始碼會輸出 阻止cache的header
11/27 06:58, 55F

11/27 06:59, , 56F
session本身機制設計,資料不該被任何東西cache到會強制要求
11/27 06:59, 56F

11/27 07:00, , 57F
那些裝置或服務不能把資料給儲存跟共享
11/27 07:00, 57F

11/27 07:01, , 58F
當然如果那些程式硬要不遵守快取也沒辦法
11/27 07:01, 58F

11/27 10:59, , 59F
不是有一個爛招是圖片名稱後面帶GET參數嗎
11/27 10:59, 59F

11/27 11:00, , 60F
例如這樣 x.jpg?t=38552120793 (用js隨便加一個亂數)
11/27 11:00, 60F

11/27 11:35, , 61F
樓上沒看清楚啊www 他不是要"總是"不cache
11/27 11:35, 61F

11/27 11:35, , 62F
而是PHP判定某種狀況下才不給cache
11/27 11:35, 62F

11/27 11:55, , 63F
OUCH~~
11/27 11:55, 63F

11/27 11:56, , 64F
果然看了半天還是看不懂 :~(
11/27 11:56, 64F

11/27 16:07, , 65F
request進來才確認產生圖片的理由是
11/27 16:07, 65F

11/27 16:08, , 66F
因為圖片每次更新不一定都會有人看到,如果排程更新
11/27 16:08, 66F

11/27 16:08, , 67F
沒被使用到的圖片會很浪費資源
11/27 16:08, 67F

11/27 16:09, , 68F
而且也不好處裡打錯資料造成的無意義請求
11/27 16:09, 68F

11/27 16:20, , 69F
這個函式只是為了簡單處理參數/快取而做的
11/27 16:20, 69F

11/27 16:20, , 70F
加入一堆額外判斷實在有違本意
11/27 16:20, 70F

11/27 17:49, , 71F
就評估你的成本吧
11/27 17:49, 71F

11/27 17:51, , 72F
,我個人覺得如果要考量到伺服器的狀況
11/27 17:51, 72F

11/27 17:52, , 73F
跟你的程式訴求做調整
11/27 17:52, 73F

11/27 17:54, , 74F
這就只是為demo而做,所以最低限度就是能正常運作
11/27 17:54, 74F

11/27 17:55, , 75F
不要造成額外無意義消耗
11/27 17:55, 75F

11/27 17:55, , 76F
負載重一點 你的伺服器節點就產生圖這件事情佔掉頻寬跟cpu
11/27 17:55, 76F

11/27 17:57, , 77F
哦,你覺得無意義就無意義吧,保重
11/27 17:57, 77F

11/27 17:58, , 78F
所以才有快取 本來就只能維持 請求數/消耗資源 的比例
11/27 17:58, 78F

11/27 17:59, , 79F
改變總請求數從來就不是我能決定的阿
11/27 17:59, 79F

11/27 17:59, , 80F
伺服器有上百台嗎,我是不懂怎麼變用戶一個了
11/27 17:59, 80F

11/27 18:00, , 81F
一張圖了,另外我怎麼知道你要弄demo而已,那我早就不回這篇
11/27 18:00, 81F

11/27 18:00, , 82F
那是demo阿,負載平衡...etc本來就不在考慮範圍
11/27 18:00, 82F

11/27 18:01, , 83F
似乎你自己就有答案,你自己解吧,有問題去看http協定規則
11/27 18:01, 83F

11/27 18:01, , 84F
不回了
11/27 18:01, 84F

11/28 13:15, , 85F
這種需求一般都會在前端檔一台 varnish 之類的…
11/28 13:15, 85F

11/29 00:15, , 86F
務實上確實放varnish比較簡單XDD
11/29 00:15, 86F
文章代碼(AID): #1IbEMreF (PHP)
文章代碼(AID): #1IbEMreF (PHP)