中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何實現session共享

發布時間:2020-06-26 15:04:50 來源:網絡 閱讀:1473 作者:new個對象 欄目:web開發

http協議是無狀態的,即你連續訪問某個網頁100次和訪問1次對服務器來說是沒有區別對待的,因為它記不住你。
那么,在一些場合,確實需要服務器記住當前用戶怎么辦?比如用戶登錄郵箱后,接下來要收郵件、寫郵件,總不能每次操作都讓用戶輸入用戶名和密碼吧,為了解決這個問題,session的方案就被提了出來,事實上它并不是什么新技術,而且也不能脫離http協議以及任何現有的web技術。
原理很簡單,假設你訪問網頁時就像逛澡堂,第一次進去你是沒有鑰匙的,這個時候你交了錢服務臺就分配一把鑰匙給你,你走到哪里都要帶上,因為這是你身份的唯一標識,接下來你用這把鑰匙可以去打開一個專有的儲物柜存儲你的衣物,游完泳,你再用鑰匙去打開柜子拿出衣物,最后離開游泳池時,把鑰匙歸還,你的這次游泳的過程就是一次session,或者叫做會話,在這個例子中,鑰匙就是session的key,而儲物柜可以理解為存儲用戶會話信息的介質。
那么在web server中如何實現session呢?想必看了上面的例子你會很容易理解,主要是解決兩個問題,一個是鑰匙的問題,一個是存儲用戶信息的問題。對于第一個問題,即什么東西可以讓你每次請求都會自動帶到服務器呢?如果你比較了解http協議,那么答案一目了然,就是cookie,如果你想為用戶建立一次會話,可以在用戶授權成功時給他一個cookie,叫做會話id,它當然是唯一的,比如php就會為建立會話的用戶默認set一個名為phpsessid,值看起來為一個隨機字符串的cookie,如果下次發現用戶帶了這個cookie,服務器就知道,哎呀,剛剛這位顧客來了。
剩下的是解決第二個問題,即如何存儲用戶的信息,服務器知道會話id為abc的用戶來了,那abc想存儲自己的私人信息,比如購物車信息,如何處理?這個時候可以用內存、也可以用文件,也可以用數據庫了,但有個要求是,數據需要用用戶的會話id即可取到,比如php就默認會把會話id為abc的用戶會話數據存儲到/tmp/phpsess_abc的文件里面,每次讀取都要反序列化程序可以理解的數據,寫的時候又需要序列化為持久的數據格式。
較好理解的描述:
session被用于表示一個持續的連接狀態,在網站訪問中一般指代客戶端瀏覽器的進程從開啟到結束的過程。session其實就是網站分析的訪問(visits)度量,表示一個訪問的過程。
session的常見實現形式是會話cookie(session cookie),即未設置過期時間的cookie,這個cookie的默認生命周期為瀏覽器會話期間,只要關閉瀏覽器窗口,cookie就消失了。實現機制是當用戶發起一個請求的時候,服務器會檢查該請求中是否包含sessionid,如果未包含,則系統會創造一個名為JSESSIONID的輸出 cookie返回給瀏覽器(只放入內存,并不存在硬盤中),并將其以HashTable的形式寫到服務器的內存里面;當已經包含sessionid是,服務端會檢查找到與該session相匹配的信息,如果存在則直接使用該sessionid,若不存在則重新生成新的 session。這里需要注意的是session始終是有服務端創建的,并非瀏覽器自己生成的。 但是瀏覽器的cookie被禁止后session就需要用get方法的URL重寫的機制或使用POST方法提交隱藏表單的形式來實現。
  
二、如何實現session的共享?
首先我們應該明白,為什么要實現共享,如果你的網站是存放在一個機器上,那么是不存在這個問題的,因為會話數據就在這臺機器,但是如果你使用了負載均衡把請求分發到不同的機器呢?這個時候會話id在客戶端是沒有問題的,但是如果用戶的兩次請求到了兩臺不同的機器,而它的session數據可能存在其中一臺機器,這個時候就會出現取不到session數據的情況,于是session的共享就成了一個問題。
1.各種web框架早已考慮到這個問題,比如asp.net,是支持通過配置文件修改session的存儲介質為sql server的,所有機器的會話數據都從同一個數據庫讀,就不會存在不一致的問題;
2.以cookie加密的方式保存在客戶端.優點是減輕服務器端的壓力,缺點是受到cookie的大小限制,可能占用一定帶寬,因為每次請求會在頭部附帶一定大小的cookie信息,另外這種方式在用戶禁止使用cookie的情況下無效.
3.服務器間同步。定時同步各個服務器的session信息,此方法可能有一定延時,用戶體驗也不是很好。
4.php支持把會話數據存儲到某臺memcache服務器,你也可以手工把session文件存放的目錄改為nfs網絡文件系統,從而實現文件的跨機器共享。
還有一個簡單的辦法可以用于會話信息不會頻繁變更的情況,在機器a設置用戶會話的時候,把會話數據post到機器b的一個cgi,機器b的cgi把會話數據存下來,這樣機器a和b都會有同一份session數據的拷貝。
》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》
伴隨網站業務規模和訪問量的逐步發展,原本由單臺服務器、單個域名的迷你網站架構已經無法滿足發展需要。
此時我們可能會購買更多服務器,并且啟用多個二級子域名以頻道化的方式,根據業務功能將網站分布部署在獨立的服務器上;或通過負載均衡技術(如:DNS輪詢、Radware、F5、LVS等)讓多個頻道共享一組服務器。
OK,頭腦中我們已經構思了這樣的解決方案,不過進入深入開發后新的技術問題又隨之而來:
我們把網站程序分布部署到多臺服務器上,而且獨立為幾個二級域名,由于Session受實現原理的局限(PHP中Session默認以文件的形式保存在本地服務器的硬盤),使得我們的網站用戶不得不經常在幾個頻道間來回輸入用戶名、密碼登入,導致用戶體驗大打折扣;另外,原本程序可以直接從用戶Session變量中讀取的資料(如:昵稱、積分、登入時間等),因為無法跨服務器同步更新Session 變量,迫使開發人員必須實時讀寫數據庫,從而增加了數據庫的負擔。
于是,解決網站跨服務器之間的Session共享方案需求變得迫切起來,最終催生了多種解決方案,下面列舉4種較為可行的方案進行對比探討:

  1. 基于NFS的Session共享:
    NFS是Net FileSystem的簡稱,最早由Sun公司為解決Unix網絡主機間的目錄共享而研發。
    這個方案實現最為簡單,無需做過多的二次開發,僅需將共享目錄服務器mount到各頻道服務器的本地session目錄即可,缺點是NFS依托于復雜的安全機制和文件系統,因此并發效率不高,尤其對于session這類高并發讀寫的小文件,會由于共享目錄服務器的io-wait過高,最終拖累前端WEB應用程序的執行效率。

  2. 基于數據庫的Session共享:
    首選當然是大名鼎鼎的MySQL數據庫,并且建議使用內存表Heap,提高session操作的讀寫效率。這個方案的實用性比較強,相信大家普遍在使用,它的缺點在于session的并發讀寫能力取決于Mysql數據庫的性能,同時需要自己實現session淘汰邏輯,以便定時從數據表中更新、刪除 session記錄,當并發過高時容易出現表鎖,雖然我們可以選擇行級鎖的表引擎,但不得不否認使用數據庫存儲Session還是有些殺雞用牛刀的架勢。
  3. 基于Cookie的Session共享:
    這個方案我們可能比較陌生,但它在大型網站中還是比較普遍被使用。原理是將全站用戶的Session信息加密、序列化后以Cookie的方式,統一種植在根域名下(如:.host.com),利用瀏覽器訪問該根域名下的所有二級域名站點時,會傳遞與之域名對應的所有Cookie內容的特性,從而實現用戶的Cookie化Session 在多服務間的共享訪問。
    這個方案的優點無需額外的服務器資源;缺點是由于受http協議頭信心長度的限制,僅能夠存儲小部分的用戶信息,同時Cookie化的 Session內容需要進行安全加解密(如:采用DES、RSA等進行明文加解密;再由MD5、SHA-1等算法進行防偽認證),另外它也會占用一定的帶寬資源,因為瀏覽器會在請求當前域名下任何資源時將本地Cookie附加在http頭中傳遞到服務器。
  4. 基于Memcache的Session共享:
    Memcache由于是一款基于Libevent多路異步I/O技術的內存共享系統,簡單的Key + Value數據存儲模式使得代碼邏輯小巧高效,因此在并發處理能力上占據了絕對優勢,目前本人所經歷的項目達到2000/秒 平均查詢,并且服務器CPU消耗依然不到10%。
    另外值得一提的是Memcache的內存hash表所特有的Expires數據過期淘汰機制,正好和Session的過期機制不謀而合,降低了過期Session數據刪除的代碼復雜度,對比“基于數據庫的存儲方案”,僅這塊邏輯就給數據表產生巨大的查詢壓力。
向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

拜城县| 社会| 彰化市| 永康市| 阿巴嘎旗| 贡觉县| 大冶市| 青岛市| 东海县| 同德县| 新丰县| 新竹县| 柳州市| 长岭县| 合肥市| 布拖县| 清水河县| 宜州市| 曲靖市| 邯郸县| 北票市| 龙门县| 沾益县| 长阳| 平定县| 通河县| 上犹县| 清丰县| 龙游县| 台安县| 汉阴县| 河池市| 菏泽市| 东城区| 贺兰县| 万山特区| 长寿区| 永春县| 会宁县| 内丘县| 淮阳县|