GoFrame Session-File

2022-04-14 10:20 更新

文件存儲

在默認情況下,?ghttp.Server?的?Session?存儲使用了內存+文件的方式,使用?StorageFile?對象實現。具體原理為:

  1. ?Session?的數據操作完全基于內存;
  2. 使用?gcache?進程緩存模塊控制數據過期;
  3. 使用文件存儲持久化存儲管理?Session?數據;
  4. 當且僅有當?Session?被標記為?dirty?時(數據有更新)才會執(zhí)行?Session?序列化并執(zhí)行文件持久化存儲;
  5. 當且僅當內存中的?Session?不存在時,才會從文件存儲中反序列化恢復?Session?數據到內存中,降低IO調用;
  6. 序列化/反序列化使用的是標準庫的?json.Marshal?/?UnMarshal?方法;

從原理可知,當?Session?為讀多寫少的場景中,?Session?的數據操作非常高效。

有個注意的細節(jié),由于文件存儲涉及到文件操作,為便于降低?IO?開銷并提高?Session?操作性能,并不是每一次?Session?請求結束后都會立即刷新對應?Session?的?TTL?時間。而只有當涉及到更新操作(被標記為?dirty?)時才會立即刷新其?TTL?;針對于讀取請求,將會每隔一分鐘更新前一分鐘內讀取操作對應的?Session?文件?TTL?時間,以便于?Session?自動續(xù)活。

使用示例

package main

import (
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/net/ghttp"
	"github.com/gogf/gf/v2/os/gtime"
	"time"
)

func main() {
	s := g.Server()
	s.SetConfigWithMap(g.Map{
		"SessionMaxAge": time.Minute,
	})
	s.Group("/", func(group *ghttp.RouterGroup) {
		group.ALL("/set", func(r *ghttp.Request) {
			r.Session.Set("time", gtime.Timestamp())
			r.Response.Write("ok")
		})
		group.ALL("/get", func(r *ghttp.Request) {
			r.Response.Write(r.Session.Map())
		})
		group.ALL("/del", func(r *ghttp.Request) {
			r.Session.Clear()
			r.Response.Write("ok")
		})
	})
	s.SetPort(8199)
	s.Run()
}

在該實例中,為了方便觀察過期失效,我們將?Session?的過期時間設置為1分鐘。執(zhí)行后,

  1. 首先,訪問 http://127.0.0.1:8199/set 設置一個?Session?變量;
  2. 隨后,訪問 http://127.0.0.1:8199/get 可以看到該?Session?變量已經設置并成功獲取;
  3. 接著,我們停止程序,并重新啟動,再次訪問 http://127.0.0.1:8199/get ,可以看到?Session?變量已經從文件存儲中恢復;
  4. 等待1分鐘后,再次訪問 http://127.0.0.1:8199/get 可以看到已經無法獲取該?Session?,因為該?Session?已經過期;


以上內容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號