C#session共享+redis_分布式session共享解决方案

e3bb5664dfe153ca891a68ebd50b3724.png

首先聊聊session和cookie,session对象存储在服务器端节点内存中,cookie存储在客户端浏览器中。一般是客户端请求服务器,服务器端生成session对象,将session对象存储在jvm内存中,并且在响应头中放入sessionId响应给客户端,客户端收到响应后,将sessionid存储在本地。当浏览器第二次请求时会将本地cookie中存储的seesionId通过请求头的方式传递给服务器,这样服务器和客户端就能保持会话信息啦!如下图

b81e2a9fc2843be6ecad8f6eb5392dc4.png

6184ced838b0c89b405cb9513fbb2e00.png

那么为什么会出现分布式session问题呢,为了提高服务器端的负载能力,后台一般将服务器节点做集群,通过ngnix通过轮询的方式转发到目标服务器。打个比方,当浏览器首次访问A服务器生成session对象,然后在访问生成的session对象,如果正好被ngnix转发到了A服务器,那么没问题可以获取到session对象,如果不巧请求被转发到B服务器,由于之前生成的session对象在A服务器,B服务器根本没有生成session对象,很自然访问不到session对象。

知道了问题的存在,那么我们如何解决了,可以通过token令牌代替session解决,或者采用spring-session解决,这里我们选择后一种方式,其实解决思路都是一样的。分布式session不能共享是由于session对象存储在jvm内存中,那么如果共享,答案是将session放入redis中存在,这样不管有多少台应用服务器节点,都能共享redis中存储的session对象。思路很简单,下面给出实现。首先我们引人maven依赖:

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.1.RELEASE</version>
</parent>
<dependencies><!--springboot web组件-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency><!--redis客户端连接工具-->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency><!--springboot整合redis-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency><!--springboot整合session-->
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
</dependencies>

添加配置application.yml

server: port: 8080spring: redis: database: 0host: localhostport: 6379jedis: pool: max-active: 20max-wait: -1max-idle: 10min-idle: 0timeout: 10000

redis连接配置

@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 1800)public class SessionConfig {
@Value("${redis.hostname:localhost}")private String hostName;
@Value("${redis.port:6379}")private int port;
@Beanpublic JedisConnectionFactory connectionFactory() {
JedisConnectionFactory connection = new JedisConnectionFactory();
connection.setPort(port);
connection.setHostName(hostName);return connection;
}
}

生成session和获取session

68f6bef690cccd1429a1667939da552e.png

ngnix轮询配置

524edff90c63eb08738955f7b945d099.png

启动ngnix和redis,然后启动2台服务器通过端口区分

8080启动成功

aeef8dfea02c827709b34cc9d4e22f5b.png

8081启动成功

81cd7cee392030917369e63063c295bf.png

首先生成session对象

61961af765a342ab260685fcfee0f7e7.png

然后在二台服务器都能获取到session对象中存储的内容

dd0d6fd53e3d6c2f2a8f8efd0ce67200.png

fe15d94875d8cd32be3df3087a09ef44.png

完结!错误之处,望大佬批评指正!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您可以按照以下步骤来实现Tomcat 8与Redis哨兵模式的Session共享: 1. 首先,确保您已经安装了Tomcat 8和Redis,并且Redis已经配置为哨兵模式。您可以参考Redis官方文档来进行配置。 2. 在Tomcat的conf目录下,创建一个新的文件夹,命名为context。在该文件夹下创建一个新的XML文件,命名为yourappname.xml(将yourappname替换为您的应用程序名称)。 3. 在yourappname.xml文件中,添加以下内容: ```xml <?xml version="1.0" encoding="UTF-8"?> <Context> <Valve className="org.apache.catalina.session.PersistentManager" saveOnRestart="true" maxIdleBackup="30" expireSessionsOnShutdown="false"> <Store className="org.apache.catalina.session.RedisSessionHandlerValve"/> </Valve> </Context> ``` 4. 在Tomcat的lib目录下,创建一个新的文件夹,命名为redis-session-manager。将以下JAR文件复制到该文件夹中: - jedis.jar - commons-pool2.jar - tomcat-redis-session-manager.jar 5. 在Tomcat的conf目录下,打开context.xml文件,在`<Context>`标签内添加以下内容: ```xml <Manager className="de.javakaffee.web.msm.redis.RedisSessionManager" host="your_redis_host" port="your_redis_port" database="your_redis_database" password="your_redis_password" maxInactiveInterval="your_session_timeout"> </Manager> ``` 将上述内容中的your_redis_host、your_redis_port、your_redis_database、your_redis_password和your_session_timeout替换为您的Redis连接信息和会话超时时间。 6. 在Tomcat的catalina.properties文件中,添加以下内容: ```properties redis-session-manager.enabled=true redis-session-manager.config.path=/path/to/tomcat/conf/context/yourappname.xml ``` 将/path/to/tomcat/conf/context/yourappname.xml替换为您在步骤2中创建的XML文件的实际路径。 7. 重启Tomcat服务器,使配置生效。 现在,您的Tomcat 8应该与Redis哨兵模式实现了Session共享。您可以在多个Tomcat节点上部署您的应用程序,并且它们将共享会话数据。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值