session 共享

在多個tomcat集群中,session共享就是必須违帆,不然前端nginx轉(zhuǎn)發(fā)過來不知道之前請求在哪臺浙巫,就找不到session,導(dǎo)致請求失敗刷后。

幾種實現(xiàn)方案

1.粘性session

使用Nginx的ip_hash特性做粘性會話的畴,可以讓用戶每次訪問都轉(zhuǎn)發(fā)到該用戶第一次訪問的web容器上,但是當該web容器上的應(yīng)用掛了惠险,nginx不會將該用戶的請求轉(zhuǎn)發(fā)到別的web容器苗傅,體驗不好抒线。

2.服務(wù)器session復(fù)制

即每次session發(fā)生變化時班巩,創(chuàng)建或者修改,就廣播給所有集群中的服務(wù)器嘶炭,使所有的服務(wù)器上的session相同抱慌。

3.session共享

緩存session,使用redis眨猎, memcached抑进。

4.session持久化

將session存儲至數(shù)據(jù)庫中,如mysql睡陪。

基于redis的實現(xiàn)方式

自定義Request與Session,并使用過濾器過濾對應(yīng)路徑的請求寺渗,引入自定義Request

  1. 封裝自定義Request,主要目的重寫getSession方法返回自定義的session對象兰迫。
package com.liabc.poc.server.config;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

public class HttpServletRequestWrapper extends javax.servlet.http.HttpServletRequestWrapper {

    private String sid;

    public HttpServletRequestWrapper(HttpServletRequest request, String sid) {
        super(request);
        this.sid = sid;
    }

    @Override
    public HttpSession getSession(boolean create) {
        return new HttpSessionSidWrapper(null, sid);
    }

    @Override
    public HttpSession getSession() {
        return new HttpSessionSidWrapper(null, sid);
    }
}

  1. 封裝自定義Session
package com.liabc.poc.server.config;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionContext;
import java.util.Enumeration;

public class HttpSessionWrapper implements HttpSession {

    private HttpSession session;

    public HttpSessionWrapper(HttpSession session) {
        this.session = session;
    }

    @Override
    public long getCreationTime() {
        return this.session.getCreationTime();
    }

    @Override
    public String getId() {
        return this.session.getId();
    }

    @Override
    public long getLastAccessedTime() {
        return this.session.getLastAccessedTime();
    }

    @Override
    public ServletContext getServletContext() {
        return this.session.getServletContext();
    }

    @Override
    public void setMaxInactiveInterval(int interval) {
        this.session.setMaxInactiveInterval(interval);
    }

    @Override
    public int getMaxInactiveInterval() {
        return this.session.getMaxInactiveInterval();
    }

    @Override
    public HttpSessionContext getSessionContext() {
        return this.session.getSessionContext();
    }

    @Override
    public Object getAttribute(String name) {
        return this.session.getAttribute(name);
    }

    @Override
    public Object getValue(String name) {
        return this.session.getValue(name);
    }

    @Override
    public Enumeration<String> getAttributeNames() {
        return this.session.getAttributeNames();
    }

    @Override
    public String[] getValueNames() {
        return this.session.getValueNames();
    }

    @Override
    public void setAttribute(String name, Object value) {
        this.session.setAttribute(name, value);
    }

    @Override
    public void putValue(String name, Object value) {
        this.session.putValue(name, value);
    }

    @Override
    public void removeAttribute(String name) {
        this.session.removeAttribute(name);
    }

    @Override
    public void removeValue(String name) {
        this.session.removeValue(name);
    }

    @Override
    public void invalidate() {
        this.session.invalidate();
    }

    @Override
    public boolean isNew() {
        return this.session.isNew();
    }
}
  1. 繼承并重寫getAttribute信殊,setAttribute等方法。(主要實現(xiàn)從redis讀取數(shù)據(jù)封裝session信息汁果,暫未實現(xiàn)涡拘。)
package com.liabc.poc.server.config;


import javax.servlet.http.HttpSession;
import java.util.HashMap;
import java.util.Map;

public class HttpSessionSidWrapper extends HttpSessionWrapper {

    private String sid;
    private Map map = new HashMap();

    public HttpSessionSidWrapper(HttpSession session, String sid) {
        super(session);
        this.sid = sid;
    }

    @Override
    public Object getAttribute(String name) {
        map.put("test","Hello Session!");
        return this.map.get(name);
    }

    @Override
    public void setAttribute(String name, Object value) {
        this.map.put(name, value);
    }

    @Override
    public String getId() {
        return this.sid;
    }
}
  1. 在過濾器里引入自定義Request和Session
package com.liabc.poc.server.config;


import javax.servlet.*;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class SessionFilter implements Filter {

    private static final long serialVersionUID = 8928219999641126613L;
    private String cookieDomain = "";
    private String cookiePath = "/";


    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

        this.cookiePath = filterConfig.getInitParameter("cookiePath");
        if (this.cookiePath == null || this.cookiePath.length() == 0) {
            this.cookiePath = "/";
        }

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        String sessionId = "XmlBeanDefinitionReaderSid";
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        Cookie cookies[] = request.getCookies();
        Cookie sCookie = null;
        String sid = "";
        if (cookies != null && cookies.length > 0) {
            for (int i = 0; i < cookies.length; i++) {
                sCookie = cookies[i];
                if (sCookie.getName().equals(sessionId)) {
                    sid = sCookie.getValue();
                }
            }
        }

        if (sid == null || sid.length() == 0) {
            sid = java.util.UUID.randomUUID().toString();
            Cookie mycookies = new Cookie(sessionId, sid);
            mycookies.setMaxAge(-1);
            mycookies.setPath("/");
            mycookies.setHttpOnly(true);
            response.addCookie(mycookies);
        }

        HttpServletRequestWrapper requestWrapper = new HttpServletRequestWrapper(request, sid);

        filterChain.doFilter(requestWrapper, response);

    }


}
  1. web.xml 配置過濾器
<!-- session共享過濾器 -->
    <filter>
        <filter-name>mySessionFilter</filter-name>
        <filter-class>com.liabc.poc.server.config.SessionFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>mySessionFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市据德,隨后出現(xiàn)的幾起案子鳄乏,更是在濱河造成了極大的恐慌跷车,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,997評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件橱野,死亡現(xiàn)場離奇詭異朽缴,居然都是意外死亡,警方通過查閱死者的電腦和手機水援,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,603評論 3 392
  • 文/潘曉璐 我一進店門不铆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人裹唆,你說我怎么就攤上這事誓斥。” “怎么了许帐?”我有些...
    開封第一講書人閱讀 163,359評論 0 353
  • 文/不壞的土叔 我叫張陵劳坑,是天一觀的道長。 經(jīng)常有香客問我成畦,道長距芬,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,309評論 1 292
  • 正文 為了忘掉前任循帐,我火速辦了婚禮框仔,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘拄养。我一直安慰自己离斩,他們只是感情好,可當我...
    茶點故事閱讀 67,346評論 6 390
  • 文/花漫 我一把揭開白布瘪匿。 她就那樣靜靜地躺著跛梗,像睡著了一般。 火紅的嫁衣襯著肌膚如雪棋弥。 梳的紋絲不亂的頭發(fā)上核偿,一...
    開封第一講書人閱讀 51,258評論 1 300
  • 那天,我揣著相機與錄音顽染,去河邊找鬼漾岳。 笑死,一個胖子當著我的面吹牛粉寞,可吹牛的內(nèi)容都是我干的尼荆。 我是一名探鬼主播,決...
    沈念sama閱讀 40,122評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼仁锯,長吁一口氣:“原來是場噩夢啊……” “哼耀找!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,970評論 0 275
  • 序言:老撾萬榮一對情侶失蹤野芒,失蹤者是張志新(化名)和其女友劉穎蓄愁,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體狞悲,經(jīng)...
    沈念sama閱讀 45,403評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡撮抓,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,596評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了摇锋。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片丹拯。...
    茶點故事閱讀 39,769評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖荸恕,靈堂內(nèi)的尸體忽然破棺而出乖酬,到底是詐尸還是另有隱情,我是刑警寧澤融求,帶...
    沈念sama閱讀 35,464評論 5 344
  • 正文 年R本政府宣布咬像,位于F島的核電站,受9級特大地震影響生宛,放射性物質(zhì)發(fā)生泄漏县昂。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,075評論 3 327
  • 文/蒙蒙 一陷舅、第九天 我趴在偏房一處隱蔽的房頂上張望倒彰。 院中可真熱鬧,春花似錦莱睁、人聲如沸待讳。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,705評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽耙箍。三九已至撰糠,卻和暖如春酥馍,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背阅酪。 一陣腳步聲響...
    開封第一講書人閱讀 32,848評論 1 269
  • 我被黑心中介騙來泰國打工旨袒, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人术辐。 一個月前我還...
    沈念sama閱讀 47,831評論 2 370
  • 正文 我出身青樓砚尽,卻偏偏與公主長得像,于是被迫代替她去往敵國和親辉词。 傳聞我的和親對象是個殘疾皇子必孤,可洞房花燭夜當晚...
    茶點故事閱讀 44,678評論 2 354

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