Golang web 開發實戰之 session 緩衝:如何使用 redigo 將一個結構體資料儲存到 redis?

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。自訂 session 結構體:
type Session struct {SessionID  string        `json:"sessionId" bson:"sessionId"`User       *User         `json:"-" bson:"user"`UserType   string        `json:"userType" bson:"userType"`NickName   string        `json:"nickName" bson:"nickName"`CreateTime time.Time     `json:"-" bson:"createTime"`UpdateTime time.Time     `json:"-" bson:"updateTime"`Expires    time.Time     `json:"-" bson:"expires"`Locale     string        `json:"-" bson:"locale"` // default is zh_CNMenus      []wmodel.Menu `json:"menus" bson:"menus"`}

1. session 的儲存

使用 json.Marshal 將結構體 json 化之後儲存到 redis:

/*【增】描述:插入一個 session 對象session 頂級 key,頂級 key 可以設定到期時間<[session]: 要插入的 session 對象>[error]:插入失敗相關資訊*/func (s *sessionService) SetSession(session *model.Session) error {// 從池裡擷取串連conn := pool.Get()if conn == nil {log.Errorf("redis connnection is nil")return errors.New("redis connnection is nil")}// 用完後將串連放回串連池defer conn.Close()// 將session轉換成json資料,注意:轉換後的value是一個byte數組value, err := json.Marshal(session)if err != nil {log.Errorf("json marshal err,%s", err)return err}log.Infof("send data[%s]", session.SessionID, value)_, err = conn.Do("SET", session.SessionID, value, "EX", sessionTimeOutInSeconds)if err != nil {return err}return nil}

Golang 測實驗證:

func TestSetSession(t *testing.T) {s := &model.Session{SessionID: "20150421120000",UserType:  "admin",NickName:  "df",}err := SessionService.SetSession(s)if err != nil {t.Errorf("fail to add one session(%+v): %s", s, err)t.FailNow()}}

redis 用戶端查看該 session 儲存情況:


2. session 的刪除

直接通過 redigo 驅動遠程調用 DEL 命令:

/*【刪】描述: 刪除一個 session 對象session 頂級 key,一般情況下 session 會在使用者無操作 30 分鐘後自行到期刪除但使用者登出操作可以提前對 session 進行刪除,這就是本方法被調用的地方<[sessionID]: 要刪除的 session 對象的 id>[error]:刪除失敗相關資訊*/func (s *sessionService) DelSession(sessionID string) (err error) {// 從池裡擷取串連conn := pool.Get()if conn == nil {log.Errorf("redis connnection is nil")return errors.New("redis connnection is nil")}// 用完後將串連放回串連池defer conn.Close()log.Infof("move data[%s]", sessionID)_, err = conn.Do("DEL", sessionID)if err != nil {return err}return nil}
Golang 測實驗證:

func TestDelSession(t *testing.T) {err := SessionService.DelSession("20150421120000")if err != nil {t.Errorf("fail to delete one session(%s): %s", "20150421120000", err)t.FailNow()}}

3. session 的擷取

使用 json.Unmarshal 將序列化之後的結構體還原:

/*【查】描述: 查看並返回一個 session 實體session 頂級 key<[sessionID]: 要查看的 session 對象的 id>[error]:查看失敗相關資訊*/func (s *sessionService) GetSession(sessionID string) (session *model.Session, err error) {// 從池裡擷取串連conn := pool.Get()if conn == nil {log.Errorf("redis connnection is nil")return nil, errors.New("redis connnection is nil")}// 用完後將串連放回串連池defer conn.Close()log.Infof("exists data[%s]", sessionID)// 先查看該session是否存在var ifExists boolifExists, err = SessionService.ExistsSession(sessionID)if err != nil {log.Errorf("fail to exists one session(%s): %s", sessionID, err)return nil, errors.New("session not exists, sessionID: " + sessionID)}if ifExists {// json資料在go中是[]byte類型,所以此處用redis.Bytes轉換valueBytes, err2 := redis.Bytes(conn.Do("GET", sessionID))if err2 != nil {return nil, err2}//log.Infof("receive data[%s]:%s", sessionID, string(valueBytes))session = &model.Session{}err = json.Unmarshal(valueBytes, session)if err != nil {return nil, err}return session, nil} else {return nil, errors.New("session not exists, sessionID: " + sessionID)}}
Golang 測實驗證:

func TestGetSession(t *testing.T) {s, err := SessionService.GetSession("20150421120000")if err != nil {t.Errorf("fail to exists one session(%s): %s", "20150421120000", err)t.FailNow()}log.Debug("session exists, session nickname is: %s", s.NickName)}


後記

redis 的作者為了保持簡單的架構只允許我們對 top level 的 key 設定逾時時間,次級 key(比如 Hash 裡邊的每個子 key)是不能設定逾時時間的,所以我們單獨使用了一個 index 為 3 的 redis 庫專門存放 session,就是方便管理。另外,我們將每個 session 的 key(即 top level 的 key)有效期間設定為半小時,有效期間斷定及處理託管 redis,避開了程式裡對 session 逾時機制管理的複雜性——特別是分布式環境。

另外,本文只提供了 session 的增、刪、查操作,對於 session 的修改以及有效期間推延操作筆者建議可以先刪除再增加。

參考資料

GO: How to save and retrieve a struct to redis using redigo
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.