redis實現(xiàn)分布式session的解決方案
一、首先Session
Session 是客戶端與服務器通訊會話技術, 比如瀏覽器登陸、記錄整個瀏覽會話信息。session存放在服務器,關閉瀏覽器不會失效。
Session實現(xiàn)原理
客戶對向服務器端發(fā)送請求后,Session 創(chuàng)建在服務器端,返回Sessionid給客戶端瀏覽器保存在本地,當下次發(fā)送請求的時候,在請求頭中傳遞sessionId獲取對應的從服務器上獲取對應的Sesison
請求過程:
服務器端接受到客戶端請求,會創(chuàng)建一個session,使用響應頭返回 sessionId給客戶端??蛻舳双@取到sessionId后,保存到本地。
下次請求:客戶端將本地的sessionId通過請求頭發(fā)送到服務器。服務器從請求頭獲取到對應的sessionId,使用sessionId在本地session內存中查詢。

HttpSession session = request.getSession(); //默認創(chuàng)建一個session 默認值為true 沒有找到對應的session 自動創(chuàng)建session HttpSession session = request.getSession(false) //true的情況是 客戶端使用對應的sessionId查詢不到對應的session 會直接創(chuàng)建一個新的session 如果有的話直接覆蓋之前的 //false 客戶端使用對應的sessionId查詢不到對應的session 不會創(chuàng)建新的session
session 包括 sessionId和sessionValue
session本身是臨時的 token(令牌)與 sessionId很相似 保證了臨時且唯一
玩下session:
前提需要安裝nginx
配置如下:
host文件:c:\windows\system32\drivers\etc
訪問 www.toov5.com時候 走的nginx的服務器域名 然后默認監(jiān)聽的端口號80。 進而通過配置upstream 負載均衡!

lz在玩時候,弄到了半夜,也沒排查出來原因,媽的氣死了! 地址寫成了 127.0.0.1

yml:
server: port: 8080
pom:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.toov5.loveCode</groupId>
<artifactId>loveCode</artifactId>
<version>0.0.1-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<properties>
<weixin-java-mp.version>2.8.0</weixin-java-mp.version>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.build.locales>zh_CN</project.build.locales>
</properties>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<!-- <exclusions> <exclusion> <groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId> </exclusion> </exclusions> -->
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>
<!-- Testing Dependencies -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--spring session 與redis應用基本環(huán)境配置,需要開啟redis后才可以使用,不然啟動Spring boot會報錯 -->
<!-- <dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency> -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<maimClass>com.meiteedu.WxMpApplication</maimClass>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>服務器端代碼:
package com.toov5.loveCode;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
@RestController
public class TestSessionController {
@Value("${server.port}")
private String serverPort;
@RequestMapping("/")
public String index() {
return serverPort;
}
// 創(chuàng)建session 會話
@RequestMapping("/createSession")
public String createSession(HttpServletRequest request, String nameValue) {
// 默認 創(chuàng)建一個session,
HttpSession session = request.getSession();
System.out.println(
"存入Session sessionid:信息" + session.getId() + ",nameValue:" + nameValue + ",serverPort:" + serverPort);
session.setAttribute("name", nameValue);
return "success-" + serverPort;
}
// 獲取session 會話
@RequestMapping("/getSession")
public Object getSession(HttpServletRequest request) {
// 設置為true 情況下的時候,客戶端使用對應的sessionid 查詢不到對應的sesison 會直接創(chuàng)建一個新的session
// 設置為false 情況下的時候,客戶端使用對應的sessionid 查詢不到對應的sesison 不 會直接創(chuàng)建一個新的session
HttpSession session = request.getSession(true);
if (session == null) {
return serverPort + " 該服務器上沒有存放對應的session值";
}
System.out.println("獲取Session sessionid:信息" + session.getId() + "serverPort:" + serverPort);
Object value = session.getAttribute("name");
return serverPort + "-" + value;
}
}啟動類:啟動兩次 端口號修改8080、 8081
package com.toov5.loveCode;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@EnableAutoConfiguration
@SpringBootApplication
public class AppSession {
public static void main(String[] args) {
SpringApplication.run(AppSession.class, args);
}
}運行結果:8080 和 8081來回切換 負載均衡

調用服務器端方法: fist 存放在8080


查詢不到哦!

8081 沒有 就創(chuàng)建新的session 覆蓋原來的sessionId true沒有就創(chuàng)建
下次 又去8080 又沒有 又創(chuàng)建 來回折騰..............

此時:

修改false 沒有時候不創(chuàng)建

然后傳入 value 然后繼續(xù)輪訓訪問;


二、分布式Session
1、直接使用cookie替代session 不安全(存客戶端)
2、Nginx的IP綁定 目的是同一個IP只能指定同一個機器訪問(相當于沒做集群了)
3、 使用數(shù)據(jù)庫(效率低)
4、tomcat內置Session同步,通過廣播可能產生延遲,占用帶寬
5、使用 Spring-Session框架,相當于把session緩存緩存到redis中 (緩存框架,緩存Session的值)
6、可以使用token替代session功能。自定義令牌替代session
Spring-Session 重寫httpsession框架,將對應的值緩存到redis中,有點類似于一級、二級緩存。
必須要有的!

yml文件:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.toov5.loveCode</groupId>
<artifactId>loveCode</artifactId>
<version>0.0.1-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<properties>
<weixin-java-mp.version>2.8.0</weixin-java-mp.version>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.build.locales>zh_CN</project.build.locales>
</properties>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<!-- <exclusions> <exclusion> <groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId> </exclusion> </exclusions> -->
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>
<!-- Testing Dependencies -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--spring session 與redis應用基本環(huán)境配置,需要開啟redis后才可以使用,不然啟動Spring boot會報錯 -->
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<maimClass>com.meiteedu.WxMpApplication</maimClass>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>非常非常重要的:一定要jredis引入 同時這個對session提供了大力支持哈哈

yml 的redis配置文件:
server: port: 8080 redis: hostname: 192.168.91.3 port: 6379 password: 123
后臺業(yè)務邏輯:
package com.toov5.loveCode;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
@RestController
public class TestSessionController {
@Value("${server.port}")
private String serverPort;
@RequestMapping("/")
public String index() {
return serverPort;
}
// 創(chuàng)建session 會話
@RequestMapping("/createSession")
public String createSession(HttpServletRequest request, String nameValue) {
// 默認 創(chuàng)建一個session,
HttpSession session = request.getSession();
System.out.println(
"存入Session sessionid:信息" + session.getId() + ",nameValue:" + nameValue + ",serverPort:" + serverPort);
session.setAttribute("name", nameValue);
return "success-" + serverPort;
}
// 獲取session 會話
@RequestMapping("/getSession")
public Object getSession(HttpServletRequest request) {
// 設置為true 情況下的時候,客戶端使用對應的sessionid 查詢不到對應的sesison 會直接創(chuàng)建一個新的session
// 設置為false 情況下的時候,客戶端使用對應的sessionid 查詢不到對應的sesison 不 會直接創(chuàng)建一個新的session
HttpSession session = request.getSession(false);
if (session == null) {
return serverPort + " 該服務器上沒有存放對應的session值";
}
System.out.println("獲取Session sessionid:信息" + session.getId() + "serverPort:" + serverPort);
Object value = session.getAttribute("name");
return serverPort + "-" + value;
}
}配置:
package com.toov5.loveCode;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
//這個類用配置redis服務器的連接
//maxInactiveIntervalInSeconds為SpringSession的過期時間(單位:秒)
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 1800)
public class SessionConfig {
// 冒號后的值為沒有配置文件時,制動裝載的默認值
@Value("${redis.hostname:localhost}")
String HostName;
@Value("${redis.port:6379}")
int Port;
@Value("${redis.password}")
String password;
@Bean
public JedisConnectionFactory connectionFactory() {
JedisConnectionFactory connection = new JedisConnectionFactory();
connection.setPort(Port);
connection.setHostName(HostName);
connection.setPassword(password);
return connection;
}
}初始化:
package com.toov5.loveCode;
import org.springframework.session.web.context.AbstractHttpSessionApplicationInitializer;
//初始化Session配置
public class SessionInitializer extends AbstractHttpSessionApplicationInitializer{
public SessionInitializer() {
super(SessionConfig.class);
}
}啟動類:
package com.toov5.loveCode;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@EnableAutoConfiguration
@SpringBootApplication
public class AppSession {
public static void main(String[] args) {
SpringApplication.run(AppSession.class, args);
}
}

雖然是存放在8081,但是訪問時候 都有哦~ 大家試試玩玩吧~~
引入的jar包重寫了 HttpSession類 去解決Session共享問題
而此時的:redis

控制臺:

補充:
Spring Boot 整合redis:

到此這篇關于redis實現(xiàn)分布式session的解決方案的文章就介紹到這了,更多相關redis 分布式session內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Redis如何使用樂觀鎖(CAS)保證數(shù)據(jù)一致性
本文主要介紹了Redis如何使用樂觀鎖(CAS)保證數(shù)據(jù)一致性,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-03-03

