使用Spring-Session共享使用Session

<div id="content_views" class="markdown_views"> <!-- flowchart 箭頭圖標 勿刪 --> <svg xmlns="http://www.w3.org/2000/svg" style="display: none;"> <path stroke-linecap="round" d="M5,0 0,2.5 5,5z" id="raphael-marker-block" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path> </svg> <h2 id="前言"><a name="t0"></a>前言:</h2>html

<p>session共享策略有不少,常見的有粘性複製,高併發下效率查。tomcat-redis-session-manager無疑是一個挺好的方案,缺點要配置tomcat,有點複雜。最優的方案莫過於使用Spring-Session無縫整合redis,只要項目修改便可。</p>java

<h2 id="測試項目結構"><a name="t1"></a>測試項目結構:</h2>nginx

<p>項目結構很簡單: <br> <img src="https://img-blog.csdn.net/20180418192111447?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM1ODMwOTQ5/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70" alt="這裏寫圖片描述" title=""></p>web

<p><code>Test.java</code> 就是一個頁面跳轉,傳輸一下sessionid</p>redis

<pre class="prettyprint" name="code"><code class="hljs java has-numbering" onclick="mdcp.signin(event)"><span class="hljs-annotation">@Controller</span> <span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Test</span> {</span> <span class="hljs-annotation">@RequestMapping</span>(<span class="hljs-string">"/test"</span>) <span class="hljs-keyword">public</span> String <span class="hljs-title">test</span>(HttpSession session, HttpServletRequest request) { request.setAttribute(<span class="hljs-string">"id"</span>, session.getId()); <span class="hljs-keyword">return</span> <span class="hljs-string">"index"</span>; } }<div class="hljs-button signin" data-title="登陸後複製"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li></ul></pre>spring

<p><code>index.jsp</code> 單純的打印一下sessionid</p>緩存

<pre class="prettyprint" name="code"><code class="hljs xml has-numbering" onclick="mdcp.signin(event)"><span class="vbscript">&lt;%@ page language=<span class="hljs-string">"java"</span> import=<span class="hljs-string">"java.util.*"</span> pageEncoding=<span class="hljs-string">"UTF-8"</span>%&gt;</span> <span class="vbscript">&lt;% <span class="hljs-built_in">String</span> path = <span class="hljs-built_in">request</span>.getContextPath(); <span class="hljs-built_in">String</span> basePath = <span class="hljs-built_in">request</span>.getScheme() + <span class="hljs-string">"://"</span> + <span class="hljs-built_in">request</span>.getServerName() + <span class="hljs-string">":"</span> + <span class="hljs-built_in">request</span>.getServerPort() + path + <span class="hljs-string">"/"</span>; %&gt;</span> <span class="vbscript">&lt;%@ taglib prefix=<span class="hljs-string">"c"</span> uri=<span class="hljs-string">"http://java.sun.com/jsp/jstl/core"</span>%&gt;</span> <span class="vbscript">&lt;%-- &lt;%@ page isELIgnored =<span class="hljs-string">"false"</span> %&gt;</span> --%&gt; <span class="hljs-doctype">&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-title">html</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-title">head</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-title">base</span> <span class="hljs-attribute">href</span>=<span class="hljs-value">"&lt;%=basePath%&gt;"</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-title">title</span>&gt;</span>My JSP 'TestUpload.jsp' starting page<span class="hljs-tag">&lt;/<span class="hljs-title">title</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-title">meta</span> <span class="hljs-attribute">http-equiv</span>=<span class="hljs-value">"pragma"</span> <span class="hljs-attribute">content</span>=<span class="hljs-value">"no-cache"</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-title">meta</span> <span class="hljs-attribute">http-equiv</span>=<span class="hljs-value">"cache-control"</span> <span class="hljs-attribute">content</span>=<span class="hljs-value">"no-cache"</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-title">meta</span> <span class="hljs-attribute">http-equiv</span>=<span class="hljs-value">"expires"</span> <span class="hljs-attribute">content</span>=<span class="hljs-value">"0"</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-title">meta</span> <span class="hljs-attribute">http-equiv</span>=<span class="hljs-value">"keywords"</span> <span class="hljs-attribute">content</span>=<span class="hljs-value">"keyword1,keyword2,keyword3"</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-title">meta</span> <span class="hljs-attribute">http-equiv</span>=<span class="hljs-value">"description"</span> <span class="hljs-attribute">content</span>=<span class="hljs-value">"This is my page"</span>&gt;</span> <span class="hljs-tag">&lt;/<span class="hljs-title">head</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-title">body</span>&gt;</span> 個人session:${id} <span class="hljs-tag">&lt;<span class="hljs-title">br</span>&gt;</span> sessionid=<span class="vbscript">&lt;%=session.getId()%&gt;</span> <span class="hljs-tag">&lt;/<span class="hljs-title">body</span>&gt;</span> <span class="hljs-tag">&lt;/<span class="hljs-title">html</span>&gt;</span> <div class="hljs-button signin" data-title="登陸後複製"></div></code></pre>tomcat

<p>當項目部署到nginx上的兩個tomcat上時,每次訪問地址,打印出來的sessionId都發生變化,這樣在一些登陸的操做中,用戶明明在tomcatA上登陸了,可是用戶的其餘操做負載到了TomcatB中,然而B不知道用戶已經在A登陸了,又讓用戶登陸一次,這樣用戶體驗極差。使用Spring-Session就是把用戶的session緩存到redis中,讓你們都從redis中獲取用戶session,這樣就保證了session的共享。</p>服務器

<h2 id="使用spring-session"><a name="t2"></a>使用Spring-Session</h2>markdown

<ul> <li>pom.xml 增長依賴</li> </ul>

<pre class="prettyprint" name="code"><code class="hljs xml has-numbering" onclick="mdcp.signin(event)"><span class="hljs-comment">&lt;!-- 使用Spring Session來解決Session共享問題 --&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-title">dependency</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-title">groupId</span>&gt;</span>org.springframework.session<span class="hljs-tag">&lt;/<span class="hljs-title">groupId</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-title">artifactId</span>&gt;</span>spring-session-data-redis<span class="hljs-tag">&lt;/<span class="hljs-title">artifactId</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-title">version</span>&gt;</span>1.3.0.RELEASE<span class="hljs-tag">&lt;/<span class="hljs-title">version</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-title">type</span>&gt;</span>pom<span class="hljs-tag">&lt;/<span class="hljs-title">type</span>&gt;</span> <span class="hljs-tag">&lt;/<span class="hljs-title">dependency</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-title">dependency</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-title">groupId</span>&gt;</span>biz.paluch.redis<span class="hljs-tag">&lt;/<span class="hljs-title">groupId</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-title">artifactId</span>&gt;</span>lettuce<span class="hljs-tag">&lt;/<span class="hljs-title">artifactId</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-title">version</span>&gt;</span>3.5.0.Final<span class="hljs-tag">&lt;/<span class="hljs-title">version</span>&gt;</span> <span class="hljs-tag">&lt;/<span class="hljs-title">dependency</span>&gt;</span><div class="hljs-button signin" data-title="登陸後複製"></div></code></pre>

<ul> <li>web.xml增長配置</li> </ul>

<pre class="prettyprint" name="code"><code class="hljs xml has-numbering" onclick="mdcp.signin(event)"><span class="hljs-comment">&lt;!-- Spring session --&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-title">filter</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-title">filter-name</span>&gt;</span>springSessionRepositoryFilter<span class="hljs-tag">&lt;/<span class="hljs-title">filter-name</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-title">filter-class</span>&gt;</span>org.springframework.web.filter.DelegatingFilterProxy<span class="hljs-tag">&lt;/<span class="hljs-title">filter-class</span>&gt;</span> <span class="hljs-tag">&lt;/<span class="hljs-title">filter</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-title">filter-mapping</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-title">filter-name</span>&gt;</span>springSessionRepositoryFilter<span class="hljs-tag">&lt;/<span class="hljs-title">filter-name</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-title">url-pattern</span>&gt;</span>/*<span class="hljs-tag">&lt;/<span class="hljs-title">url-pattern</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-title">dispatcher</span>&gt;</span>REQUEST<span class="hljs-tag">&lt;/<span class="hljs-title">dispatcher</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-title">dispatcher</span>&gt;</span>ERROR<span class="hljs-tag">&lt;/<span class="hljs-title">dispatcher</span>&gt;</span> <span class="hljs-tag">&lt;/<span class="hljs-title">filter-mapping</span>&gt;</span><div class="hljs-button signin" data-title="登陸後複製"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li></ul></pre>

<ul> <li>Spring.xml增長配置 <br> 做用是導入redis配置<code>redis.properties</code>,導入新建的一個配置文件<code>spring-session.xml</code></li> </ul>

<pre class="prettyprint" name="code"><code class="hljs r has-numbering" onclick="mdcp.signin(event)">&lt;context:property-placeholder location=<span class="hljs-string">"classpath:db.properties,classpath*:redis.properties"</span> ignore-unresolvable=<span class="hljs-string">"true"</span>/&gt; <span class="hljs-keyword">...</span> &lt;import resource=<span class="hljs-string">"classpath:spring-session.xml"</span>/&gt;<div class="hljs-button signin" data-title="登陸後複製"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li></ul></pre>

<ul> <li>新增配置spring-session.xml</li> </ul>

<pre class="prettyprint" name="code"><code class="hljs xml has-numbering" onclick="mdcp.signin(event)"><span class="hljs-pi">&lt;?xml version="1.0" encoding="UTF-8"?&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-title">beans</span> <span class="hljs-attribute">xmlns</span>=<span class="hljs-value">"http://www.springframework.org/schema/beans"</span> <span class="hljs-attribute">xmlns:xsi</span>=<span class="hljs-value">"http://www.w3.org/2001/XMLSchema-instance"</span> <span class="hljs-attribute">xmlns:util</span>=<span class="hljs-value">"http://www.springframework.org/schema/util"</span> <span class="hljs-attribute">xsi:schemaLocation</span>=<span class="hljs-value">"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"</span>&gt;</span> <span class="hljs-comment">&lt;!-- 建立名爲springSessionRepositoryFilter 的Spring Bean,繼承自Filter。 springSessionRepositoryFilter替換容器默認的HttpSession支持爲Spring Session, 將Session實例存放在Redis中 --&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-title">bean</span> <span class="hljs-attribute">id</span>=<span class="hljs-value">"redisHttpSessionConfiguration"</span> <span class="hljs-attribute">class</span>=<span class="hljs-value">"org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration"</span> /&gt;</span> <span class="hljs-comment">&lt;!-- 使用LettuceConnectionFactory --&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-title">bean </span> <span class="hljs-attribute">class</span>=<span class="hljs-value">"org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory"</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-title">property</span> <span class="hljs-attribute">name</span>=<span class="hljs-value">"hostName"</span> <span class="hljs-attribute">value</span>=<span class="hljs-value">"${redis.ip}"</span> /&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-title">property</span> <span class="hljs-attribute">name</span>=<span class="hljs-value">"port"</span> <span class="hljs-attribute">value</span>=<span class="hljs-value">"${redis.port}"</span> /&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-title">property</span> <span class="hljs-attribute">name</span>=<span class="hljs-value">"password"</span> <span class="hljs-attribute">value</span>=<span class="hljs-value">"${redis.password}"</span> /&gt;</span> <span class="hljs-tag">&lt;/<span class="hljs-title">bean</span>&gt;</span> <span class="hljs-comment">&lt;!-- 也能夠將使用LettuceConnectionFactory改爲使用JedisConnectionFactory,二者保留其一就好 --&gt;</span> <span class="hljs-comment">&lt;!--&lt;bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"&gt; --&gt;</span> <span class="hljs-comment">&lt;!--&lt;property name="hostName" value="${redis.ip}"/&gt; --&gt;</span> <span class="hljs-comment">&lt;!--&lt;property name="port" value="${redis.port}"/&gt; --&gt;</span> <span class="hljs-comment">&lt;!--&lt;property name="password" value="${redis.password}"/&gt; --&gt;</span> <span class="hljs-comment">&lt;!--&lt;/bean&gt; --&gt;</span> <span class="hljs-comment">&lt;!-- 讓Spring Session再也不執行config命令 --&gt;</span> <span class="hljs-comment">&lt;!-- &lt;util:constant static-field="org.springframework.session.data.redis.config.ConfigureRedisAction.NO_OP" /&gt; --&gt;</span> <span class="hljs-tag">&lt;/<span class="hljs-title">beans</span>&gt;</span><div class="hljs-button signin" data-title="登陸後複製"></div></code></pre>

<ul> <li>增長redis.properties</li> </ul>

<blockquote> <p>redis.ip=193.112.76.194 <br> redis.port=6379 <br> redis.password=xxxxxx <br> redis.pool.maxTotal=10 <br> redis.pool.minIdle=4 <br> redis.pool.maxIdle=8 <br> redis.pool.testOnBorrow=true</p> </blockquote>

<p>發佈到服務器上。訪問index頁面。不管刷新多少次結果都同樣。session沒變</p>

<blockquote> <p>個人session:a4b2fe35-aaa5-40c2-a7de-b1d60180ca04 <br> sessionid=a4b2fe35-aaa5-40c2-a7de-b1d60180ca04</p> </blockquote>

<h2 id="使用redis客戶端查看"><a name="t3"></a>使用redis客戶端查看</h2>

<p><img src="https://img-blog.csdn.net/20180418194007520?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM1ODMwOTQ5/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70" alt="這裏寫圖片描述" title=""></p>

<p>恰好有個seession一致。</p>

<h2 id="原理"><a name="t4"></a>原理:</h2>

<p>DelegatingFilterProxy攔截器攔截, springSessionRepositoryFilter替換容器默認的HttpSession支持爲SpringSession每一個請求都會訪問它。</p> </div>

相關文章
相關標籤/搜索