前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring Boot 使用 Spring Session 集成 Redis 实现Session共享Spring Boot 使用 Spring Session 集成 Redis 实现Session共享

Spring Boot 使用 Spring Session 集成 Redis 实现Session共享Spring Boot 使用 Spring Session 集成 Redis 实现Session共享

作者头像
一个会写诗的程序员
发布2018-08-17 10:57:09
3.6K0
发布2018-08-17 10:57:09
举报

Spring Boot 使用 Spring Session 集成 Redis 实现Session共享

《Spring Boot 2.0极简教程》—— 基于 Gradle + Kotlin的企业级应用开发最佳实践

通常在web开发中,Session 会话管理是很重要的一部分,用于存储与用户相关的一些数据。在Java Web 系统中的 Session一般由 Tomcat 容器来管理。不过,使用特定的容器虽然可以很好地实现会话管理,但是基于Tomcat的会话插件实现tomcat-redis-session-manager 和tomcat-memcache-session-manager,会话统一由 NoSql 管理。对于项目本身来说,无须改动代码,只需要简单的配置Tomcat的server.xml就可以解决问题。但是插件太依赖于容器,并且对于Tomcat各个版本的支持不是特别的好。重写Tomcat的session管理,代码耦合度高,不利于维护。而使用开源的Spring Session 框架,既不需要修改Tomcat配置,又无须重写代码,只需要配置相应的参数即可完成分布式系统中的 Session 共享管理。

本章我们来介绍在 Spring Boot 应用中如何使用Spring Session 集成 Redis 实现分布式系统中的Session共享,从而实现 Spring Boot 应用的水平扩展。

1.1 集中式共享 Session 架构

我们通常优先采用水平扩展架构来提升系统的可用性和系统性能。但是更多的应用导致管理更加复杂。对于Spring Boot 应用,会话管理是一个难点。 Spring Boot 应用水平扩展通常有如下两个问题需要解决:

1.负载均衡。将用户请求平均派发到水平部署的任意一台Spring Boot 应用服务器上。可以用一个反向代理服务器来实现,例如使用Nginx作为反向代理服务器。在Spring Cloud 中,我们使用 Zuul(智能路由) 集成Eureka(服务发现)、 Hystrix(断路器) 和 Ribbon(客户端负载均衡)来实现。 2.共享 Session。 单个Spring Boot应用的Session由Tomcat来管理。如果部署多个Spring Boot应用,对于同一个用户请求,实现在这些应用之间共享 Session 通常有如下两种方式:   a.Session 复制:Web服务器通常都支持Session复制,一台应用的 Session 信息改变将立刻复制到其他集群的Web服务器上。   b.集中式 Session 共享 :所有 Web 服务器都共享同一个Session,Session 通常存放在 Redis 数据库服务器上。

Session 复制的缺点是效率较低,性能差。 所以Spring Boot 应用采用集中式 Session 共享。架构图如下:

上图是一个通用的分布式系统架构,包含了三个独立运行的微服务应用。微服务1部署在一台Tomcat服务器上(IP1:9000),微服务2部署在两台Tomcat服务器(IP2:9001、IP3:9002)上采用水平扩展。架构采用Nginx作为反向代理,Nginx提供统一的入口。Spring Boot应用微服务1和微服务2,都采用 Spring Session实现各个子系统共享同一个 Session,该 Session 统一存放在 Redis中。微服务1和微服务2独立部署的,支持水平扩展,最终整合成一个大的分布式系统。

1.2 Spring Session 介绍

Session 一直都是我们做分布式系统架构时需要解决的一个难题,过去我们可以从 Serlvet容器上解决,比如开源servlet容器-tomcat提供的tomcat-redis-session-manager、memcached-session-manager。 或者通过nginx之类的负载均衡做ip_hash,路由到特定的服务器上。而使用 Spring Session 来管理分布式session,则完全实现了与具体的容器无关。Spring Session 是Spring的项目之一,GitHub地址:https://github.com/spring-projects/spring-session

Spring Session 提供了一套创建和管理 Servlet HttpSession 的方案。Spring Session提供了集群 Session(Clustered Sessions)功能,默认采用外置的 Redis 来存储 Session 数据,以此来解决Session共享的问题。

使用Spring Session 可以非常简易地把 Session 存储到第三方存储容器,框架提供了redis、jvm 的 map、mongo、gemfire、hazelcast、jdbc等多种存储 Session 的容器的方式。

1.3 Redis 简介 本节介绍 Redis。Redis是目前使用的非常广泛的内存数据库,相比memcached,它支持更加丰富的数据类型。 1.3.1 Redis 是什么 Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库。 Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。Redis支持数据的备份,即master-slave模式的数据备份。 Redis 优势  性能极高。 Redis能读的速度是110000次/s,写的速度是81000次/s 。  丰富的数据类型 。 Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。  原子性。 Redis的所有操作都是原子性的,意思就是要么成功执行要么失败完全不执行。单个操作是原子性的。多个操作也支持事务,即原子性,通过MULTI和EXEC指令包起来。  丰富的特性。 Redis还支持 publish/subscribe, 通知, key 过期等特性。 Redis运行在内存中但是可以持久化到磁盘,所以在对不同数据集进行高速读写时需要权衡内存,因为数据不能大于硬件内存。在内存数据库方面的另一个优点是,相比在磁盘上相同的复杂的数据结构,在内存中操作起来非常简单,这样Redis可以做很多内部复杂性很强的事情。同时,在磁盘格式方面他们是紧凑的以追加的方式产生的,因为他们并不需要进行随机访问。 1.3.2 安装Redis 使用下面的命令下载安装 redis:

代码语言:javascript
复制
$ wget http://download.redis.io/releases/redis-4.0.9.tar.gz
$ tar xzf redis-4.0.9.tar.gz
$ cd redis-4.0.9
$ make

启动 redis server 进程命令如下:

代码语言:javascript
复制
$ src/redis-server

打开 redis client 命令

代码语言:javascript
复制
$ src/redis-cli
redis> set foo bar
OK
redis> get foo
"bar"

这样我们就简单完成了 redis 的环境配置。 如果需要在远程 redis 服务上执行命令,同样我们使用的也是 redis-cli 命令。语法格式如下 $ redis-cli -h host -p port -a password

代码实例:

$redis-cli -h 127.0.0.1 -p 6379 -a "123456"

连接到主机为 127.0.0.1,端口为 6379 ,密码为 123456 的 redis 服务上。 使用 * 号获取所有配置项命令:

代码语言:javascript
复制
redis 127.0.0.1:6379> config get *
  1) "dbfilename"
  2) "dump.rdb"
  3) "requirepass"
  4) "123456"
  5) "masterauth"
  ...

1.3.3 设置Redis密码 通常我们会设置 redis 密码,命令如下:

127.0.0.1:6379> config set requirepass 123456 OK

测试密码: 127.0.0.1:6379> info NOAUTH Authentication required. 127.0.0.1:6379> set x 0 (error) NOAUTH Authentication required.

提示无权限。使用密码授权登陆: 127.0.0.1:6379> auth 123456 OK 127.0.0.1:6379> set x 0 OK 127.0.0.1:6379> get x "0"

1.3.4 Redis 数据类型 Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。

1.字符串string string是redis最基本的类型,你可以理解成与Memcached一样的类型,一个key对应一个value。string类型是二进制安全的。意思是redis的string可以包含任何数据。比如jpg图片或者序列化的对象 。 string类型是Redis最基本的数据类型,一个键最大能存储512MB。 代码实例 redis 127.0.0.1:6379> set name "Spring Boot Plus Kotlin" OK redis 127.0.0.1:6379> get name "Spring Boot Plus Kotlin"

在以上实例中我们使用了 Redis 的 SET 和 GET 命令。键为 name,对应的值为 "Spring Boot Plus Kotlin"。

2.哈希Hash Redis hash 是一个键值(key => value)对集合。Redis hash 是一个 string 类型的 field 和 value 的映射表,hash 适用于存储对象。 代码实例 redis> HMSET myhash field1 "Hello" field2 "World" "OK" redis> HGET myhash field1 "Hello" redis> HGET myhash field2 "World" 以上实例中 hash 数据类型存储了包含用户脚本信息的用户对象。 实例中我们使用了 Redis HMSET, HGETALL 命令,user:1 为键值。每个 hash 可以存储 2^32 -1 键值对(4294967295)。

3.列表 List Redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)。 代码实例 127.0.0.1:6379> lpush mylist redis (integer) 1 127.0.0.1:6379> lpush mylist springboot (integer) 2 127.0.0.1:6379> lpush mylist kotlin (integer) 3 127.0.0.1:6379> lpush mylist kotlin (integer) 4 127.0.0.1:6379> lrange mylist 0 10

  1. "kotlin"
  2. "kotlin"
  3. "springboot"
  4. "redis" 列表最多可存储 2^32 - 1 元素 (4294967295)。 4.集合 Set Redis的Set是string类型的无序集合。集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。 使用sadd 命令添加一个 string 元素到 key 对应的 set 集合中,成功返回1,如果元素已经在集合中返回 0,如果 key 对应的 set 不存在则返回错误。 向集合添加一个或多个成员命令: SADD key member1 [member2] 代码示例: 127.0.0.1:6379> sadd myset redis (integer) 1 127.0.0.1:6379> sadd myset springboot (integer) 1 127.0.0.1:6379> sadd myset kotlin (integer) 1 127.0.0.1:6379> sadd myset kotlin (integer) 0 获取集合的成员数: SCARD key 代码示例: 127.0.0.1:6379> scard myset (integer) 3

返回集合中的所有成员: SMEMBERS key 代码示例: 127.0.0.1:6379> smembers myset

  1. "kotlin"
  2. "redis"
  3. "springboot"

注意:以上实例中 kotlin 添加了两次,但根据集合内元素的唯一性,第二次插入的元素将被忽略。集合中最大的成员数为 2^32 - 1 (4294967295)。 5.有序集合(sorted set) Redis 有序集合和集合一样也是string类型元素的集合,且不允许重复的成员。不同的是每个元素都会关联一个double类型的分数。redis 正是通过分数来为集合中的成员进行从小到大的排序。有序集合的成员是唯一的,但分数(score)却可以重复。集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。 集合中最大的成员数为 2^32 - 1 (4294967295)。 代码实例 127.0.0.1:6379> ZADD mysortedset 1 redis (integer) 1 127.0.0.1:6379> ZADD mysortedset 2 mongodb (integer) 1 127.0.0.1:6379> ZADD mysortedset 3 mysql (integer) 1 127.0.0.1:6379> ZADD mysortedset 3 mysql (integer) 0 127.0.0.1:6379> ZADD mysortedset 4 mysql (integer) 0 127.0.0.1:6379> ZRANGE mysortedset 0 10 WITHSCORES

  1. "redis"
  2. "1"
  3. "mongodb"
  4. "2"
  5. "mysql"
  6. "4" 在以上实例中我们通过命令 ZADD 向 redis 的有序集合中添加了三个值并关联上分数。我们重复添加了 mysql,分数以最后添加的元素为准。 1.3.5 Spring Boot 集成 Redis 在项目中添加 spring-boot-starter-data-redis 依赖,然后在 application.properties 中配置 spring.redis.* 属性即可使用 StringRedisTemplate模板类来操作 Redis 了。 Spring Data Redis 是对访问redis客户端的一个包装适配,支持Jedis,JRedis,SRP,Lettuce四中开源的redis客户端。RedisTemplate是对redis的CRUD的高级封装,而RedisConnection提供了简单封装。 一个简单的代码示例如下:
代码语言:javascript
复制
@RestController
class RedisTemplateController {
    @Autowired lateinit var stringRedisTemplate: StringRedisTemplate

    @RequestMapping(value = ["/redis/{key}/{value}"], method = [RequestMethod.GET])
    fun redisSave(@PathVariable key: String, @PathVariable value: String): String {

        val redisValue = stringRedisTemplate.opsForValue().get(key)

        if (StringUtils.isEmpty(redisValue)) {
            stringRedisTemplate.opsForValue().set(key, value)
            return String.format("设置[key=%s,value=%s]成功!", key, value)
        }

        if (redisValue != value) {
            stringRedisTemplate.opsForValue().set(key, value)
            return String.format("更新[key=%s,value=%s]成功!", key, value)
        }

        return String.format("redis中已存在[key=%s,value=%s]的数据!", key, value)
    }

    @RequestMapping(value = ["/redis/{key}"], method = [RequestMethod.GET])
    fun redisGet(@PathVariable key: String): String? {
        return stringRedisTemplate.opsForValue().get(key) // String 类型的 value
    }

    @RequestMapping(value = ["/redisHash/{key}/{field}"], method = [RequestMethod.GET])
    fun redisHashGet(@PathVariable key: String, @PathVariable field: String): String? {
        return stringRedisTemplate.opsForHash<String, String>().get(key, field) // Hash 类型的 value
    }
}

StringRedisTemplate 继承了 RedisTemplate 。RedisTemplate是一个泛型类,而StringRedisTemplate则不是。StringRedisTemplate只能对key=String,value=String的键值对进行操作,RedisTemplate可以对任何类型的key-value键值对操作。 StringRedisTemplate 封装了对Redis的一些常用的操作。StringRedisTemplate 使用的是 StringRedisSerializer。RedisTemplate使用的序列类在在操作数据的时候,比如说存入数据会将数据先序列化成字节数组,然后在存入Redis数据库,这个时候打开Redis查看的时候,你会看到你的数据不是以可读的形式展现的。在使用StringRedisSerializer 操作redis数据类型的时候必须要set相对应的序列化。从StringRedisTemplate类的构造函数代码可以看出

代码语言:javascript
复制
public class StringRedisTemplate extends RedisTemplate<String, String> {
    public StringRedisTemplate() {
        RedisSerializer<String> stringSerializer = new StringRedisSerializer();
        setKeySerializer(stringSerializer);
        setValueSerializer(stringSerializer);
        setHashKeySerializer(stringSerializer);
        setHashValueSerializer(stringSerializer);
    }
    ...
}

StringRedisTemplate 和 RedisTemplate 各自序列化的方式不同,但最终都是得到了一个字节数组,殊途同归,StringRedisTemplate使用的是StringRedisSerializer类;RedisTemplate使用的是JdkSerializationRedisSerializer类。反序列化,则是一个得到String,一个得到Object。 测试 redis 操作 1.请求 http://127.0.0.1:9000/redis/x/1,输出:"更新[key=x,value=1]成功!"。 2.再次请求 http://127.0.0.1:9000/redis/x/1,输出:“redis中已存在[key=x,value=1]的数据!”。 3.请求 http://127.0.0.1:9000/redis/x , 输出:1。 4.请求 http://127.0.0.1:9000/redisHash/spring:session:sessions:06830c1b-8157-46fc-b84a-a086aa8c8d45/lastAccessedTime,输出一段不可读的对象数据:“...java.lang.Long;...java.lang.Number...”。

提示:更多关于 Redis 的介绍参考 https://redis.io/download http://try.redis.io/

1.4 项目实战 本节通过完整的项目实例来介绍在 Spring Boot 应用中如何使用 Redis 来实现共享 Session。在分布式系统中,Sessiong 共享有很多的解决方案,其中使用 Redis 缓存是最常用的方案之一。 1.创建项目 创建两个 Spring Boot 应用 demo_microservice_api_book、demo_microservice_api_user,它们的 Session 都使用同一个 Redis 数据库存储。 2.添加依赖 在build.gradle中添加 spring-session-data-redis 就可以使用 Redis来存储 Session。 3.配置Redis 为了简单起见,我们这里就使用的单点 Redis 模式。在实际生产中,为了保障高可用性,通常是一个 Redis 集群。在 application.properties中配置 Redis 信息如下

代码语言:javascript
复制
spring.application.name=demo_microservice_api_user
server.port=9001
################# Redis 基础配置 #################
spring.redis.host=127.0.0.1
spring.redis.password=123456
spring.redis.port=6379
#连接超时时间 单位 ms(毫秒)
spring.redis.timeout=3000ms
################# Redis 线程池设置 #################
#连接池中的最大空闲连接,默认值是8。
spring.redis.jedis.pool.max-idle=10
#连接池中的最小空闲连接,默认值是0。
spring.redis.jedis.pool.min-idle=20
#连接池最大活跃数。默认值8。如果赋值为-1,则表示不限制;如果pool已经分配了maxActive个jedis实例,则此时pool的状态为exhausted(耗尽)。
spring.redis.jedis.pool.max-active=10
# 等待可用连接的最大时间,单位毫秒,默认值为-1ms,表示永不超时。如果超过等待时间,则直接抛出JedisConnectionException
spring.redis.jedis.pool.max-wait=3000ms

4.配置 Session 存储类型 在 application.properties中配置存储 Session的类型为 Redis:

代码语言:javascript
复制
################# 使用 Redis 存储 Session 设置 #################
# Redis|JDBC|Hazelcast|none
spring.session.store-type=Redis

spring-boot-autoconfigure 的源代码中使用RedisAutoConfiguration来加载Redis的配置类RedisProperties。 其中RedisAutoConfiguration会加载 application.properties 文件的前缀为“spring.redis”的属性。其中“spring.redis.sentinel”是哨兵模式的配置,“spring.redis.cluster”是集群模式的配置。

当我们添加spring.session.store-type=Redis这行配置,指定 Session 的存储方式为 Redis,可以看到控制台输出的日志为:

代码语言:javascript
复制
c.e.s.d.SessionController : 
org.springframework.session.web.http.SessionRepositoryFilter.SessionRepositoryRequestWrapper.HttpSessionWrapper

我们可以看到,Session 已经使用了 HttpSessionWrapper 这个包装类实现,HttpSessionWrapper 背后真正负责 Session 管理的适配器类是 HttpSessionAdapter。RedisOperationsSessionRepository 是采用Redis存储 Session 的核心业务逻辑实现。其中的变量DEFAULT_NAMESPACE = "spring:session"定义了Spring Session 存储在 Redis 中的默认命名空间。其中的getSessionKey()方法如下:

代码语言:javascript
复制
String getSessionKey(String sessionId) {
    return this.namespace + "sessions:" + sessionId;
}

通过方法源码,我们可以知道 session id 存储的 Key 是 spring:session:sessions:{sessionId}。这个我们稍后去 Redis 中查看验证。 按照上面的步骤在另一个项目中再次配置一次,启动后,该项目也会自动进行了session共享。

5.测试 Session 数据 分别在两个 Spring Boot 应用中编写获取 Session 数据的 Controller 类 SessionController,代码相同,如下:

代码语言:javascript
复制
@RestController
class SessionController {
    val log = LoggerFactory.getLogger(SessionController::class.java)
    @RequestMapping(value = "/session")
    fun getSession(request: HttpServletRequest): SessionInfo {
        val session = request.session
        log.info(session.javaClass.canonicalName)
        log.info(session.id)

        val SessionInfo = SessionInfo()
        SessionInfo.id = session.id
        SessionInfo.creationTime = session.creationTime
        SessionInfo.lastAccessedTime = session.lastAccessedTime
        SessionInfo.maxInactiveInterval = session.maxInactiveInterval
        SessionInfo.isNew = session.isNew
        return SessionInfo
    }

    class SessionInfo {
        var id = ""
        var creationTime = 0L
        var lastAccessedTime = 0L
        var maxInactiveInterval = 0
        var isNew = false
    }
}

在本机部署 demo_microservice_api_book,端口号为 9000。部署 demo_microservice_api_user 两个运行实例,端口号分别为9001、9002。即使用 gradle bootJar 打可执行 jar 包,然后在命令行分别执行:

代码语言:javascript
复制
$ java -jar demo_microservice_api_user-0.0.1-SNAPSHOT.jar  --server.port=9001
$ java -jar demo_microservice_api_user-0.0.1-SNAPSHOT.jar  --server.port=9002

访问 http://127.0.0.1:9000/session,得到输出 { "id": "06830c1b-8157-46fc-b84a-a086aa8c8d45", "creationTime": 1523693635249, "lastAccessedTime": 1523697391616, "maxInactiveInterval": 1800, "new": false } 访问 http://127.0.0.1:9001/session,得到输出 { "id": "06830c1b-8157-46fc-b84a-a086aa8c8d45", "creationTime": 1523693635249, "lastAccessedTime": 1523697427153, "maxInactiveInterval": 1800, "new": false } 访问 http://127.0.0.1:9002/session,得到输出 { "id": "06830c1b-8157-46fc-b84a-a086aa8c8d45", "creationTime": 1523693635249, "lastAccessedTime": 1523697440377, "maxInactiveInterval": 1800, "new": false } 我们可以看到,这3个独立运行的应用,都共享了同一个 Session Id。通过 Redis 客户端命令行 redis-cli 输入如下命令,查看所有“spring:session:”开头的 keys:

代码语言:javascript
复制
127.0.0.1:6379> keys spring:session:*
...
15) "spring:session:sessions:expires:06830c1b-8157-46fc-b84a-a086aa8c8d45"
16) "spring:session:sessions:06830c1b-8157-46fc-b84a-a086aa8c8d45"
17) "spring:session:sessions:expires:d2193501-1d0b-4f1a-9b50-cd01949ce998"

我们可以看到,spring:session:sessions的值跟我们在浏览器中得到得到结果一样。正如我们看到的一样,session id 在 Redis 中存储的 Key 是 spring:session:sessions:{sessionId}。 通过 redis-cli 查看 Redis 存储的所有 key 命令如下:

代码语言:javascript
复制
127.0.0.1:6379> keys *
…
4) "spring:session:sessions:c3304842-d3a1-42f5-936c-fb73606beda7"
5) "mylist"
6) "spring:session:sessions:expires:c3304842-d3a1-42f5-936c-fb73606beda7"
7) "spring:session:expirations:1523691300000"
…

执行type命令可以获取一个 key 存储的数据类型,例如:

代码语言:javascript
复制
127.0.0.1:6379> type "spring:session:sessions:c3304842-d3a1-42f5-936c-fb73606beda7"
hash

其中"spring:session:sessions:c3304842-d3a1-42f5-936c-fb73606beda7" 为其中的一个key值。表明出该key存储在现在redis服务器中的类型为 hash。此时操作这个数据就必须使用 hset、hget 等操作方法。否则会报错:

代码语言:javascript
复制
127.0.0.1:6379> get "spring:session:sessions:c3304842-d3a1-42f5-936c-fb73606beda7"
(error) WRONGTYPE Operation against a key holding the wrong kind of value

例如,获取在哈希表中指定 key 为"spring:session:sessions:c4a6db26-d86d-47db-b53c-a10d3b997e40"的所有字段和值的命令如下:

代码语言:javascript
复制
127.0.0.1:6379> hgetall "spring:session:sessions:c4a6db26-d86d-47db-b53c-a10d3b997e40"
1) "maxInactiveInterval"
…
3) "lastAccessedTime"
…

单独获取maxInactiveInterval、creationTime的值的命令如下:

代码语言:javascript
复制
127.0.0.1:6379> hget "spring:session:sessions:c4a6db26-d86d-47db-b53c-a10d3b997e40" maxInactiveInterval
…
127.0.0.1:6379> hget "spring:session:sessions:c4a6db26-d86d-47db-b53c-a10d3b997e40" creationTime
…

提示: demo_microservice_api_book 工程源代码: https://github.com/EasySpringBoot/demo_microservice_api_book/tree/demo_session demo_microservice_api_user 工程源代码: https://github.com/EasySpringBoot/demo_microservice_api_user/tree/demo_session

1.5 本章小结 本章我们在Spring Session的基础上完成了Spring Boot应用的水平扩展。通过 Spring Boot + Redis来实现 Session 的共享非常简单,而且用处也极大,配合nginx进行负载均衡,便能实现分布式的应用了。 此处,我们没有对 Redis 进行主从、读写分离等配置。而且,nginx的单点故障也是我们应用的障碍,比如使用zookeeper进行负载均衡。限于篇幅,本书暂不作详细介绍。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018.04.17 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Spring Boot 使用 Spring Session 集成 Redis 实现Session共享
相关产品与服务
云数据库 Redis
腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档