一、首先Session
Session 是客戶端與服務(wù)器通訊會(huì)話技術(shù), 比如瀏覽器登陸、記錄整個(gè)瀏覽會(huì)話信息。session存放在服務(wù)器,關(guān)閉瀏覽器不會(huì)失效。
Session實(shí)現(xiàn)原理
客戶對(duì)向服務(wù)器端發(fā)送請(qǐng)求后,Session 創(chuàng)建在服務(wù)器端,返回Sessionid給客戶端瀏覽器保存在本地,當(dāng)下次發(fā)送請(qǐng)求的時(shí)候,在請(qǐng)求頭中傳遞sessionId獲取對(duì)應(yīng)的從服務(wù)器上獲取對(duì)應(yīng)的Sesison
請(qǐng)求過(guò)程:
服務(wù)器端接受到客戶端請(qǐng)求,會(huì)創(chuàng)建一個(gè)session,使用響應(yīng)頭返回 sessionId給客戶端。客戶端獲取到sessionId后,保存到本地。
下次請(qǐng)求:客戶端將本地的sessionId通過(guò)請(qǐng)求頭發(fā)送到服務(wù)器。服務(wù)器從請(qǐng)求頭獲取到對(duì)應(yīng)的sessionId,使用sessionId在本地session內(nèi)存中查詢。
HttpSession session = request.getSession(); //默認(rèn)創(chuàng)建一個(gè)session 默認(rèn)值為true 沒(méi)有找到對(duì)應(yīng)的session 自動(dòng)創(chuàng)建session HttpSession session = request.getSession(false) //true的情況是 客戶端使用對(duì)應(yīng)的sessionId查詢不到對(duì)應(yīng)的session 會(huì)直接創(chuàng)建一個(gè)新的session 如果有的話直接覆蓋之前的 //false 客戶端使用對(duì)應(yīng)的sessionId查詢不到對(duì)應(yīng)的session 不會(huì)創(chuàng)建新的session
session 包括 sessionId和sessionValue
session本身是臨時(shí)的 token(令牌)與 sessionId很相似 保證了臨時(shí)且唯一
玩下session:
前提需要安裝nginx
配置如下:
host文件:c:windowssystem32driversetc
訪問(wèn) www.toov5.com時(shí)候 走的nginx的服務(wù)器域名 然后默認(rèn)監(jiān)聽(tīng)的端口號(hào)80。 進(jìn)而通過(guò)配置upstream 負(fù)載均衡!
lz在玩時(shí)候,弄到了半夜,也沒(méi)排查出來(lái)原因,媽的氣死了! 地址寫(xiě)成了 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應(yīng)用基本環(huán)境配置,需要開(kāi)啟redis后才可以使用,不然啟動(dòng)Spring boot會(huì)報(bào)錯(cuò) --> <!-- <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>
服務(wù)器端代碼:
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 會(huì)話 @RequestMapping("/createSession") public String createSession(HttpServletRequest request, String nameValue) { // 默認(rèn) 創(chuàng)建一個(gè)session, HttpSession session = request.getSession(); System.out.println( "存入Session sessionid:信息" + session.getId() + ",nameValue:" + nameValue + ",serverPort:" + serverPort); session.setAttribute("name", nameValue); return "success-" + serverPort; } // 獲取session 會(huì)話 @RequestMapping("/getSession") public Object getSession(HttpServletRequest request) { // 設(shè)置為true 情況下的時(shí)候,客戶端使用對(duì)應(yīng)的sessionid 查詢不到對(duì)應(yīng)的sesison 會(huì)直接創(chuàng)建一個(gè)新的session // 設(shè)置為false 情況下的時(shí)候,客戶端使用對(duì)應(yīng)的sessionid 查詢不到對(duì)應(yīng)的sesison 不 會(huì)直接創(chuàng)建一個(gè)新的session HttpSession session = request.getSession(true); if (session == null) { return serverPort + " 該服務(wù)器上沒(méi)有存放對(duì)應(yīng)的session值"; } System.out.println("獲取Session sessionid:信息" + session.getId() + "serverPort:" + serverPort); Object value = session.getAttribute("name"); return serverPort + "-" + value; } }
啟動(dòng)類(lèi):?jiǎn)?dòng)兩次 端口號(hào)修改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); } }
運(yùn)行結(jié)果:8080 和 8081來(lái)回切換 負(fù)載均衡
調(diào)用服務(wù)器端方法: fist 存放在8080
查詢不到哦!
8081 沒(méi)有 就創(chuàng)建新的session 覆蓋原來(lái)的sessionId true沒(méi)有就創(chuàng)建
下次 又去8080 又沒(méi)有 又創(chuàng)建 來(lái)回折騰..............
此時(shí):
修改false 沒(méi)有時(shí)候不創(chuàng)建
然后傳入 value 然后繼續(xù)輪訓(xùn)訪問(wèn);
二、分布式Session
1、直接使用cookie替代session 不安全(存客戶端)
2、Nginx的IP綁定 目的是同一個(gè)IP只能指定同一個(gè)機(jī)器訪問(wèn)(相當(dāng)于沒(méi)做集群了)
3、 使用數(shù)據(jù)庫(kù)(效率低)
4、tomcat內(nèi)置Session同步,通過(guò)廣播可能產(chǎn)生延遲,占用帶寬
5、使用 Spring-Session框架,相當(dāng)于把session緩存緩存到redis中 (緩存框架,緩存Session的值)
6、可以使用token替代session功能。自定義令牌替代session
Spring-Session 重寫(xiě)httpsession框架,將對(duì)應(yīng)的值緩存到redis中,有點(diǎn)類(lèi)似于一級(jí)、二級(jí)緩存。
必須要有的!
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應(yīng)用基本環(huán)境配置,需要開(kāi)啟redis后才可以使用,不然啟動(dòng)Spring boot會(huì)報(bào)錯(cuò) --> <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引入 同時(shí)這個(gè)對(duì)session提供了大力支持哈哈
yml 的redis配置文件:
server: port: 8080 redis: hostname: 192.168.91.3 port: 6379 password: 123
后臺(tái)業(yè)務(wù)邏輯:
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 會(huì)話 @RequestMapping("/createSession") public String createSession(HttpServletRequest request, String nameValue) { // 默認(rèn) 創(chuàng)建一個(gè)session, HttpSession session = request.getSession(); System.out.println( "存入Session sessionid:信息" + session.getId() + ",nameValue:" + nameValue + ",serverPort:" + serverPort); session.setAttribute("name", nameValue); return "success-" + serverPort; } // 獲取session 會(huì)話 @RequestMapping("/getSession") public Object getSession(HttpServletRequest request) { // 設(shè)置為true 情況下的時(shí)候,客戶端使用對(duì)應(yīng)的sessionid 查詢不到對(duì)應(yīng)的sesison 會(huì)直接創(chuàng)建一個(gè)新的session // 設(shè)置為false 情況下的時(shí)候,客戶端使用對(duì)應(yīng)的sessionid 查詢不到對(duì)應(yīng)的sesison 不 會(huì)直接創(chuàng)建一個(gè)新的session HttpSession session = request.getSession(false); if (session == null) { return serverPort + " 該服務(wù)器上沒(méi)有存放對(duì)應(yīng)的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; //這個(gè)類(lèi)用配置redis服務(wù)器的連接 //maxInactiveIntervalInSeconds為SpringSession的過(guò)期時(shí)間(單位:秒) @EnableRedisHttpSession(maxInactiveIntervalInSeconds = 1800) public class SessionConfig { // 冒號(hào)后的值為沒(méi)有配置文件時(shí),制動(dòng)裝載的默認(rèn)值 @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); } }
啟動(dòng)類(lèi):
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,但是訪問(wèn)時(shí)候 都有哦~ 大家試試玩玩吧~~
引入的jar包重寫(xiě)了 HttpSession類(lèi) 去解決Session共享問(wèn)題
而此時(shí)的:redis
控制臺(tái):
補(bǔ)充:
Spring Boot 整合redis:
到此這篇關(guān)于redis實(shí)現(xiàn)分布式session的解決方案的文章就介紹到這了,更多相關(guān)redis 分布式session內(nèi)容請(qǐng)搜索服務(wù)器之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持服務(wù)器之家!
原文地址:https://www.cnblogs.com/toov5/p/9903017.html