Spring Session Redis

什么是 HttpSession
是 JavaWeb 服务端提供的用来建立与客户端会话状态的对象。
 

什么是 Session 共享
是指在一个浏览器对应多个 Web 服务时,服务端的 Session 数据需要共享。
 

Session 共享应用场景
1) 单点登录
2) Web 服务器集群等场景都需要用到
 

Session 复制
通过对应用服务器的配置开启服务器的 Session 复制功能,在集群中的几台服务器之间同步 Session 对象,使得每台服务器上都保存所有的 Session 信息,这样任何一台宕机都不会导致 Session 的数据丢失,服务器使用 Session 时,直接从本地获取。这种方式的缺点也比较明显。因为 Session 需要时时同步,并且同步过程是有应用服务器来完成,由此对服务器的性能损耗也比较大。

Session 绑定
利用 hash 算法,比如 nginx 的 ip_hash,使得同一个 Ip 的请求分发到同一台服务器上。这种方式不符合对系统的高可用要求,因为一旦某台服务器宕机,那么该机器上的Session 也就不复存在了,用户请求切换到其他机器后么有 Session,无法完成业务处理。
 

利用 Cookie 记录 Session
Session 记录在客户端,每次请求服务器的时候,将 Session 放在请求中发送给服务器,服务器处理完请求后再将修改后的 Session 响应给客户端。这里的客户端就是 cookie。
利用 cookie 记录 Session 的也有缺点,比如受 cookie 大小的限制,能记录的信息有限,安全性低,每次请求响应都需要传递 cookie,影响性能,如果用户关闭 cookie,访问就不正常。

Session 服务器
Session 服务器可以解决上面的所有的问题,利用独立部署的 Session 服务器统一管理
Session,服务器每次读写 Session 时,都访问 Session 服务器。对于 Session 服务器,我们可以使用 Redis 或者 MongoDB 等内存数据库来保存 Session中的数据,以此替换掉服务中的 HttpSession。达到 Session 共享的效果。
 

什么是 Spring Session
Spring Session 是 Spring 的项目之一。Spring Session 提供了一套创建和管理 ServletHttpSession 的方案,默认采用外置的 Redis 来存储 Session 数据,以此来解决 Session 共享的问题。
 

Spring Session 的使用
安装 Redis(单机)
第一步 需要在 linux 系统中安装 gcc
命令:
yum install-y gcc-c++
第二步 需要将下载好的 redis 压缩包添加到 linux 服务器中
版本:redis-3.0.0.tar.gz
redis 的版本:副版本号奇数版本号是测试版,不建议在生产环境中使用。
偶数版本时稳定版建议在生产环境中使用。3.0 版本更新比较大。集成了集群技术
 
第三步 解压压缩包
命令:
tar-zxvf redis......
第四步 编译 redis
命令:进入 redis 的解压完毕的根目录下 执行命令:
make
第五步 安装 redis
命 令 : 进 入 redis 的 解 压 完 毕 的 根 目 录 下 , 执 行 命 令 :
 make installPREFIX=/usr/local/redis
第六步:启动 redis
1,前端启动
在 bin 目录下执行命令:
./redis-server 

(ctrl+c)退出 redis

2.后端启动
(1)先将 redis 解压目录下的 redis.conf 文件拷贝到 安装好的 redis 的 bin 目录下
命令:
cp redis.conf /usr/local/redis/bin
(2)修改拷贝过来的 redis.conf 配置文件
命令:
vim redis.conf
将 daemonize no 改为 yes
 
(3)启动 redis
在 bin 目录下执行命令:
./redis-server redis.conf
(4)查看 redis 启动是否成功
输入命令:
ps aux|grep redis
(5) 关闭 redis 的命令
./redis-cli shutdown
第七步:测试 redis
在 bin 目录下启动 redis 自带的客户端
./redis-cli
常见 redis 命令:
ping

如果正常的启动应该会影响pong

 
 

搭建案例环境

版本介绍
JDK:1.8
Spring Boot:2.1.6.RELEASE
Spring Session:Bean-SR3

创建项目
创建父工程 spring_session

创建模块 session_service1

创建模块 session_service2
 

修改 POM 文件添加坐标依赖
修改父工程 POM 文件
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.bjsxt</groupId>
    <artifactId>spring_session</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>session_server1</module>
        <module>session_server2</module>
    </modules>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.9.RELEASE</version>
    </parent>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.session</groupId>
                <artifactId>spring-session-bom</artifactId>
                <version>Bean-SR3</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>

        <!--web Starter-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!--Redis Starter-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-redis</artifactId>
            <version>1.4.7.RELEASE</version>
        </dependency>

        <!--Spring session data redis-->
        <dependency>
            <groupId>org.springframework.session</groupId>
            <artifactId>spring-session-data-redis</artifactId>
        </dependency>

        <!--Lettuce 是一个基于Netty的NIO方式处理Redis的技术-->
        <dependency>
            <groupId>io.lettuce</groupId>
            <artifactId>lettuce-core</artifactId>
        </dependency>
    </dependencies>
</project>

添加配置文件

session_service1
server:
  port: 8081
spring:
  application:
    name: server1
  redis:
    host: 192.168.181.136
    port: 6379
    database: 0

session_service2
server:
  port: 8082
spring:
  application:
    name: server2
  redis:
    host: 192.168.181.136
    port: 6379
    database: 0

创建启动类
com.bjsxt.SessionServer1Application
package com.bjsxt;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;

@SpringBootApplication
@EnableRedisHttpSession(redisNamespace = "user")/*(maxInactiveIntervalInSeconds = 10)配置Redis的失效时间*/
public class SessionServer1Application {

    public static void main(String[] args) {
        SpringApplication.run(SessionServer1Application.class,args);
    }
}
 
com.bjsxt.SessionServer2Application
package com.bjsxt;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;

@SpringBootApplication
@EnableRedisHttpSession(redisNamespace = "user")/*(maxInactiveIntervalInSeconds = 10)配置Redis的失效时间*/
public class SessionServer2Application {
    public static void main(String[] args) {
        SpringApplication.run(SessionServer2Application.class,args);
    }
}
 

编写测试代码测试效果

session_service1
创建 Controller
package com.bjsxt.controller;

import com.bjsxt.pojo.Roles;
import com.bjsxt.pojo.User;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpSession;

@RestController
@RequestMapping("/server1")
public class WebController {

    @RequestMapping("/setMsg")
    public String setMsg(HttpSession session,String msg){
        session.setAttribute("msg",msg);
        return "ok";
    }

    @RequestMapping("/setUser")
    public String setUser(HttpSession session){
        Roles roles=new Roles();
        roles.setRid(1001);
        roles.setName("VIP会员");
        User user=new User();
        user.setName("yxf");
        user.setAge(22);
        user.setRoles(roles);
        session.setAttribute("user",user);
        return "success";
    }
}

session_service2
com.bjsxt.controller.WebController
package com.bjsxt.controller;

import com.bjsxt.pojo.User;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpSession;

@RestController
@RequestMapping("/server2")
public class WebController {

    @RequestMapping("/getMsg")
    public String getMsg(HttpSession session){
        String msg = (String) session.getAttribute("msg");
        return msg;
    }

    @RequestMapping("/getUser")
    public User getUser(HttpSession session){
        User user = (User) session.getAttribute("user");
        return user;
    }
}

猜你喜欢

转载自www.cnblogs.com/sakura-yxf/p/12069709.html