nginx 解決session一致性


session 粘滯性
每個請求按訪問ip的hash結果分配,這樣每個訪客固定訪問一個后端服務器,可以解決session的問題。 
upstream backserver {
ip_hash;
server 192.168.0.14:88;
server 192.168.0.15:80;
}
但是有缺點,這存在單點風險,倘若我已經在192.168.0.14:88端口登錄后,過段時間發現14服務器掛了(session時間未過期),那么這時候會訪問到15服務器,那這時候需要重新登錄,因為在拿14服務器上的JsessionId去15服務器請求發現不存在。
2、session 復制

可以通過tomcat的server.xml文件進行配置,這樣每個tomcat都會同步對應的session,那么此時即使某個tomcat被宕機了,也不影響服務。
具體的tomcat可以參見如下 ,tomcat 官網對應的tomcat集群配置
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"
channelSendOptions="8">

<Manager className="org.apache.catalina.ha.session.DeltaManager"
expireSessionsOnShutdown="false"
notifyListenersOnReplication="true"/>

<Channel className="org.apache.catalina.tribes.group.GroupChannel">
<Membership className="org.apache.catalina.tribes.membership.McastService"
address="228.0.0.4"
port="45564"
frequency="500"
dropTime="3000"/>
<Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
address="auto"
port="4000"
autoBind="100"
selectorTimeout="5000"
maxThreads="6"/>

<Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter">
<Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/>
</Sender>
<Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/>
<Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatchInterceptor"/>
</Channel>

<Valve className="org.apache.catalina.ha.tcp.ReplicationValve"
filter=""/>
<Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/>

<Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer"
tempDir="/tmp/war-temp/"
deployDir="/tmp/war-deploy/"
watchDir="/tmp/war-listen/"
watchEnabled="false"/>

<ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
</Cluster>
3、session 共享(springboot)

  對應的項目中pom文件添加
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
在對應的application.properties中配置redis信息
spring.redis.host=localhost
spring.redis.port=6379
添加開啟spring session支持的注解@EnableRedisHttpSession
@Configuration
@EnableRedisHttpSession
public class RedisSessionConfig {
}
添加驗證的接口
@Value("${server.port}")
String port;

@GetMapping("/session")
public Object getSession(HttpServletRequest request){
Map<String, Object> map = new HashMap<String, Object>();
map.put("SessionId", request.getSession().getId());
map.put("ServerPort", "服務端口號為 "+port);
return map;
}
訪問 http://localhost:8080/session

我們看下redis緩存的數據

可以發現sessionId已經緩存在redis數據庫中
下面我們換個端口再訪問一次看看
這次我把端口換成了8888 訪問:http://localhost:8888/session

刷新了redis數據庫,緩存的數據也沒變

結果中的SessionId是一致的,卻是由兩個不同項目工程來提供服務。這樣子,SpringSession 利用攔截器 Filter 幫我們在每個請求前進行了同步設置,達到了分布式系統中 session 共享。
4、session 共享(springmvc 版本)

首先在pom.xml文件中添加對應的jar

<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>
在對應springmvc-context.xml文件中配置

<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" />
<property name="testOnBorrow" value="true" />
</bean>

<bean id="connectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" >
<property name="poolConfig" ref="jedisPoolConfig" />
<property name="port" value="6379" />
<property name="hostName" value="192.168.1.11" />
<property name="password" value="xxx" />
<property name="timeout" value="30000" ></property>
</bean >

<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate" >
<property name="connectionFactory" ref="connectionFactory" />
<property name="keySerializer">
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />
</property>
<property name="valueSerializer">
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />
</property>
</bean >

<bean id="redisUtil" class="com.isea533.mybatis.service.RedisUtil" >
<property name="redisTemplate" ref="redisTemplate" />
</bean >
其次在web.xml中配置(非常重要,filter的名字必須是springSessionRepositoryFilter)

<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>
訪問項目路徑呈現結果

 


————————————————
版權聲明:本文為CSDN博主「小風010766」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/u011196623/article/details/84453758


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM