15.Redis实现分布式Session管理
7.Redis的session管理和Memcached的session管理不同.jpg
注意:1、MSM是将Tomcat服务器做整合,所有部署到Tomcat服务器上的应用都可以进行session共享,但是Tomcat服务器和Memcached存在耦合。 2、RSM是基于某个应用的整合,必须是spring的项目,如果部署的应用没有进行整合,将无法用session共享。服务器和redis不存在耦合。
15.1 管理机制
redis的session管理是利用spring提供的session管理解决方案,将一个应用session交给Redis存储,整个应用中所有session的请求都会去redis中获取对应的session数据。
image-20200628201643358.png
15.2 开发Session管理
1. 引入依赖
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
2. 开发Session管理配置类
@Configuration
@EnableRedisHttpSession
public class RedisSessionManager {
}
3.打包测试即可
实现:
1、创建一个新的springboot工程
2、引入相关依赖
<!--springboot-redis-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--spring-data-redis session管理-->
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
3、Application.properties连接redis集群
server.port=8989
server.servlet.context-path=/redissession
spring.redis.cluster.nodes=192.168.159.2:7000,192.168.159.2:7001,192.168.159.2:7002,192.168.159.2:7003,192.168.159.2:7004,192.168.159.2:7005,192.168.159.2:7006
4、创建config包,编写RedisSessionManager
@Configuration
@EnableRedisHttpSession //将整个应用中使用的session全部交给redis
public class RedisSessionManager {
}
5、创建controller包,编写TestController
package com.nono.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@Controller
@RequestMapping("test")
public class TestController {
// redis session list 1
// jvm list 地址 list.add list.size 2
//使用redis 的session管理 注意:当session中数据发生变化时必须将session中变化的数据同步到redis中
@RequestMapping("test")
public void test(HttpServletRequest request, HttpServletResponse response) throws IOException {
List<String> list = (List<String>) request.getSession().getAttribute("list");
if(list==null){
list = new ArrayList<>();
}
list.add("xxxx");
request.getSession().setAttribute("list",list);//每次session变化都要同步session
response.getWriter().println("size: "+list.size());
response.getWriter().println("sessionid: "+request.getSession().getId());
}
@RequestMapping("logout")
public void logout(HttpServletRequest request){
//退出登录
request.getSession().invalidate();//失效
}
}
6、启动本地运行代码访问
image.png
image.png
将项目以war包形式运行在服务器
1、排除内嵌的tomcat 和 将打包方式设置为war
<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.nono</groupId>
<artifactId>redis_session_manager</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>redis_session_manager</name>
<description>reids session manager for Spring Boot</description>
<packaging>war</packaging>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--springboot-redis-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--spring-data-redis session管理-->
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
<!--排除内嵌的tomcat-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2、入口类继承SpringBootServletInitializer,重写configure方法
package com.nono;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
@SpringBootApplication
public class RedisSessionManagerApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(RedisSessionManagerApplication.class, args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(RedisSessionManagerApplication.class);
}
}
3、打包
先clear-再package
image.png
4、创建3个tomcat服务
image.png
5、修改这个三个tomcat的server.xml
<!-- Note: A "Server" is not itself a "Container", so you may not
define subcomponents such as "Valves" at this level.
Documentation at /docs/config/server.html
-->
<Server port="8003" shutdown="SHUTDOWN"> 8003-8005
<!-- A "Connector" represents an endpoint by which requests are received
and responses are returned. Documentation at :
Java HTTP Connector: /docs/config/http.html
Java AJP Connector: /docs/config/ajp.html
APR (HTTP/AJP) Connector: /docs/apr.html
Define a non-SSL/TLS HTTP/1.1 Connector on port 8080
-->
<Connector port="8989" protocol="HTTP/1.1"....>8989-8991
<!-- Define an AJP 1.3 Connector on port 8009 -->
<Connector port="10010" protocol="AJP/1.3" redirectPort="8443" />10010-10012
6、启动三个tomcat
[root@localhost ~]# ls
anaconda-ks.cfg testSession.war tom4 tom5 tom6 tom8-msm tomcat1 tomcat2 tomcat3
[root@localhost ~]# ./tom4/bin/startup.sh
Using CATALINA_BASE: /root/tom4
Using CATALINA_HOME: /root/tom4
Using CATALINA_TMPDIR: /root/tom4/temp
Using JRE_HOME: /usr/java/jdk1.8.0_171-amd64
Using CLASSPATH: /root/tom4/bin/bootstrap.jar:/root/tom4/bin/tomcat-juli.jar
Tomcat started.
[root@localhost ~]# ./tom5/bin/startup.sh
Using CATALINA_BASE: /root/tom5
Using CATALINA_HOME: /root/tom5
Using CATALINA_TMPDIR: /root/tom5/temp
Using JRE_HOME: /usr/java/jdk1.8.0_171-amd64
Using CLASSPATH: /root/tom5/bin/bootstrap.jar:/root/tom5/bin/tomcat-juli.jar
Tomcat started.
[root@localhost ~]# ./tom6/bin/startup.sh
Using CATALINA_BASE: /root/tom6
Using CATALINA_HOME: /root/tom6
Using CATALINA_TMPDIR: /root/tom6/temp
Using JRE_HOME: /usr/java/jdk1.8.0_171-amd64
Using CLASSPATH: /root/tom6/bin/bootstrap.jar:/root/tom6/bin/tomcat-juli.jar
Tomcat started.
image.png
查看tomcat日志:
tail -f tom4/logs/catalina.out
7、配置nginx
将三个tomcat交给nginx:
upstream tomcat-servers {
# ip_hash;
# least_conn
server 192.168.159.3:8989;
server 192.168.159.3:8990;
server 192.168.159.3:8991;
}
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
# location / {
# root html;
# index index.html index.htm;
# }
location / {
proxy_pass http://tomcat-servers;
proxy_redirect off;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
proxy_next_upstream http_502 http_504 error timeout invalid_header;
}
启动nginx:
启动前查看一下nginx的进程是否有,否则重复会出现端口错误
ps aux|grep nginx
[root@localhost sbin] ./nginx -c /usr/nginx/conf/nginx.conf
访问:nginx的服务器应该跳出来tomcat页面
image.png
8、拷贝我们的war包到三个tomcat-webapps中
image.png
image.png