SpringBoot集成redisson利用redis

开发者 2024-9-22 08:18:38 109 0 来自 中国
一、设置

1.1 引入maven

<dependency>    <groupId>org.redisson</groupId>    <artifactId>redisson</artifactId>    <version>3.17.0</version></dependency>1.2 设置文件

spring.redis.database=0spring.redis.password=spring.redis.timeout=3000#sentinel/cluster/singlespring.redis.mode=single#毗连池设置spring.redis.pool.max-idle=16spring.redis.pool.min-idle=8spring.redis.pool.max-active=8spring.redis.pool.max-wait=3000spring.redis.pool.conn-timeout=3000spring.redis.pool.so-timeout=3000spring.redis.pool.size=10#单机设置spring.redis.single.address=192.168.60.23:6379#集群设置spring.redis.cluster.scan-interval=1000spring.redis.cluster.nodes=spring.redis.cluster.read-mode=SLAVEspring.redis.cluster.retry-attempts=3spring.redis.cluster.failed-attempts=3spring.redis.cluster.slave-connection-pool-size=64spring.redis.cluster.master-connection-pool-size=64spring.redis.cluster.retry-interval=1500#哨兵设置spring.redis.sentinel.master=business-masterspring.redis.sentinel.nodes=spring.redis.sentinel.master-onlyWrite=truespring.redis.sentinel.fail-max=31.3 设置文件读取

/** * @author: huangyibo * @Date: 2022/6/23 10:56 * @Description: 设置文件读取 */@ConfigurationProperties(prefix="spring.redis", ignoreUnknownFields = false)@Data@ToStringpublic class RedisProperties {    private int database;    /**     * 等候节点复兴下令的时间。该时间从下令发送乐成时开始计时     */    private int timeout;    private String password;    private String mode;    /**     * 池设置     */    private RedisPoolProperties pool;    /**     * 单机信息设置     */    private RedisSingleProperties single;    /**     * 集群 信息设置     */    private RedisClusterProperties cluster;    /**     * 哨兵设置     *     */    private RedisSentinelProperties sentinel;}/** * @author: huangyibo * @Date: 2022/6/23 11:00 * @Description: redis 池设置 */@Data@ToStringpublic class RedisPoolProperties {    private int maxIdle;    private int minIdle;    private int maxActive;    private int maxWait;    private int connTimeout;    private int soTimeout;    /**     * 池巨细     */    private int size;}/** * @author: huangyibo * @Date: 2022/6/23 11:02 * @Description: 单节点设置 */@Data@ToStringpublic class RedisSingleProperties {    private String address;}/** * @author: huangyibo * @Date: 2022/6/23 11:03 * @Description: 集群设置 */@Data@ToStringpublic class RedisClusterProperties {    /**     * 集群状态扫描隔断时间,单元是毫秒     */    private int scanInterval;    /**     * 集群节点     */    private String nodes;    /**     * 默认值: SLAVE(只在从服务节点里读取)设置读取利用选择节点的模式。 可用值为: SLAVE - 只在从服务节点里读取。     * MASTER - 只在主服务节点里读取。 MASTER_SLAVE - 在主从服务节点里都可以读取     */    private String readMode;    /**     * (从节点毗连池巨细) 默认值:64     */    private int slaveConnectionPoolSize;    /**     * 主节点毗连池巨细)默认值:64     */    private int masterConnectionPoolSize;    /**     * (下令失败重试次数) 默认值:3     */    private int retryAttempts;    /**     *下令重试发送时间隔断,单元:毫秒 默认值:1500     */    private int retryInterval;    /**     * 实行失败最大次数默认值:3     */    private int failedAttempts;}/** * @author: huangyibo * @Date: 2022/6/23 11:06 * @Description: 哨兵设置 */@Data@ToStringpublic class RedisSentinelProperties {    /**     * 哨兵master 名称     */    private String master;    /**     * 哨兵节点     */    private String nodes;    /**     * 哨兵设置     */    private boolean masterOnlyWrite;    /**     *     */    private int failMax;}1.4 CacheConfiguration

import org.redisson.Redisson;import org.redisson.api.RedissonClient;import org.redisson.config.*;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;import org.springframework.boot.context.properties.EnableConfigurationProperties;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.util.StringUtils;import java.util.ArrayList;import java.util.Arrays;import java.util.List;/** * @author: huangyibo * @Date: 2022/6/23 11:08 * @Description: */@Configuration@EnableConfigurationProperties(RedisProperties.class)public class CacheConfiguration {    @Autowired    private RedisProperties redisProperties;    @Configuration    @ConditionalOnClass({Redisson.class})    @ConditionalOnExpression("'${spring.redis.mode}'=='single' or '${spring.redis.mode}'=='cluster' or '${spring.redis.mode}'=='sentinel'")    protected class RedissonSingleClientConfiguration {        /**         * 单机模式 redisson 客户端         */        @Bean        @ConditionalOnProperty(name="spring.redis.mode", havingValue="single")        public RedissonClient redissonSingle() {            Config config = new Config();            String node = redisProperties.getSingle().getAddress();            node = node.startsWith("redis://") ? node : "redis://" + node;            SingleServerConfig serverConfig = config.useSingleServer()                    .setAddress(node)                    .setTimeout(redisProperties.getPool().getConnTimeout())                    .setConnectionPoolSize(redisProperties.getPool().getSize())                    .setConnectionMinimumIdleSize(redisProperties.getPool().getMinIdle());            if(!StringUtils.isEmpty(redisProperties.getPassword())) {                serverConfig.setPassword(redisProperties.getPassword());            }            return Redisson.create(config);        }        /**         * 集群模式的 redisson 客户端         *         * @return         */        @Bean        @ConditionalOnProperty(name = "spring.redis.mode", havingValue = "cluster")        public RedissonClient redissonCluster() {            System.out.println("cluster redisProperties:" + redisProperties.getCluster());            Config config = new Config();            String[] nodes = redisProperties.getCluster().getNodes().split(",");            List<String> newNodes = new ArrayList<>(nodes.length);            Arrays.stream(nodes).forEach((index) -> newNodes.add(                index.startsWith("redis://") ? index : "redis://" + index)            );            ClusterServersConfig serverConfig = config.useClusterServers()                    .addNodeAddress(newNodes.toArray(new String[0])                    ).setScanInterval(                        redisProperties.getCluster().getScanInterval()                    ).setIdleConnectionTimeout(                        redisProperties.getPool().getSoTimeout()                    ).setConnectTimeout(                        redisProperties.getPool().getConnTimeout()                    ).setRetryAttempts(                        redisProperties.getCluster().getRetryAttempts()                    ).setRetryInterval(                        redisProperties.getCluster().getRetryInterval()                    ).setMasterConnectionPoolSize(                            redisProperties.getCluster().getMasterConnectionPoolSize()                    ).setSlaveConnectionPoolSize(                            redisProperties.getCluster().getSlaveConnectionPoolSize()                    ).setTimeout(                            redisProperties.getTimeout()                    );            if (!StringUtils.isEmpty(redisProperties.getPassword())) {                serverConfig.setPassword(redisProperties.getPassword());            }            return Redisson.create(config);        }        /**           * 哨兵模式 redisson 客户端         * @return         */        @Bean        @ConditionalOnProperty(name = "spring.redis.mode", havingValue = "sentinel")        public RedissonClient redissonSentinel() {            System.out.println("sentinel redisProperties:" + redisProperties.getSentinel());            Config config = new Config();            String[] nodes = redisProperties.getSentinel().getNodes().split(",");            List<String> newNodes = new ArrayList<>(nodes.length);            Arrays.stream(nodes).forEach((index) -> newNodes.add(                index.startsWith("redis://") ? index : "redis://" + index)            );            SentinelServersConfig serverConfig = config.useSentinelServers()                    .addSentinelAddress(newNodes.toArray(new String[0]))                    .setMasterName(redisProperties.getSentinel().getMaster())                    .setReadMode(ReadMode.SLAVE)                    .setTimeout(redisProperties.getTimeout())                    .setMasterConnectionPoolSize(redisProperties.getPool().getSize())                    .setSlaveConnectionPoolSize(redisProperties.getPool().getSize());            if (!StringUtils.isEmpty(redisProperties.getPassword())) {                serverConfig.setPassword(redisProperties.getPassword());            }            return Redisson.create(config);        }    }}二、Redisson工具类

import org.redisson.api.*;import org.redisson.client.codec.StringCodec;import org.springframework.stereotype.Component;import javax.annotation.Resource;import java.util.concurrent.TimeUnit;/** * @author: huangyibo * @Date: 2022/6/23 15:01 * @Description: */@Componentpublic class RedisUtils {    /**     * 默认缓存时间     */    private static final Long DEFAULT_EXPIRED = 32000L;        /**     * 主动装配redisson client对象     */    @Resource    private RedissonClient redissonClient;        /**     * 用于利用key     * @return RKeys 对象     */    public RKeys getKeys() {        return redissonClient.getKeys();    }            /**     * 移除缓存     *     * @param key     */    public void delete(String key) {        redissonClient.getBucket(key).delete();    }        /**     * 获取getBuckets 对象     *     * @return RBuckets 对象     */    public RBuckets getBuckets() {        return redissonClient.getBuckets();    }        /**     * 读取缓存中的字符串,永世有用     *     * @param key 缓存key     * @return 字符串     */    public String getStr(String key) {        RBucket<String> bucket = redissonClient.getBucket(key);        return bucket.get();    }        /**     * 缓存字符串     *     * @param key     * @param value     */    public void setStr(String key, String value) {        RBucket<String> bucket = redissonClient.getBucket(key);        bucket.set(value);    }        /**     * 缓存带过期时间的字符串     *     * @param key     缓存key     * @param value   缓存值     * @param expired 缓存过期时间,long范例,必须传值     */    public void setStr(String key, String value, long expired) {        RBucket<String> bucket = redissonClient.getBucket(key, StringCodec.INSTANCE);        bucket.set(value, expired <= 0L ? DEFAULT_EXPIRED : expired, TimeUnit.SECONDS);    }        /**     * string 利用,假如不存在则写入缓存(string方式,不带有redisson的格式信息)     *     * @param key     缓存key     * @param value   缓存值     * @param expired 缓存过期时间     */    public Boolean setIfAbsent(String key, String value, long expired) {        RBucket<String> bucket = redissonClient.getBucket(key, StringCodec.INSTANCE);        return bucket.trySet(value, expired <= 0L ? DEFAULT_EXPIRED : expired, TimeUnit.SECONDS);    }        /**     * 假如不存在则写入缓存(string方式,不带有redisson的格式信息),永世生存     *     * @param key   缓存key     * @param value 缓存值     */    public Boolean setIfAbsent(String key, String value) {        RBucket<String> bucket = redissonClient.getBucket(key, StringCodec.INSTANCE);        return bucket.trySet(value);    }        /**     * 判定缓存是否存在     *     * @param key     * @return true 存在     */    public Boolean isExists(String key) {        return redissonClient.getBucket(key).isExists();    }        /**     * 获取RList对象     *     * @param key RList的key     * @return RList对象     */    public <T> RList<T> getList(String key) {        return redissonClient.getList(key);    }        /**     * 获取RMapCache对象     *     * @param key     * @return RMapCache对象     */    public <K, V> RMapCache<K, V> getMap(String key) {        return redissonClient.getMapCache(key);    }        /**     * 获取RSET对象     *     * @param key     * @return RSET对象     */    public <T> RSet<T> getSet(String key) {        return redissonClient.getSet(key);    }        /**     * 获取RScoredSortedSet对象     *     * @param key     * @param <T>     * @return RScoredSortedSet对象     */    public <T> RScoredSortedSet<T> getScoredSortedSet(String key) {        return redissonClient.getScoredSortedSet(key);    }}三、常用RKeys的API利用

每个Redisson对象实例都会有一个与之对应的Redis数据实例,可以通过调用getName方法来取得redis数据实例的名称(key),全部于Redis key相干的利用都归纳在RKeys这个接口里。
RKeys keys = client.getKeys();//获取全部key值Iterable<String> allKeys = keys.getKeys();//含糊查询全部包罗关键字key的值Iterable<String> foundedKeys = keys.getKeysByPattern("key");//删除多个key值long numOfDeletedKeys = keys.delete("obj1", "obj2", "obj3");//含糊删除key值long deletedKeysAmount = keys.deleteByPattern("test?");//随机获取keyString randomKey = keys.randomKey();//查询当前有多少个keylong keysAmount = keys.count();详细demo
private void getKeys() {    RKeys keys = redisUtils.getRedisKeys();    Iterable<String> allKeys = keys.getKeys();    StringBuilder sb = new StringBuilder();    for (String key : allKeys) {        sb = sb.append(key).append(",");    }    log.info("全部的key:{}", sb.substring(0, sb.length() - 1));    // 含糊查询以 map 打头的全部 key    allKeys = keys.getKeysByPattern("map*");    sb = new StringBuilder();    for (String key : allKeys) {        sb = sb.append(key).append(",");    }    log.info("含糊匹配到的key:{}", sb.substring(0, sb.length() - 1));}此中,getKeysByPattern是基于redis的scan下令实现。
四、通用对象桶Object Bucket

Redisson的分布式RBucket Java对象是一种通用对象桶,可以用来存放恣意范例的对象。除了同步接口外,还提供异步(Async)、反射式(Reactive)和RxJava2尺度的接口。还可以通过RBuckets接口实现批量利用多个RBucket对象。
/** * String 数据范例 */private void strDemo() {    redisUtils.setStr(DEMO_STR, "Hello, String.");    log.info("String 测试数据:{}", redisUtils.getStr(DEMO_STR));    redisUtils.setStr("myBucket", "myBucketIsXxx");    RBuckets buckets = redisUtils.getBuckets();    Map<String, String> foundBuckets = buckets.get("myBucket*");    Map<String, Object> map = new HashMap<>();    map.put("myBucket1", "value1");    map.put("myBucket2", 30L);    // 同时生存全部通用对象桶。    buckets.set(map);    Map<String, String> loadedBuckets = buckets.get("myBucket1", "myBucket2", "myBucket3");    log.info("跨桶String 测试数据:{}", loadedBuckets);    map.put("myBucket3", 320L);}五、散列 Hash

基于Redisson的分布式映射布局的RMap Java对象实现了java.util.concurrent.ConcurrentMap和java.util.Map接口,与HashMap差别的是,RMap 保持了元素的插入次序。该对象的最大容量受Redis限制,最大元素数量是4294967295个。
/** * Hash范例 */private void hashDemo() {    RMap<Object, Object> map = redisUtils.getMap("mapDemo");    map.put("demoId1", "123");    map.put("demoId100", "13000");    Object demoId1Obj = map.get("demoId1");    log.info("Hash 测试数据:{}", demoId1Obj);}六、聚集 Set

基于Redisson的分布式Set布局的RSet Java对象实现了java.util.Set接口,通过元素的相互状态比力包管了每个元素的唯一性,该对象的最大容量受Redis限制,最大元素数量是4294967295个。
/** * Set 测试 */private void setDemo() {    RSet<String> set = redisUtils.getSet("setKey");    set.add("value777");    log.info("Set 测试数据");    Iterator<String> iterator = set.iterator();    while (iterator.hasNext()) {        String next = iterator.next();        log.info(next);    }}七、列表 List

基于Redisson的分布式列表 List 布局的RList Java对象在实现了java.util.List接口的同时,确保了元素插入时的次序,该对象的最大容量受Redis限制,最大元素数量是4294967295个。
/** * List数据范例 */private void listDemo() {    RList<String> list = redisUtils.getList("listDemo");    list.add("listValue1");    list.add("listValue2");    log.info("List 测试数据:{}", list.get(1));}综合示例

将上述demo放入一个API中,快速测试:
import lombok.extern.slf4j.Slf4j;import org.redisson.api.*;import org.springframework.web.bind.annotation.ModelAttribute;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;import java.util.HashMap;import java.util.Iterator;import java.util.Map;@Slf4j@RestController@RequestMapping(value = "/redisson", method = RequestMethod.POST)public class StudyRedissonController {    @Resource    private RedisUtils redisUtils;    private static String DEMO_STR = "demoStr";    @PostMapping("/learnRedisson")    public void learnRedisson() {        //三种数据布局使用示例        strDemo();        hashDemo();        listDemo();        setDemo();        getKeys();    }    private void getKeys() {        RKeys keys = redisUtils.getKeys();        Iterable<String> allKeys = keys.getKeys();        StringBuilder sb = new StringBuilder();        for (String key : allKeys) {            sb = sb.append(key).append(",");        }        log.info("全部的key:{}", sb.substring(0, sb.length() - 1));        // 含糊查询以 map 打头的全部 key        allKeys = keys.getKeysByPattern("map*");        sb = new StringBuilder();        for (String key : allKeys) {            sb = sb.append(key).append(",");        }        log.info("含糊匹配到的key:{}", sb.substring(0, sb.length() - 1));    }    /**     * Hash范例     */    private void hashDemo() {        RMap<Object, Object> map = redisUtils.getMap("mapDemo");        map.put("demoId1", "123");        map.put("demoId100", "13000");        Object demoId1Obj = map.get("demoId1");        log.info("Hash 测试数据:{}", demoId1Obj);    }    /**     * String 数据范例     */    private void strDemo() {        redisUtils.setStr(DEMO_STR, "Hello, String.");        log.info("String 测试数据:{}", redisUtils.getStr(DEMO_STR));        redisUtils.setStr("myBucket", "myBucketIsXxx");        RBuckets buckets = redisUtils.getBuckets();        Map<String, String> foundBuckets = buckets.get("myBucket*");        Map<String, Object> map = new HashMap<>();        map.put("myBucket1", "value1");        map.put("myBucket2", 30L);        // 同时生存全部通用对象桶。        buckets.set(map);        Map<String, String> loadedBuckets = buckets.get("myBucket1", "myBucket2", "myBucket3");        log.info("跨桶String 测试数据:{}", loadedBuckets);        map.put("myBucket3", 320L);    }    /**     * List数据范例     */    private void listDemo() {        RList<String> list = redisUtils.getList("listDemo");        list.add("listValue1");        list.add("listValue2");        log.info("List 测试数据:{}", list.get(1));    }    /**     * Set 测试     */    private void setDemo() {        RSet<String> set = redisUtils.getSet("setKey");        set.add("value777");        log.info("Set 测试数据");        Iterator<String> iterator = set.iterator();        while (iterator.hasNext()) {            String next = iterator.next();            log.info(next);        }    }}参考:
https://blog.51cto.com/u_14028890/2308518
https://www.cnblogs.com/east7/p/16255253.html
https://www.cnblogs.com/east7/p/16255305.html
您需要登录后才可以回帖 登录 | 立即注册

Powered by CangBaoKu v1.0 小黑屋藏宝库It社区( 冀ICP备14008649号 )

GMT+8, 2024-11-24 11:05, Processed in 0.186195 second(s), 32 queries.© 2003-2025 cbk Team.

快速回复 返回顶部 返回列表