集群部署時(shí)的分布式 session 如何實(shí)現(xiàn)?

面試題

集群部署時(shí)的分布式 session 如何實(shí)現(xiàn)?

面試官心理分析

面試官問了你一堆 dubbo 是怎么玩兒的躁倒,你會玩兒 dubbo 就可以把單塊系統(tǒng)弄成分布式系統(tǒng)赎婚,然后分布式之后接踵而來的就是一堆問題,最大的問題就是分布式事務(wù)樱溉、接口冪等性分布式鎖纬凤,還有最后一個(gè)就是分布式session福贞。

當(dāng)然了,分布式系統(tǒng)中的問題何止這么一點(diǎn)停士,非常之多挖帘,復(fù)雜度很高,但是這里就是說下常見的幾個(gè)恋技,也是面試的時(shí)候常問的幾個(gè)拇舀。

面試題剖析

session 是啥?瀏覽器有個(gè) cookie蜻底,在一段時(shí)間內(nèi)這個(gè) cookie 都存在骄崩,然后每次發(fā)請求過來都帶上一個(gè)特殊的 jsessionid cookie,就根據(jù)這個(gè)東西薄辅,在服務(wù)端可以維護(hù)一個(gè)對應(yīng)的 session 域要拂,里面可以放點(diǎn)數(shù)據(jù)。

一般只要你沒關(guān)掉瀏覽器站楚,cookie 還在脱惰,那么對應(yīng)的那個(gè) session 就在,但是如果 cookie 沒了窿春,session 也就沒了拉一。常見于什么購物車之類的東西,還有登錄狀態(tài)保存之類的旧乞。

這個(gè)不多說了蔚润,懂 Java 的都該知道這個(gè)。

單塊系統(tǒng)的時(shí)候這么玩兒 session 沒問題良蛮,但是你要是分布式系統(tǒng)呢抽碌,那么多的服務(wù),session 狀態(tài)在哪兒維護(hù)熬鐾货徙?

其實(shí)方法很多,但是常見常用的是兩種:

tomcat + redis

這個(gè)其實(shí)還挺方便的皮胡,就是使用 session 的代碼跟以前一樣痴颊,還是基于 tomcat 原生的 session 支持即可,然后就是用一個(gè)叫做 Tomcat RedisSessionManager 的東西屡贺,讓所有我們部署得 tomcat 都將 session 數(shù)據(jù)存儲到 redis 即可蠢棱。

在 tomcat 的配置文件中配置:

<Valve className="com.orangefunction.tomcat.redissessions.RedisSessionHandlerValve" />

<Manager className="com.orangefunction.tomcat.redissessions.RedisSessionManager"
         host="{redis.host}"
         port="{redis.port}"
         database="{redis.dbnum}"
         maxInactiveInterval="60"/>

然后指定 redis 的 host 和 port 就 ok 了锌杀。

<Valve className="com.orangefunction.tomcat.redissessions.RedisSessionHandlerValve" />
<Manager className="com.orangefunction.tomcat.redissessions.RedisSessionManager"
     sentinelMaster="mymaster"
     sentinels="<sentinel1-ip>:26379,<sentinel2-ip>:26379,<sentinel3-ip>:26379"
     maxInactiveInterval="60"/>

還可以用上面這種方式基于 redis 哨兵支持的 redis 高可用集群來保存 session 數(shù)據(jù),都是 ok 的泻仙。

spring session + redis

第一種方式會與 tomcat 容器重耦合糕再,如果我要將 web 容器遷移成 jetty,難道還要重新把 jetty 都配置一遍玉转?

因?yàn)樯厦婺欠N tomcat + redis 的方式好用突想,但是會嚴(yán)重依賴于web容器,不好將代碼移植到其他 web 容器上去究抓,尤其是你要是換了技術(shù)棧咋整猾担?比如換成了 spring cloud 或者是 spring boot 之類的呢?

所以現(xiàn)在比較好的還是基于 Java 一站式解決方案刺下,也就是 spring绑嘹。人家 spring 基本上包掉了大部分我們需要使用的框架,spirng cloud 做微服務(wù)橘茉,spring boot 做腳手架工腋,所以用 sping session 是一個(gè)很好的選擇。

在 pom.xml 中配置:

<dependency>
  <groupId>org.springframework.session</groupId>
  <artifactId>spring-session-data-redis</artifactId>
  <version>1.2.1.RELEASE</version>
</dependency>
<dependency>
  <groupId>redis.clients</groupId>
  <artifactId>jedis</artifactId>
  <version>2.8.1</version>
</dependency>

在 spring 配置文件中配置:

<bean id="redisHttpSessionConfiguration"
     class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration">
    <property name="maxInactiveIntervalInSeconds" value="600"/>
</bean>

<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
    <property name="maxTotal" value="100" />
    <property name="maxIdle" value="10" />
</bean>

<bean id="jedisConnectionFactory"
      class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" destroy-method="destroy">
    <property name="hostName" value="${redis_hostname}"/>
    <property name="port" value="${redis_port}"/>
    <property name="password" value="${redis_pwd}" />
    <property name="timeout" value="3000"/>
    <property name="usePool" value="true"/>
    <property name="poolConfig" ref="jedisPoolConfig"/>
</bean>

在 web.xml 中配置:

<filter>
    <filter-name>springSessionRepositoryFilter</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
    <filter-name>springSessionRepositoryFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

示例代碼:

@Controller
@RequestMapping("/test")
public class TestController {

    @RequestMapping("/putIntoSession")
    @ResponseBody
    public String putIntoSession(HttpServletRequest request, String username) {
        request.getSession().setAttribute("name",  “l(fā)eo”);

        return "ok";
    }

    @RequestMapping("/getFromSession")
    @ResponseBody
    public String getFromSession(HttpServletRequest request, Model model){
        String name = request.getSession().getAttribute("name");
        return name;
    }
}

上面的代碼就是 ok 的畅卓,給 sping session 配置基于 redis 來存儲 session 數(shù)據(jù)夷蚊,然后配置了一個(gè) spring session 的過濾器,這樣的話髓介,session 相關(guān)操作都會交給 spring session 來管了惕鼓。接著在代碼中,就用原生的 session 操作唐础,就是直接基于 spring sesion 從 redis 中獲取數(shù)據(jù)了箱歧。

實(shí)現(xiàn)分布式的會話,有很多種很多種方式一膨,我說的只不過比較常見的兩種方式呀邢,tomcat + redis 早期比較常用,但是會重耦合到 tomcat 中豹绪;近些年价淌,通過 spring session 來實(shí)現(xiàn)。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末瞒津,一起剝皮案震驚了整個(gè)濱河市蝉衣,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌巷蚪,老刑警劉巖病毡,帶你破解...
    沈念sama閱讀 216,692評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異屁柏,居然都是意外死亡啦膜,警方通過查閱死者的電腦和手機(jī)有送,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,482評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來僧家,“玉大人雀摘,你說我怎么就攤上這事“斯埃” “怎么了届宠?”我有些...
    開封第一講書人閱讀 162,995評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長乘粒。 經(jīng)常有香客問我,道長伤塌,這世上最難降的妖魔是什么灯萍? 我笑而不...
    開封第一講書人閱讀 58,223評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮每聪,結(jié)果婚禮上旦棉,老公的妹妹穿的比我還像新娘。我一直安慰自己药薯,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,245評論 6 388
  • 文/花漫 我一把揭開白布童本。 她就那樣靜靜地躺著真屯,像睡著了一般。 火紅的嫁衣襯著肌膚如雪绑蔫。 梳的紋絲不亂的頭發(fā)上泵额,一...
    開封第一講書人閱讀 51,208評論 1 299
  • 那天篓叶,我揣著相機(jī)與錄音缸托,去河邊找鬼嗦董。 笑死京革,一個(gè)胖子當(dāng)著我的面吹牛奇唤,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播匹摇,決...
    沈念sama閱讀 40,091評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼咬扇,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了廊勃?” 一聲冷哼從身側(cè)響起懈贺,我...
    開封第一講書人閱讀 38,929評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎坡垫,沒想到半個(gè)月后梭灿,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,346評論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡冰悠,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,570評論 2 333
  • 正文 我和宋清朗相戀三年堡妒,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片溉卓。...
    茶點(diǎn)故事閱讀 39,739評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡皮迟,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出桑寨,到底是詐尸還是另有隱情伏尼,我是刑警寧澤,帶...
    沈念sama閱讀 35,437評論 5 344
  • 正文 年R本政府宣布尉尾,位于F島的核電站爆阶,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏沙咏。R本人自食惡果不足惜扰她,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,037評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望芭碍。 院中可真熱鬧徒役,春花似錦、人聲如沸窖壕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,677評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽瞻讽。三九已至鸳吸,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間速勇,已是汗流浹背晌砾。 一陣腳步聲響...
    開封第一講書人閱讀 32,833評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留烦磁,地道東北人养匈。 一個(gè)月前我還...
    沈念sama閱讀 47,760評論 2 369
  • 正文 我出身青樓哼勇,卻偏偏與公主長得像,于是被迫代替她去往敵國和親呕乎。 傳聞我的和親對象是個(gè)殘疾皇子积担,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,647評論 2 354

推薦閱讀更多精彩內(nèi)容