springmvc項目集羣模式下如何維護session

傳統的session是維護在內存中的,如果部署多個服務,通過ngix轉發,用戶登錄完成後的請求可能轉發到另外一個服務上去,內存中就沒有用戶的session,就會判定爲用戶沒有登錄,spring-session項目可以把session維護到redis等數據庫中,這樣多個服務可以共用session,就可以解決上面遇到的問題。下面就用redis保存session示例。

需要添加的依賴

        <dependency>
            <groupId>org.springframework.session</groupId>
            <artifactId>spring-session-core</artifactId>
            <version>2.0.2.RELEASE</version>
        </dependency>
                <!-- 緩存 -->
        <dependency>
            <groupId>org.redisson</groupId>
            <artifactId>redisson</artifactId>
            <version>${redisson.version}</version>
        </dependency>
        <dependency>
            <groupId>com.esotericsoftware</groupId>
            <artifactId>kryo</artifactId>
            <version>4.0.2</version>
        </dependency>

配置連接redis

文件名爲applicationContext-cache-single.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:redisson="http://redisson.org/schema/redisson"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://redisson.org/schema/redisson http://redisson.org/schema/redisson/redisson.xsd">

    <!--使用kryo序列化方式-->
    <bean id="kryoCodec" class="org.redisson.codec.KryoCodec"/>

    <redisson:client id="redissonClient" codec-ref="kryoCodec">
        <redisson:single-server address="redis://127.0.0.1:6379"/>
    </redisson:client>
</beans>

配置相關bean

    <import resource="classpath:applicationContext-cache-single.xml"/>

    <!-- session交給redis管理 -->
    <bean id="redissonHttpSessionConfiguration"
          class="org.redisson.spring.session.config.RedissonHttpSessionConfiguration">
        <property name="maxInactiveIntervalInSeconds" value="1800"/>
    </bean>
    <!--這個是設置cookie保存的位置,需要不同服務指定成一樣的,不然無法公用cookie-->
    <bean id="defaultCookieSerializer" class="org.springframework.session.web.http.DefaultCookieSerializer">
        <property name="cookieName" value="GARDPAY_SESSION_ID"/>
        <property name="cookiePath" value="/"/>
    </bean>

這裏只是初始化了一些相關配置,真正能夠把session,從請求中找出,保存到數據庫中需要通過過濾器實現

過濾器配置

    <!-- spring-session過濾器 -->
    <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>

這裏的DelegatingFilterProxy是一個代理過濾器,真正的過濾器是springSessionRepositoryFilter,這個過濾器是我們創建redissonHttpSessionConfiguration這個bean的時候這個bean內部生產的。

測試

    @GetMapping("/put.pub")
    public Map<String, String> put(HttpServletRequest request) {
        request.getSession().setAttribute("aaa", "佔旭鵬");
        Map<String, String> map = new HashMap<>();
        map.put("success", "成功");
        return map;
    }

    @GetMapping("/get.pub")
    public Map<String, Object> get(HttpServletRequest request) {
        Object result = request.getSession().getAttribute("aaa");
        Map<String, Object> map = new HashMap<>();
        map.put("aaa", result);
        return map;
    }

把項目放在兩個端口下跑起來,一個端口put數據,兩個端口下都可以取到,說明已經session共享成功了

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章