--
PHP 如果需要使用 Session 一定要注意基本使用原則,可以參考 Hoyo 最近遇到的案例引以為戒
--
案例一:不當的存放內容
公司前員工犯蠢將大量資料儲存於 Session,PHP 的 Session 儲存空間因為是雲端主機,硬碟空間很小只有 30G 導致空間寫滿系統發生錯誤
解決:找到犯蠢的程式,修正即可
--
案例二:不當的存放位置
使用 MySQL 當作 Session 儲存空間,在相簿應用內,大量照片因為權限檢查問題使用 Session,導致網頁載入速度緩慢,在 500 張照片測試下,沒有 Session 檢查的 3 秒延長到超過 30 秒
這是 Hoyo 自己的相簿平台,因為多網站跨網域 Session 的應用,一開始使用 MySQL 資料庫當作儲存媒介,後來一直遇到照片多時效率不彰問題,下定決心解決,因為系統架構比較複雜懷疑過 Nginx Proxy 做了大量的設定,也以為是 HTTP 1.1 的限制採用了 HTTP/2 甚至是 HTTP/3 也是改善不大,也以為是 Docker 的效能問題或是家裡路由器老舊,走了很多彎路最後才確定是 Session 存放在資料庫的問題
將資料表轉換成 Memory 存放在記憶體後,速度快了一些,不過還是不理想
解決:改放在 Redis 就解決了
1 2 |
ini_set('session.save_handler', 'redis'); ini_set('session.save_path', 'tcp://1.2.3.4:6379'); |
--
一個月後...
又變慢了,然後懷疑是有了資料的問題,雖然才 1000 多筆,清空之後就又恢復原本的速度,然後就
查了一下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
192.168.0.6:6379> SLOWLOG GET 1) 1) (integer) 1 2) (integer) 1670123800 3) (integer) 10757 4) 1) "KEYS" 2) "sess_*" 5) "172.18.0.1:51378" 6) "" 2) 1) (integer) 0 2) (integer) 1669562864 3) (integer) 17423 4) 1) "KEYS" 2) "sess_*" 5) "172.18.0.1:60924" 6) "" |
再到 PHP Redis 看了一下,果然是這樣用的
1 2 3 4 5 6 7 8 9 10 |
// 垃圾回收函式,呼叫週期由 session.gc_probability 和 session.gc_divisor 引數控制 public function gc($maxlifetime) { $allKeys = $this->redis->keys("{$this->prefix}*"); foreach($allKeys as $key) { if($this->redis->exists($key) && $this->redis->hGet($key, 'expires') + $maxlifetime < time()) { $this->redis->del($key); } } return true; } |
參考
1 2 3 4 5 6 |
// 會話儲存資料時呼叫該方法,在指令碼執行完或session_write_close方法呼叫之後呼叫 public function write($session_id, $data) { $this->redis->hMSet($this->prefix.$session_id, array('expires' => time(), 'data' => $data)); $this->redis->expire($this->prefix.$session_id, 86400*30); return 1; } |
讓 Redis 自己管理再觀察看看吧
--
547 total views, 2 views today