14.1. Spring框架整合
Redisson不仅完美地支持运行在Spring框架下,还提供了和Spring框架的各项特性类似的,以Spring XML的命名空间的方式配置RedissonClient
实例和它所支持的所有对象和服务。
首先需要做的是向你的Spring XML文件增加一个Redisson的引用描述:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:redisson="http://redisson.org/schema/redisson"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://redisson.org/schema/redisson
http://redisson.org/schema/redisson/redisson.xsd
">
...
</beans>
然后按照配置方法文档中介绍的方法配置需要的Redisson实例类型。比如一个单Redis节点模式的配置方法如下:
<!-- 最基本配置 -->
<redisson:client>
<!-- 默认地址是 127.0.0.1:6379 -->
<redisson:single-server/>
</redisson:client>
<!-- 或者 -->
<redisson:client>
<redisson:single-server address="${redisAddress}"/>
</redisson:client>
其它连接类型的使用范例以及所有的可变参数均可在配置方法文档中找到。
你可能注意到上面例子里使用了一个属性表达式来指定连接的地址。这种使用方式是直接通过Spring自身提供的功能来实现的,你只需要在你的XML文件中增加一个<context:property-placeholder/>
元素标签即可。如果你希望在项目中使用Spring提供的自动依赖注入功能,请不要忘了同时增加<context:annotation-config/>
的元素标签。
通常情况下在一个应用程序里创建一个Redisson实例就已经能够满足正常的使用了,但是在个别的情况下,一个应用程序可能会遇到需要同时连接多个不同的Redis环境,这就需要多个Redisson实例同时并存。你可以通过定义多个<redisson:client/>
元素标签来实现这个要求:
<redisson:client id="myRedisson1" name="redisson1,redisson2" >
<redisson:single-server address="127.0.0.1:6379" client-name="1"/>
</redisson:client>
<redisson:client id="myRedisson2" name="redisson3,redisson4">
<redisson:single-server address="127.0.0.1:6380" client-name="2"/>
</redisson:client>
Redisson实例之间是通过它们的id
属性值来区分的,这个值也同时被用来在自动依赖注入时作为qualifier
的备选值使用。在name
属性中出现的多个由英文逗号分开的值是作为这个bean
的化名的方式来解析的,它们在自动依赖注入时也会被用来作为qualifier
的备选值使用。
也可以通过定义一个qualifier
元素标签来明确的指定它的qualifier
备选值,但是这个元素标签不能同时和name
属性共存。
<redisson:client>
<qualifier value="qualifiedName"/>
<redisson:single-server address="127.0.0.1:6379"/>
</redisson:client>
除了定义Redisson实例以外,其它Redisson提供的对象和服务也可以通过类似的方式来定义。它们既可以作为<Redisson:client/>
的子元素在它的内部申明,和可以在XML文件的其他地方申明。在外部申明的时候需要指定一个Redisson bean的引用。
代表Redisson对象的XML元素采用了Spring建议的命名法则。它们和Redisson一样都使用了同样的命名空间:
<redisson:client id="myRedisson">
<redisson:single-server address="127.0.0.1:6379"/>
<redisson:map id="map" key="map"/>
</redisson:client>
<!-- 或者 -->
<redisson:map id="map1" key="map" redisson-ref="myRedisson"/>
同样的道理,Redisson提供的服务也可以用同样的方法来获取:
<redisson:client id="myRedisson">
<redisson:single-server address="127.0.0.1:6379"/>
<redisson:executor-service
id="executorService"
service="executorServiceName"/>
</redisson:client>
<!-- 或者 -->
<redisson:executor-service
id="executorService"
service="executorServiceName"
redisson-ref="myRedisson"/>
不仅如此,对于Redisson的分布式远程服务(Remote Service)和分布式实时对象(Live Object)服务来说,你可以通过同样的Spring XML命名空间的方式来实现服务的注册和服务对象的获取:
<redisson:remote-service
id="remoteService"
service="remoteServiceName"
redisson-ref="myRedisson">
<!-- 注册服务 -->
<redisson:rpc-server
api-class="com.example.MyTestService"
bean="myTestServiceBean"/>
<!-- 获取代理后的服务对象 -->
<redisson:rpc-client
id="client"
api-class="com.example.MyTestService">
<redisson:remote-invocation-options>
<redisson:remote-ack within="1" time-unit="SECONDS"/>
<redisson:remote-result within="1" time-unit="SECONDS"/>
</redisson:remote-invocation-options>
</redisson:rpc-client>
</redisson:remote-service>
<!-- 服务对象 -->
<bean id="myTestServiceBean" class="com.example.MyTestServiceImpl"/>
<redisson:live-object-service
id="live-object-service-ext"
redisson-ref="myRedisson">
<!-- 注册类 -->
<redisson:live-object-registration class="com.example.MyTestEntity"/>
<!-- 获取代理后的实例 -->
<redisson:live-object
id="liveObject"
object-id="testLiveObjectId"
class="com.example.MyTestEntity"/>
</redisson:live-object-service>
很明显在这些服务被申明在一个<redisson:client/>
元素标签的内部时,它的redisson-ref
属性可以略去不用写。
下面是所有支持的对象和服务的使用范例:
<redisson:client>
<redisson:single-server address="127.0.0.1:6379"/>
<redisson:binary-stream id="binary-stream" key="binary-stream"/>
<redisson:geo id="geo" key="geo"/>
<redisson:set-cache id="set-cache" key="set-cache"/>
<redisson:map-cache id="map-cache" key="map-cache"/>
<redisson:bucket id="bucket" key="bucket"/>
<redisson:buckets id="buckets"/>
<redisson:hyper-log-log id="hyper-log-log" key="hyper-log-log"/>
<redisson:list id="list" key="list"/>
<redisson:list-multimap id="list-multimap" key="list-multimap"/>
<redisson:list-multimap-cache id="list-multimap-cache" key="list-multimap-cache"/>
<redisson:local-cached-map id="local-cached-map" key="local-cached-map">
<redisson:local-cached-map-options id="local-options" eviction-policy="LRU" time-to-live="1" time-to-live-unit="SECONDS"/>
</redisson:local-cached-map>
<redisson:map id="map" key="map"/>
<redisson:set-multimap id="set-multimap" key="set-multimap"/>
<redisson:set-multimap-cache id="set-multimap-cache" key="set-multimap-cache"/>
<redisson:semaphore id="semaphore" key="semaphore"/>
<redisson:permit-expirable-semaphore id="permit-expirable-semaphore" key="permit-expirable-semaphore"/>
<redisson:lock id="lock" key="lock"/>
<redisson:fair-lock id="fair-lock" key="fair-lock"/>
<redisson:read-write-lock id="read-write-lock" key="read-write-lock">
<redisson:read-lock id="read-lock"/>
<redisson:write-lock id="write-lock"/>
</redisson:read-write-lock>
<redisson:multi-lock id="multi-lock">
<ref bean="lock"/>
<redisson:lock id="lock-1" key="lock-1"/>
<redisson:fair-lock id="fair-lock-1" key="fair-lock-1"/>
<redisson:write-lock id="write-lock-1" read-write-lock-ref="read-write-lock"/>
<redisson:read-lock id="read-lock-1" read-write-lock-ref="read-write-lock"/>
</redisson:multi-lock>
<redisson:red-lock id="red-lock">
<ref bean="lock"/>
<redisson:lock id="lock-2" key="lock-2"/>
<redisson:fair-lock id="fair-lock-2" key="fair-lock-2"/>
<redisson:write-lock id="write-lock-2" read-write-lock-ref="read-write-lock"/>
<redisson:read-lock id="read-lock-2" read-write-lock-ref="read-write-lock"/>
</redisson:red-lock>
<redisson:set id="set" key="set"/>
<redisson:sorted-set id="sorted-set" key="sorted-set"/>
<redisson:scored-sorted-set id="scored-sorted-set" key="scored-sorted-set"/>
<redisson:lex-sorted-set id="lex-sorted-set" key="lex-sorted-set"/>
<redisson:topic id="topic" topic="topic"/>
<redisson:pattern-topic id="pattern-topic" pattern="pattern-topic"/>
<redisson:blocking-fair-queue id="blocking-fair-queue" key="blocking-fair-queue"/>
<redisson:queue id="queue" key="queue"/>
<redisson:delayed-queue id="delayed-queue" destination-queue-ref="queue"/>
<redisson:priority-queue id="priority-queue" key="priority-queue"/>
<redisson:priority-deque id="priority-deque" key="priority-deque"/>
<redisson:blocking-queue id="blocking-queue" key="blocking-queue"/>
<redisson:bounded-blocking-queue id="bounded-blocking-queue" key="bounded-blocking-queue"/>
<redisson:deque id="deque" key="deque"/>
<redisson:blocking-deque id="blocking-deque" key="blocking-deque"/>
<redisson:atomic-long id="atomic-long" key="atomic-long"/>
<redisson:atomic-double id="atomic-double" key="atomic-double"/>
<redisson:count-down-latch id="count-down-latch" key="count-down-latch"/>
<redisson:bit-set id="bit-set" key="bit-set"/>
<redisson:bloom-filter id="bloom-filter" key="bloom-filter"/>
<redisson:script id="script"/>
<redisson:executor-service id="executor-service" service="executor-service"/>
<redisson:remote-service id="remote-service" service="remote-service">
<redisson:rpc-server api-class="com.example.MyTestService" bean="myServiceBean"/>
<redisson:rpc-client id="rpc-client" api-class="com.example.MyTestService">
<redisson:remote-invocation-options id="options">
<!-- 以下二选一 -->
<!--<redisson:remote-no-ack/>-->
<redisson:remote-ack within="1" time-unit="SECONDS"/>
<!-- 以下二选一 -->
<!--<redisson:remote-no-result/>-->
<redisson:remote-result within="1" time-unit="SECONDS"/>
</redisson:remote-invocation-options>
</redisson:rpc-client>
</redisson:remote-service>
<redisson:keys id="keys"/>
<redisson:live-object-service id="live-object-service">
<redisson:live-object-registration class="com.example.MyEntity" />
<redisson:live-object id="live-object" object-id="live-object" class="com.example.MyEntity" />
</redisson:live-object-service>
</redisson:client>
Spring的qualifier
元素标签可以作为子节点被放置在所有上面提到的类型里。
Redisson提供的底层Redis客户端也可以用同样的方式来获取。
<!-- 底层Redis客户端最基本配置-->
<!-- 默认使用的主机为127.0.0.1,端口为6379 -->
<redisson:redis/>
<!-- 或者 -->
<redisson:redis
host="127.0.0.1"
port="6379"
connection-timeout="10000"
command-timeout="10000"/>
14.2. Spring Cache整合
Redisson提供了将Redis无缝整合到Spring框架的能力。Redisson依照Spring Cache标准提供了基于Redis的Spring缓存实现。 每个缓存(Cache)实例都提供了了两个重要的可配置参数:过期时间(ttl)
和最长空闲时间(maxIdleTime)
,如果这两个参数都未指定或值为0
,那么实例管理的数据将永久保存。
配置范例:
@Configuration
@ComponentScan
@EnableCaching
public static class Application {
@Bean(destroyMethod="shutdown")
RedissonClient redisson() throws IOException {
Config config = new Config();
config.useClusterServers()
.addNodeAddress("127.0.0.1:7004", "127.0.0.1:7001");
return Redisson.create(config);
}
@Bean
CacheManager cacheManager(RedissonClient redissonClient) {
Map<String, CacheConfig> config = new HashMap<String, CacheConfig>();
// 创建一个名称为"testMap"的缓存,过期时间ttl为24秒钟,同时最长空闲时maxIdleTime为12秒钟。
config.put("testMap", new CacheConfig(24*60*1000, 12*60*1000));
return new RedissonSpringCacheManager(redissonClient, config);
}
}
Spring Cache也可以通过JSON或YAML配置文件来配置:
@Configuration
@ComponentScan
@EnableCaching
public static class Application {
@Bean(destroyMethod="shutdown")
RedissonClient redisson(@Value("classpath:/redisson.json") Resource configFile) throws IOException {
Config config = Config.fromJSON(configFile.getInputStream());
return Redisson.create(config);
}
@Bean
CacheManager cacheManager(RedissonClient redissonClient) throws IOException {
return new RedissonSpringCacheManager(redissonClient, "classpath:/cache-config.json");
}
}
14.2.1. Spring Cache - 本地缓存和数据分片
Redisson提供了几种不同的Spring Cache Manager,按功能可以分为以下两大类:
- 本地缓存(Local Cache) 类 -- 本地缓存(Local Cache)也叫就近缓存(Near Cache)。这类Spring Cache的使用主要用于在特定的场景下,映射缓存(MapCache)上的高度频繁的读取操作,使网络通信都被视为瓶颈的情况。Redisson与Redis通信的同时,还将部分数据保存在本地内存里。这样的设计的好处是它能将读取速度提高最多 45倍 。
- 数据分片(Sharding) 类 -- 数据分片(Sharding)类仅适用于Redis集群环境下,因此带有数据分片(Sharding)功能的Spring Cache也叫集群分布式Spring缓存。它利用分库的原理,将单一一个缓存结构切分为若干个小的缓存,并均匀的分布在集群中的各个槽里。这样的设计能使Spring缓存突破Redis自身的容量限制,让其容量随集群的扩大而增长。在扩容的同时,还能够使读写性能和元素淘汰处理能力随之成线性增长。
以下列表是Redisson提供的所有Spring Cache Manager的名称及其特性:
类名 | 本地缓存功能 Local Cache |
数据分片功能 Sharding |
---|---|---|
RedissonSpringCacheManager |
No | No |
RedissonSpringLocalCachedCacheManager 仅限于Redisson PRO版本 |
Yes | No |
RedissonClusteredSpringCacheManager 仅限于Redisson PRO版本 |
No | Yes |
RedissonSpringClusteredLocalCachedCacheManager 仅限于Redisson PRO版本 |
Yes | Yes |
在初始化org.redisson.spring.cache.RedissonSpringLocalCachedCacheManager
对象和org.redisson.spring.cache.RedissonSpringClusteredLocalCachedCacheManager
对象的时候可以通过LocalCachedMapOptions
对象来配置选项。
LocalCachedMapOptions options = LocalCachedMapOptions.defaults()
// 淘汰机制有LFU, LRU和NONE这几种算法策略可供选择
.evictionPolicy(EvictionPolicy.LFU)
.cacheSize(1000)
// 如果该值是`真(true)`时,在该实例执行更新和删除操作的同时,将向其他所有的相同实例发
// 送针对该元素的淘汰消息。其他相同实例在收到该消息以后,会同时删除自身的缓存。下次读取
// 该元素时会从Redis服务器获取。
.invalidateEntryOnChange(false)
// 每个Map本地缓存里元素的有效时间,默认毫秒为单位
.timeToLive(10000)
// 或者
.timeToLive(10, TimeUnit.SECONDS)
// 每个Map本地缓存里元素的最长闲置时间,默认毫秒为单位
.maxIdle(10000)
// 或者
.maxIdle(10, TimeUnit.SECONDS);
Redisson为每个Spring缓存实例都提供了两个很重要的参数:ttl
和maxIdleTime
,当两个参数设为0
或为指定值时,缓存数据将永久保留。
完整的使用范例如下:
@Configuration
@ComponentScan
@EnableCaching
public static class Application {
@Bean(destroyMethod="shutdown")
RedissonClient redisson() throws IOException {
Config config = new Config();
config.useClusterServers()
.addNodeAddress("127.0.0.1:7004", "127.0.0.1:7001");
return Redisson.create(config);
}
@Bean
CacheManager cacheManager(RedissonClient redissonClient) {
Map<String, CacheConfig> config = new HashMap<String, CacheConfig>();
LocalCachedMapOptions options = LocalCachedMapOptions.defaults()
.evictionPolicy(EvictionPolicy.LFU)
.cacheSize(1000);
// 创建一个名称为"testMap"的缓存,过期时间ttl为24秒钟,同时最长空闲时maxIdleTime为12秒钟。
config.put("testMap", new LocalCachedCacheConfig(24*60*1000, 12*60*1000, options));
return new RedissonSpringLocalCachedCacheManager(redissonClient, config);
}
}
也可以通过JSON或YAML配置文件来设置相关缓存参数:
@Configuration
@ComponentScan
@EnableCaching
public static class Application {
@Bean(destroyMethod="shutdown")
RedissonClient redisson(@Value("classpath:/redisson.yaml") Resource configFile) throws IOException {
Config config = Config.fromYAML(configFile.getInputStream());
return Redisson.create(config);
}
@Bean
CacheManager cacheManager(RedissonClient redissonClient) throws IOException {
return new RedissonSpringLocalCachedCacheManager(redissonClient, "classpath:/cache-config.yaml");
}
}
14.2.2. Spring Cache - JSON和YAML配置文件格式:
JSON:
{
"testMap": {
"ttl": 1440000,
"maxIdleTime": 720000,
"localCacheOptions": {
"invalidationPolicy": "ON_CHANGE",
"evictionPolicy": "NONE",
"cacheSize": 0,
"timeToLiveInMillis": 0,
"maxIdleInMillis": 0
}
}
}
YAML:
---
testMap:
ttl: 1440000
maxIdleTime: 720000
localCacheOptions:
invalidationPolicy: "ON_CHANGE"
evictionPolicy: "NONE"
cacheSize: 0
timeToLiveInMillis: 0
maxIdleInMillis: 0
以上内容是名叫testMap
的Spring缓存实例的配置方式。
需要注意的是:localCacheOptions
配置实例仅适用于org.redisson.spring.cache.RedissonSpringLocalCachedCacheManager
类和org.redisson.spring.cache.RedissonSpringClusteredLocalCachedCacheManager
类。
14.3. Hibernate整合
hibernate-redis项目实现了Redisson与Hibernate的完美整合。
14.3.1. Hibernate二级缓存 - 本地缓存和数据分片
Redisson提供了几种不同的Hibernate Cache Factory,按功能主要分为两大类:
- 本地缓存 类 -- 本地缓存(Local Cache)也叫就近缓存(Near Cache)。这类Hibernate Cache的使用主要用于在特定的场景下,映射缓存(MapCache)上的高度频繁的读取操作,使网络通信都被视为瓶颈的情况。Redisson与Redis通信的同时,还将部分数据保存在本地内存里。这样的设计的好处是它能将读取速度提高最多 5倍 。
- 数据分片 类 -- 数据分片(Sharding)类仅适用于Redis集群环境下,因此带有数据分片(Sharding)功能的Hibernate Cache也叫集群分布式Hibernate二级缓存。它利用分库的原理,将单一一个缓存结构切分为若干个小的缓存,并均匀的分布在集群中的各个槽里。这样的设计能使Hibernate缓存突破Redis自身的容量限制,让其容量随集群的扩大而增长。在扩容的同时,还能够使读写性能和元素淘汰处理能力随之成线性增长。
以下列表是Redisson提供的所有Hibernate Cache Factory的名称及其特性:
类名 | 本地缓存功能 Local Cache |
数据分片功能 Sharding |
---|---|---|
SingletonRedisRegionFactory |
No | No |
LocalCachedRedisRegionFactory 仅限于Redisson PRO版本 |
Yes | No |
ClusteredRedisRegionFactory 仅限于Redisson PRO版本 |
No | Yes |
ClusteredLocalCachedRedisRegionFactory 仅限于Redisson PRO版本 |
Yes | Yes |
配置范例如下:
// 二级缓存
props.put(Environment.USE_SECOND_LEVEL_CACHE, true);
props.put(Environment.USE_QUERY_CACHE, true);
props.put(Environment.CACHE_REGION_FACTORY, org.redisson.hibernate.v52.LocalCachedRedisRegionFactory.class.getName());
props.put(Environment.CACHE_REGION_PREFIX, "hibernate");
// 为Hibernate提供Redis相关的配置
props.put(Environment.CACHE_PROVIDER_CONFIG, "hibernate-redis.properties");
hibernate-redis.properties文件范例:
hibernate-redis.properties文件
# redisson配置文件地址
redisson-config=conf/redisson.yaml
# 为缓存指定默认过期时间
redis.expiryInSeconds.default=120
# 为缓存指定默认过期策略
# 如果过期策略采用了`ON_CHANGE`、`ON_CHANGE_WITH_CLEAR_ON_RECONNECT`或是`ON_CHANGE_WITH_LOAD_ON_RECONNECT`
# 那么在修改或删除映射元素的时候,相应的映射元素将被从所有掌握该缓存的Hibernate本地缓存实例中驱除
redis.localCache.invalidationPolicy.default=ON_CHANGE_WITH_CLEAR_ON_RECONNECT
# 如果本地缓存最大数量设定为`0`则表示默认缓存的元素数量不受限制
redis.localCache.cacheSize.default=10000
# 有`LFU`、`LRU`、`SOFT`、`WEAK`以及`NONE`这几种默认驱逐策略可供选择
redis.localCache.evictionPolicy.default=LFU
# 默认每个本地缓存中的元素过期时间
redis.localCache.timeToLiveInMillis.default=1000000
# 默认每个本地缓存中的元素最大闲置时间
redis.localCache.maxIdleInMillis.default=1000000
# 指定`player`区域的过期时间
redis.expiryInSeconds.hibernate.player=900
# `player`区域的本地缓存相关设定
redis.localCache.invalidationPolicy.hibernate.player=ON_CHANGE_WITH_CLEAR_ON_RECONNECT
redis.localCache.cacheSize.hibernate.player=10000
redis.localCache.evictionPolicy.hibernate.player=LFU
redis.localCache.timeToLiveInMillis.hibernate.player=1000000
redis.localCache.maxIdleInMillis.hibernate.player=1000000
需要注意的是: redis.localCache.*
配置参数仅适用于ClusteredLocalCachedRedisRegionFactory
类和LocalCachedRedisRegionFactory
类。
14.4. Java缓存标准规范JCache API (JSR-107)
Redisson在Redis的基础上实现了Java缓存标准规范(JCache API JSR-107)
以下范例展示了使用Java缓存标准的用法。范例采用了保存在默认路径/redisson-jcache.json
或/redisson-jcache.yaml
下的配置文件构造实例。
MutableConfiguration<String, String> config = new MutableConfiguration<>();
CacheManager manager = Caching.getCachingProvider().getCacheManager();
Cache<String, String> cache = manager.createCache("namedCache", config);
也可以采用指定配置文件路径的方式构造实例:
MutableConfiguration<String, String> config = new MutableConfiguration<>();
// JSON格式的配置文件
URI redissonConfigUri = getClass().getResource("redisson-jcache.json").toURI();
// YAML格式的配置文件
URI redissonConfigUri = getClass().getResource("redisson-jcache.yaml").toURI();
CacheManager manager = Caching.getCachingProvider().getCacheManager(redissonConfigUri, null);
Cache<String, String> cache = manager.createCache("namedCache", config);
还可以通过程序化的方式来构造:
MutableConfiguration<String, String> jcacheConfig = new MutableConfiguration<>();
Config redissonCfg = ...
Configuration<String, String> config = RedissonConfiguration.fromConfig(redissonCfg, jcacheConfig);
CacheManager manager = Caching.getCachingProvider().getCacheManager();
Cache<String, String> cache = manager.createCache("namedCache", config);
甚至可以用Redisson实例来构造:
MutableConfiguration<String, String> jcacheConfig = new MutableConfiguration<>();
RedissonClient redisson = ...
Configuration<String, String> config = RedissonConfiguration.fromInstance(redisson, jcacheConfig);
CacheManager manager = Caching.getCachingProvider().getCacheManager();
Cache<String, String> cache = manager.createCache("namedCache", config);
关于配置Redisson的方式详见这里
由Redisson提供的JCache(JSR-107)完全符合标准要求并全部通过TCK标准检测。标准检验代码在这里。
14.5. Tomcat会话管理器(Tomcat Session Manager)
Redisson为Apache Tomcat集群提供了基于Redis的非黏性会话管理功能。该功能支持Apache Tomcat的6.x、7.x、8.x和9.x版。
Redisson实现的方式有别于现有的其他的Tomcat会话管理器(Tomcat Session Manager)。在每次调用HttpSession.setAttribute
接口方法时,以每一条会话的字段属性(Attribute)为单位,将修改内容记录在Redis的一个Hash结构里。相比之下,其他的现有解决方案都普遍采用的是:在任何一个字段属性更改时,将整个会话序列化后保存。Redisson的实现方式产生的优势显而易见:在为Tomcat集群提供高效的非黏性会话管理的同时,避免了同一客户端的多个并发请求造成业务逻辑混乱。
使用方法:
- 首先将
RedissonSessionManager
添加到相关的context.xml
(求中文文档连接)里:
<Manager className="org.redisson.tomcat.RedissonSessionManager"
configPath="${catalina.base}/redisson.conf" updateMode="DEFAULT" />
readMode
- 用来设定读取会话里各个属性的方式。主要分为以下两种:
-
MEMORY
- 内存读取模式。直接从本地Tomcat中的会话里读取。这是默认情况。 -
REDIS
- Redis读取模式。绕过本地会话信息,直接从Redis里读取。
updateMode
- 用来设定更新会话属性的方式。主要有以下两种:
-
DEFAULT
- 会话的属性只能通过setAttribute
方法来储存到Redis里。这是默认请况。 -
AFTER_REQUEST
- 再每次请求结束以后进行一次所有属性全量写入Redis。
configPath
- 是指的Redisson的JSON或YAML格式的配置文件路径。配置文件详见这里。
-
拷贝相应的 两个 JAR包到指定的
TOMCAT_BASE/lib
目录下:- JDK 1.8+适用
redisson-all-3.6.0.jar
Tomcat 6.x适用
[redisson-tomcat-6-3.6.0.jar](https://repository.sonatype.org/service/local/artifact/maven/redirect?r=central-proxy&g=org.redisson&a=redisson-tomcat-6&v=3.6.0&e=jar)
Tomcat 7.x适用
[redisson-tomcat-7-3.6.0.jar](https://repository.sonatype.org/service/local/artifact/maven/redirect?r=central-proxy&g=org.redisson&a=redisson-tomcat-7&v=3.6.0&e=jar)
Tomcat 8.x适用
[redisson-tomcat-8-3.6.0.jar](https://repository.sonatype.org/service/local/artifact/maven/redirect?r=central-proxy&g=org.redisson&a=redisson-tomcat-8&v=3.6.0&e=jar)
Tomcat 9.x适用
[redisson-tomcat-9-3.6.0.jar](https://repository.sonatype.org/service/local/artifact/maven/redirect?r=central-proxy&g=org.redisson&a=redisson-tomcat-9&v=3.6.0&e=jar)
- JDK 1.6+适用
redisson-all-2.11.0.jar
Tomcat 6.x适用
[redisson-tomcat-6-2.11.0.jar](https://repository.sonatype.org/service/local/artifact/maven/redirect?r=central-proxy&g=org.redisson&a=redisson-tomcat-6&v=2.11.0&e=jar)
Tomcat 7.x适用
[redisson-tomcat-7-2.11.0.jar](https://repository.sonatype.org/service/local/artifact/maven/redirect?r=central-proxy&g=org.redisson&a=redisson-tomcat-7&v=2.11.0&e=jar)
Tomcat 8.x适用
[redisson-tomcat-8-2.11.0.jar](https://repository.sonatype.org/service/local/artifact/maven/redirect?r=central-proxy&g=org.redisson&a=redisson-tomcat-8&v=2.11.0&e=jar)
- JDK 1.8+适用
14.6. Spring Session会话管理器
Redisson还提供了Spring Session会话管理器的实现。
在每次调用HttpSession.setAttribute
接口方法时,以每一条会话的字段属性(Attribute)为单位,将修改内容记录在Redis的一个Hash结构里。
使用方法:
-
首先请确保
spring-session
版本号为1.2.2+的依赖已经添加到了您的项目中:
#### Maven<dependency> <groupId>org.springframework.session</groupId> <artifactId>spring-session</artifactId> <version>2.0.0.RELEASE</version> </dependency>
#### Gradle
compile 'org.springframework.session:spring-session:2.0.0.RELEASE'
-
然后将
@EnableRedissonHttpSession
注释和Redisson
实例添加到Spring的配置里:@EnableRedissonHttpSession public class Config { @Bean public RedissonClient redisson() { return Redisson.create(); } }
-
然后提供一个启动器
AbstractHttpSessionApplicationInitializer
的扩展就行了:public class Initializer extends AbstractHttpSessionApplicationInitializer { public Initializer() { super(Config.class); } }
14.7. JMX与Dropwizard Metrics
结合Dropwizard Metrics,我们可以很轻松地把Redisson采集的各项性能指标展示出来。
配置方法
Config config = ... // Redisson的Config对象
config.enableMetrics()
.setRegistryName("myMetrics")
// 启用JMX管理接口
.setJmxEnabled()
// 设定JMX管理域
.setJmxDomain("myDomain");
...
// 通过程序化的方式创建Redisson的MetricsRegistry对象
MetricRegistry registry = SharedMetricRegistries.getOrCreate("myMetrics")
也可以在JSON格式的配置文件中添加以下配置参数:
"enableMetrics":{
"jmxEnabled": false,
"jmxDomain": "myDomain",
"registryName": "myRegistry"
}
也可以在YAML格式的配置文件中添加以下配置参数:
enableMetrics:
jmxEnabled: false
jmxDomain: "myDomain"
registryName: "myRegistry"
Redisson提供了以下这些性能监控指标
客户端配置相关指标
-
redisson.executor-pool-size
- [Gauge] 用于展示Executor线程池大小的度量值 -
redisson.netty-pool-size
- [Gauge] 用于展示Netty线程池大小的度量值
每个Redis节点的指标
名称前缀格式:redisson.redis.<host>:<port>
-
status
- [Gauge] 用于展示连接状态,连接 和 断开 状态的值分别为:[connected, disconnected] -
type
- [Gauge] 用于展示节点类型,主节点 和 从节点 的状态值分别为:[MASTER, SLAVE] -
bytes-read
- [Meter] 用于统计从该节点读取的字节量 -
bytes-written
- [Meter] 用于统计写入到该节点的字节量 -
connections.active
- [Counter] 用于显示客户端到该Redis节点的连接池当前 正在使用 的连接数量 -
connections.free
- [Counter] 用于显示客户端到该Redis节点的连接池当前 空闲 的连接数量 -
connections.max-pool-size
- [Counter] 用于显示客户端到该Redis节点的连接池大小 -
connections.total
- [Counter] 用于显示客户端到该Redis节点的连接池当前 所有 的连接数量 -
operations.total
- [Meter] 用于统计客户端到该Redis节点所有 已发送 的指令数量 -
operations.total-failed
- [Meter] 用于统计客户端到该Redis节点所有 发送失败 的指令数量 -
operations.total-successful
- [Meter] 用于统计客户端到该Redis节点所有 发送成功 的指令数量 -
publish-subscribe-connections.active
- [Counter] 用于显示客户端到该Redis节点用于订阅发布的连接池 正在使用 的连接数量 -
publish-subscribe-connections.free
- [Counter] 用于显示客户端到该Redis节点用于订阅发布的连接池 空闲 的连接数量 -
publish-subscribe-connections.max-pool-size
- [Counter] 用于显示客户端到该Redis节点用于订阅发布的连接池大小 -
publish-subscribe-connections.total
- [Counter] 用于显示客户端到该Redis节点用于订阅发布的连接池 所有 的连接数量
每个分布式远程服务(RRemoteService)对象的指标
名称前缀格式:redisson.remote-service.<name>
-
invocations.total
- [Meter] 用于统计该远程服务对象所有 已执行 的请求数量 -
invocations.total-failed
- [Meter] 用于统计该远程服务对象 执行失败 的请求数量 -
invocations.total-successful
- [Meter] 用于统计该远程服务对象 执行成功 的请求数量
每个分布式执行服务(RExecutorService)对象的指标
名称前缀格式:redisson.executor-service.<name>
-
tasks.submitted
- [Meter] 用于统计 已提交 的任务数量 -
tasks.executed
- [Meter] 用于统计 已执行 的任务数量 -
workers.active
- [Gauge] 用于统计 工作中 的任务线程(Workers)数量 -
workers.free
- [Gauge] 用于统计 空闲 的任务线程(Workers)数量 -
workers.total
- [Gauge] 用于统计 所有 的任务线程(Workers)数量 -
workers.tasks-executed.total
- [Meter] 用于统计任务线程(Workers) 已执行 的任务数量 -
workers.tasks-executed.total-failed
- [Meter] 用于统计任务线程(Workers) 执行失败 的任务数量 -
workers.tasks-executed.total-successful
- [Meter] 用于统计任务线程(Workers) 执行成功 的任务数量
每个分布式映射(RMap)对象的指标
名称前缀:redisson.map.<name>
-
hits
- [Meter] 用于统计 Redis命中(Redis内 有 需要的数据)的次数 -
misses
- [Meter] 用于统计 Redis未命中(Redis内 没有 需要的数据)的次数 -
puts
- [Meter] 用于统计 写入 操作次数 -
removals
- [Meter] 用于统计 擦除 操作次数
每个分布式映射缓存(RMapCache)对象的指标
名称前缀:redisson.map-cache.<name>
-
hits
- [Meter] 用于统计 Redis命中(Redis内 有 需要的数据)的次数 -
misses
- [Meter] 用于统计 Redis未命中(Redis内 没有 需要的数据)的次数 -
puts
- [Meter] 用于统计 写入 操作次数 -
removals
- [Meter] 用于统计 擦除 操作次数
每个集群分布式映射缓存(RClusteredMapCache)对象的指标
名称前缀:redisson.clustered-map-cache.<name>
-
hits
- [Meter] 用于统计 Redis命中(Redis内 有 需要的数据)的次数 -
misses
- [Meter] 用于统计 Redis命中(Redis内 没有 需要的数据)的次数 -
puts
- [Meter] 用于统计 写入 操作次数 -
removals
- [Meter] 用于统计 擦除 操作次数
每个分布式本地缓存映射(RLocalCachedMap)对象的指标
名称前缀:redisson.local-cached-map.<name>
-
hits
- [Meter] 用于统计 Redis命中(Redis内 有 需要的数据)的次数 -
misses
- [Meter] 用于统计 Redis未命中(Redis内 没有 需要的数据)的次数 -
puts
- [Meter] 用于统计 写入 操作次数 -
removals
- [Meter] 用于统计 擦除 操作次数 -
local-cache.hits
- [Meter] 用于统计 本地命中(JVM内 有 需要的数据)的次数 -
local-cache.misses
- [Meter] 用于统计 本地未命中(Redis内 没有 需要的数据)的次数 -
local-cache.evictions
- [Meter] 用于统计 驱逐 发生次数 -
local-cache.size
- [Gauge] 用于统计 本地缓存 的容量大小
每个集群分布式本地缓存映射(RClusteredLocalCachedMap)对象的指标
名称前缀:redisson.clustered-local-cached-map.<name>
-
hits
- [Meter] 用于统计 Redis命中(Redis内 有 需要的数据)的次数 -
misses
- [Meter] 用于统计 Redis未命中(Redis内 没有 需要的数据)的次数 -
puts
- [Meter] 用于统计 写入 操作次数 -
removals
- [Meter] 用于统计 擦除 操作次数 -
local-cache.hits
- [Meter] 用于统计 本地命中(JVM内 有 需要的数据)的次数 -
local-cache.misses
- [Meter] 用于统计 本地未命中(Redis内 没有 需要的数据)的次数 -
local-cache.evictions
- [Meter] 用于统计 驱逐 发生次数 -
local-cache.size
- [Gauge] 用于统计 本地缓存 的容量大小
每个分布式本地缓存映射缓存(RLocalCachedMapCache)对象的指标
名称前缀:redisson.local-cached-map-cache.<name>
-
hits
- [Meter] 用于统计 Redis命中(Redis内 有 需要的数据)的次数 -
misses
- [Meter] 用于统计 Redis未命中(Redis内 没有 需要的数据)的次数 -
puts
- [Meter] 用于统计 写入 操作次数 -
removals
- [Meter] 用于统计 擦除 操作次数 -
local-cache.hits
- [Meter] 用于统计 本地命中(JVM内 有 需要的数据)的次数 -
local-cache.misses
- [Meter] 用于统计 本地未命中(Redis内 没有 需要的数据)的次数 -
local-cache.evictions
- [Meter] 用于统计 驱逐 发生次数 -
local-cache.size
- [Gauge] 用于统计 本地缓存 的容量大小
每个集群分布式本地缓存映射缓存(RClusteredLocalCachedMapCache)对象的指标
名称前缀:redisson.clustered-local-cached-map-cache.<name>
-
hits
- [Meter] 用于统计 Redis命中(Redis内 有 需要的数据)的次数 -
misses
- [Meter] 用于统计 Redis未命中(Redis内 没有 需要的数据)的次数 -
puts
- [Meter] 用于统计 写入 操作次数 -
removals
- [Meter] 用于统计 擦除 操作次数 -
local-cache.hits
- [Meter] 用于统计 本地命中(JVM内 有 需要的数据)的次数 -
local-cache.misses
- [Meter] 用于统计 本地未命中(Redis内 没有 需要的数据)的次数 -
local-cache.evictions
- [Meter] 用于统计 驱逐 发生次数 -
local-cache.size
- [Gauge] 用于统计 本地缓存 的容量大小
每个分布式话题(RTopic)对象的指标
名称前缀:redisson.topic.<name>
-
messages-sent
- [Meter] 用于统计向该话题 发送 出的消息数量 -
messages-received
- [Meter] 用于统计从该话题 接收 到的消息数量
每个分布式通用对象桶(RBucket)对象的指标
名称前缀:redisson.bucket.<name>
-
gets
- [Meter] 用于该统计分布式通用对象桶 读取 操作的次数 -
sets
- [Meter] 用于该统计分布式通用对象桶 写入 操作的次数
This feature available only in Redisson PRO edition.