精华内容
下载资源
问答
  • Redisson使用

    2020-08-17 10:26:14
    Redisson 使用 概述 Redisson是一个在Redis的基础上实现的Java驻内存数据网格(In-Memory Data Grid)。它不仅提供了一系列的分布式的Java常用对象,还提供了许多分布式服务。其中包括(BitSet, Set, Multimap, ...

    Redisson 使用

    概述

    Redisson是一个在Redis的基础上实现的Java驻内存数据网格(In-Memory Data Grid)。它不仅提供了一系列的分布式的Java常用对象,还提供了许多分布式服务。其中包括(BitSet, Set, Multimap, SortedSet, Map, List, Queue, BlockingQueue, Deque, BlockingDeque, Semaphore, Lock, AtomicLong, CountDownLatch, Publish / Subscribe, Bloom filter, Remote service, Spring cache, Executor service, Live Object service, Scheduler service) Redisson提供了使用Redis的最简单和最便捷的方法。Redisson的宗旨是促进使用者对Redis的关注分离(Separation of Concern),从而让使用者能够将精力更集中地放在处理业务逻辑上。

    配置方法(单节点)(Spring boot)

    引入依赖

    <dependency>
        <groupId>org.redisson</groupId>
        <artifactId>redisson-spring-boot-starter</artifactId>
        <version>3.13.1</version>
    </dependency>
    

    配置文件(application.properties)

    spring.redis.database=0
    spring.redis.host=localhost
    spring.redis.port=6379
    spring.redis.redisson.config=classpath:redisson.yaml
    

    编写 redisson.yaml

    对应配置java类(singleServerConfig.class)

    各个配置项说明参考

    https://github.com/redisson/redisson/wiki/2.-%E9%85%8D%E7%BD%AE%E6%96%B9%E6%B3%95#26-%E5%8D%95redis%E8%8A%82%E7%82%B9%E6%A8%A1%E5%BC%8F

    ---
    singleServerConfig:
      idleConnectionTimeout: 10000  
    #  pingTimeout: 1000
      connectTimeout: 10000
      timeout: 3000
      retryAttempts: 3
      retryInterval: 1500
    #  reconnectionTimeout: 3000
    #  failedAttempts: 3
      password: null
      subscriptionsPerConnection: 5
      clientName: null
      address: "redis://127.0.0.1:6379"
      subscriptionConnectionMinimumIdleSize: 1
      subscriptionConnectionPoolSize: 50
      connectionMinimumIdleSize: 32
      connectionPoolSize: 64
      database: 0
    #  dnsMonitoring: false
    #  dnsMonitoringInterval: 5000
    threads: 0
    nettyThreads: 0
    codec: !<org.redisson.codec.JsonJacksonCodec> {}
    transportMode: NIO
    

    其它配置方法

    https://github.com/redisson/redisson/wiki/2.-%E9%85%8D%E7%BD%AE%E6%96%B9%E6%B3%95

    使用

    @Autowired
    StringRedisTemplate redisTemplate;
    @Autowired
    RedisTemplate redisTemplate;
    @Autowired
    RedissonClient redissonClient;
    

    数据序列化

    默认序列化方式

    org.redisson.codec.JsonJacksonCodec

    自定义序列化

    继承 BaseCodec抽象类 然后配置codec 参数即可 可自定义编码器和解码器

    package com.wxy.redissondemo.config;
    
    import com.fasterxml.jackson.annotation.*;
    import com.fasterxml.jackson.core.JsonGenerator;
    import com.fasterxml.jackson.databind.*;
    import com.fasterxml.jackson.databind.jsontype.TypeResolverBuilder;
    import com.fasterxml.jackson.databind.type.TypeFactory;
    import com.wxy.redissondemo.utils.ObjectUtlis;
    import io.netty.buffer.ByteBuf;
    import io.netty.buffer.ByteBufAllocator;
    import io.netty.buffer.ByteBufInputStream;
    import io.netty.buffer.ByteBufOutputStream;
    import org.redisson.client.codec.BaseCodec;
    import org.redisson.client.handler.State;
    import org.redisson.client.protocol.Decoder;
    import org.redisson.client.protocol.Encoder;
    import org.redisson.codec.JsonJacksonCodec;
    
    import javax.crypto.Cipher;
    import javax.crypto.SecretKey;
    import javax.crypto.spec.SecretKeySpec;
    import javax.xml.datatype.XMLGregorianCalendar;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.security.GeneralSecurityException;
    import java.util.Base64;
    
    /**
     * @Description:
     */
    public class EncryptJsonJacksonCodec extends BaseCodec {
        public static final EncryptJsonJacksonCodec INSTANCE = new EncryptJsonJacksonCodec();
    
        private static final String  KEY  = "1234567890abcdef";
    
        @JsonIdentityInfo(generator= ObjectIdGenerators.IntSequenceGenerator.class, property="@id")
        @JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY,
                getterVisibility = JsonAutoDetect.Visibility.PUBLIC_ONLY,
                setterVisibility = JsonAutoDetect.Visibility.NONE,
                isGetterVisibility = JsonAutoDetect.Visibility.NONE)
        public static class ThrowableMixIn {
    
        }
    
        protected final ObjectMapper mapObjectMapper;
    
        private final Encoder encoder = new Encoder() {
            @Override
            public ByteBuf encode(Object in) throws IOException {
                ByteBuf out = ByteBufAllocator.DEFAULT.buffer();
                try {
                    ByteBufOutputStream os = new ByteBufOutputStream(out);
                    byte[] bytes = ObjectUtlis.toByteArray(in);
                    bytes = encrypt(KEY.getBytes(),bytes);
    
                    mapObjectMapper.writeValue((OutputStream) os, Base64.getEncoder().encodeToString(bytes));
                    return os.buffer();
                } catch (IOException e) {
                    out.release();
                    throw e;
                } catch (Exception e) {
                    out.release();
                    throw new IOException(e);
                }
            }
        };
    
        private final Decoder<Object> decoder = new Decoder<Object>() {
            @Override
            public Object decode(ByteBuf buf, State state) throws IOException {
               Object object = mapObjectMapper.readValue((InputStream) new ByteBufInputStream(buf), Object.class);
                try {
    
                    byte[]byi =  decrypt(KEY.getBytes(),Base64.getDecoder().decode(object.toString().getBytes()));
    
                     return ObjectUtlis.toObject(byi);
                } catch (GeneralSecurityException e) {
                    e.printStackTrace();
                }
                return  object;
            }
        };
    
        public EncryptJsonJacksonCodec() {
            this(new ObjectMapper());
        }
    
        public EncryptJsonJacksonCodec(ClassLoader classLoader) {
            this(createObjectMapper(classLoader, new ObjectMapper()));
        }
    
        public EncryptJsonJacksonCodec(ClassLoader classLoader, EncryptJsonJacksonCodec codec) {
            this(createObjectMapper(classLoader, codec.mapObjectMapper.copy()));
        }
    
        protected static ObjectMapper createObjectMapper(ClassLoader classLoader, ObjectMapper om) {
            TypeFactory tf = TypeFactory.defaultInstance().withClassLoader(classLoader);
            om.setTypeFactory(tf);
            return om;
        }
    
        public EncryptJsonJacksonCodec(ObjectMapper mapObjectMapper) {
            this.mapObjectMapper = mapObjectMapper.copy();
            init(this.mapObjectMapper);
            initTypeInclusion(this.mapObjectMapper);
        }
    
        // 加密:
        public static byte[] encrypt(byte[] key, byte[] input) throws GeneralSecurityException {
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            SecretKey keySpec = new SecretKeySpec(key, "AES");
            cipher.init(Cipher.ENCRYPT_MODE, keySpec);
            return cipher.doFinal(input);
        }
    
        // 解密:
        public static byte[] decrypt(byte[] key, byte[] input) throws GeneralSecurityException {
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            SecretKey keySpec = new SecretKeySpec(key, "AES");
            cipher.init(Cipher.DECRYPT_MODE, keySpec);
            return cipher.doFinal(input);
        }
    
        protected void initTypeInclusion(ObjectMapper mapObjectMapper) {
            TypeResolverBuilder<?> mapTyper = new ObjectMapper.DefaultTypeResolverBuilder(ObjectMapper.DefaultTyping.NON_FINAL) {
                public boolean useForType(JavaType t) {
                    switch (_appliesFor) {
                        case NON_CONCRETE_AND_ARRAYS:
                            while (t.isArrayType()) {
                                t = t.getContentType();
                            }
                            // fall through
                        case OBJECT_AND_NON_CONCRETE:
                            return (t.getRawClass() == Object.class) || !t.isConcrete();
                        case NON_FINAL:
                            while (t.isArrayType()) {
                                t = t.getContentType();
                            }
                            // to fix problem with wrong long to int conversion
                            if (t.getRawClass() == Long.class) {
                                return true;
                            }
                            if (t.getRawClass() == XMLGregorianCalendar.class) {
                                return false;
                            }
                            return !t.isFinal(); // includes Object.class
                        default:
                            // case JAVA_LANG_OBJECT:
                            return t.getRawClass() == Object.class;
                    }
                }
            };
            mapTyper.init(JsonTypeInfo.Id.CLASS, null);
            mapTyper.inclusion(JsonTypeInfo.As.PROPERTY);
            mapObjectMapper.setDefaultTyping(mapTyper);
        }
    
        protected void init(ObjectMapper objectMapper) {
            objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
            objectMapper.setVisibility(objectMapper.getSerializationConfig()
                    .getDefaultVisibilityChecker()
                    .withFieldVisibility(JsonAutoDetect.Visibility.ANY)
                    .withGetterVisibility(JsonAutoDetect.Visibility.NONE)
                    .withSetterVisibility(JsonAutoDetect.Visibility.NONE)
                    .withCreatorVisibility(JsonAutoDetect.Visibility.NONE));
            objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
            objectMapper.enable(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN);
            objectMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
            objectMapper.enable(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY);
            objectMapper.addMixIn(Throwable.class, JsonJacksonCodec.ThrowableMixIn.class);
        }
    
        @Override
        public Decoder<Object> getValueDecoder() {
            return decoder;
        }
    
        @Override
        public Encoder getValueEncoder() {
            return encoder;
        }
    
        @Override
        public ClassLoader getClassLoader() {
            if (mapObjectMapper.getTypeFactory().getClassLoader() != null) {
                return mapObjectMapper.getTypeFactory().getClassLoader();
            }
    
            return super.getClassLoader();
        }
    
        public ObjectMapper getObjectMapper() {
            return mapObjectMapper;
        }
    
    }
    

    分布式对象

    具体使用方式请参考相关api

    https://github.com/redisson/redisson/wiki/6.-%E5%88%86%E5%B8%83%E5%BC%8F%E5%AF%B9%E8%B1%A1

    通用对象桶 RBucket

    二进制流 RBinaryStream

    地理空间对象桶RGeo

    对redis版本有要求需要redis 版本大于3.0

    BitSet

    原子整长形 RAtomiclong

    原子双精度浮点RAtomicDouble

    布隆过滤器 Bloom Filter

    基数估计算法 RHyperLogLog

    整长型累加器RLongAdder

    双精度浮点累加器RLongDouble

    限流器RRateLimiter

    分布式集合

    基于Redis的Redisson的分布式映射结构的RMap Java对象实现了java.util.concurrent.ConcurrentMap接口和java.util.Map接口。与HashMap不同的是,RMap保持了元素的插入顺序。该对象的最大容量受Redis限制,最大元素数量是4 294 967 295个。

    在特定的场景下,映射缓存(Map)上的高度频繁的读取操作,使网络通信都被视为瓶颈时,可以使用Redisson提供的带有本地缓存功能的映射。

    RMap

    使用样例

    RMap<String, SomeObject> map = redisson.getMap("anyMap");
    SomeObject prevObject = map.put("123", new SomeObject());
    SomeObject currentObject = map.putIfAbsent("323", new SomeObject());
    SomeObject obj = map.remove("123");
    
    map.fastPut("321", new SomeObject());
    map.fastRemove("321");
    
    RFuture<SomeObject> putAsyncFuture = map.putAsync("321");
    RFuture<Void> fastPutAsyncFuture = map.fastPutAsync("321");
    
    map.fastPutAsync("321", new SomeObject());
    map.fastRemoveAsync("321");
    

    更多方法请参考redisson api

    RMapCache

    RMapCache<String, SomeObject> map = redisson.getMapCache("anyMap");
    // 有效时间 ttl = 10分钟
    map.put("key1", new SomeObject(), 10, TimeUnit.MINUTES);
    // 有效时间 ttl = 10分钟, 最长闲置时间 maxIdleTime = 10秒钟
    map.put("key1", new SomeObject(), 10, TimeUnit.MINUTES, 10, TimeUnit.SECONDS);
    
    // 有效时间 = 3 秒钟
    map.putIfAbsent("key2", new SomeObject(), 3, TimeUnit.SECONDS);
    // 有效时间 ttl = 40秒钟, 最长闲置时间 maxIdleTime = 10秒钟
    map.putIfAbsent("key2", new SomeObject(), 40, TimeUnit.SECONDS, 10, TimeUnit.SECONDS);
    

    RLocalCachedMap

    LocalCachedMapOptions options = LocalCachedMapOptions.defaults()
          // 用于淘汰清除本地缓存内的元素
          // 共有以下几种选择:
          // LFU - 统计元素的使用频率,淘汰用得最少(最不常用)的。
          // LRU - 按元素使用时间排序比较,淘汰最早(最久远)的。
          // SOFT - 元素用Java的WeakReference来保存,缓存元素通过GC过程清除。
          // WEAK - 元素用Java的SoftReference来保存, 缓存元素通过GC过程清除。
          // NONE - 永不淘汰清除缓存元素。
         .evictionPolicy(EvictionPolicy.NONE)
         // 如果缓存容量值为0表示不限制本地缓存容量大小
         .cacheSize(1000)
          // 以下选项适用于断线原因造成了未收到本地缓存更新消息的情况。
          // 断线重连的策略有以下几种:
          // CLEAR - 如果断线一段时间以后则在重新建立连接以后清空本地缓存
          // LOAD - 在服务端保存一份10分钟的作废日志
          //        如果10分钟内重新建立连接,则按照作废日志内的记录清空本地缓存的元素
          //        如果断线时间超过了这个时间,则将清空本地缓存中所有的内容
          // NONE - 默认值。断线重连时不做处理。
         .reconnectionStrategy(ReconnectionStrategy.NONE)
          // 以下选项适用于不同本地缓存之间相互保持同步的情况
          // 缓存同步策略有以下几种:
          // INVALIDATE - 默认值。当本地缓存映射的某条元素发生变动时,同时驱逐所有相同本地缓存映射内的该元素
          // UPDATE - 当本地缓存映射的某条元素发生变动时,同时更新所有相同本地缓存映射内的该元素
          // NONE - 不做任何同步处理
         .syncStrategy(SyncStrategy.INVALIDATE)
          // 每个Map本地缓存里元素的有效时间,默认毫秒为单位
         .timeToLive(10000)
          // 或者
         .timeToLive(10, TimeUnit.SECONDS)
          // 每个Map本地缓存里元素的最长闲置时间,默认毫秒为单位
         .maxIdle(10000)
          // 或者
         .maxIdle(10, TimeUnit.SECONDS);
    
    RLocalCachedMap<String, Integer> map = redisson.getLocalCachedMap("test", options);
    
    String prevObject = map.put("123", 1);
    String currentObject = map.putIfAbsent("323", 2);
    String obj = map.remove("123");
    
    // 在不需要旧值的情况下可以使用fast为前缀的类似方法
    map.fastPut("a", 1);
    map.fastPutIfAbsent("d", 32);
    map.fastRemove("b");
    
    RFuture<String> putAsyncFuture = map.putAsync("321");
    RFuture<Void> fastPutAsyncFuture = map.fastPutAsync("321");
    
    map.fastPutAsync("321", new SomeObject());
    map.fastRemoveAsync("321");
    

    比较和区别

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LDKuKwQp-1597631162624)(C:\Users\Waspal\AppData\Roaming\Typora\typora-user-images\image-20200701143339436.png)]

    数据淘汰策略

    • 元素淘汰(Eviction) 类 – 带有元素淘汰(Eviction)机制的映射类允许针对一个映射中每个元素单独设定 有效时间最长闲置时间
    • 本地缓存(LocalCache) 类 – 本地缓存(Local Cache)也叫就近缓存(Near Cache)。这类映射的使用主要用于在特定的场景下,映射缓存(MapCache)上的高度频繁的读取操作,使网络通信都被视为瓶颈的情况。Redisson与Redis通信的同时,还将部分数据保存在本地内存里。这样的设计的好处是它能将读取速度提高最多 45倍 。 所有同名的本地缓存共用一个订阅发布话题,所有更新和过期消息都将通过该话题共享。

    分布式锁

    以下这些分布式锁都是继承自 java.util.concurrent.locks接口,因此使用方式基本差不多。如有不懂请参考

    https://github.com/redisson/redisson/wiki/8.-%E5%88%86%E5%B8%83%E5%BC%8F%E9%94%81%E5%92%8C%E5%90%8C%E6%AD%A5%E5%99%A8

    可重入锁

    公平锁

    读写锁

    信号量

    可过期性信号量

    闭锁

    Redis命令和Redisson对象匹配表

    https://github.com/redisson/redisson/wiki/11.-Redis%E5%91%BD%E4%BB%A4%E5%92%8CRedisson%E5%AF%B9%E8%B1%A1%E5%8C%B9%E9%85%8D%E5%88%97%E8%A1%A8

    参考资料

    https://www.javadoc.io/doc/org.redisson/redisson/3.10.0/index.html (redisson api文档)

    https://github.com/redisson/redisson/wiki(使用样例文档)

    展开全文
  • redisson使用

    2021-03-03 15:01:59
    public static final String REDIS_LOCK_KEY = "lockhhf"; @Autowired private StringRedisTemplate stringRedisTemplate;...private Redisson redisson; @GetMapping("/buy_goods") public String buy_Goo
        
        public static final String REDIS_LOCK_KEY = "lockhhf";
    
        @Autowired
        private StringRedisTemplate stringRedisTemplate;
    
        @Value("${server.port}")
        private String serverPort;
    
        @Autowired
        private Redisson redisson;
    
        @GetMapping("/buy_goods")
        public String buy_Goods(){
    
            String value = UUID.randomUUID().toString()+Thread.currentThread().getName();
    
            RLock redissonLock = redisson.getLock(REDIS_LOCK_KEY);
            redissonLock.lock();
            try{
                String result = stringRedisTemplate.opsForValue().get("goods:001");
                int goodsNumber = result == null ? 0 : Integer.parseInt(result);
    
                if (goodsNumber > 0){
                    int realNumber = goodsNumber - 1;
                    stringRedisTemplate.opsForValue().set("goods:001",realNumber + "");
                    System.out.println("你已经成功秒杀商品,此时还剩余:" + realNumber + "件"+"\t 服务器端口: "+serverPort);
                    return "你已经成功秒杀商品,此时还剩余:" + realNumber + "件"+"\t 服务器端口: "+serverPort;
                }else {
                    System.out.println("商品已经售罄/活动结束/调用超时,欢迎下次光临"+"\t 服务器端口: "+serverPort);
                }
                return "商品已经售罄/活动结束/调用超时,欢迎下次光临"+"\t 服务器端口: "+serverPort;
    
            }finally {
                //还在持有锁的状态,并且是当前线程持有的锁再解锁
                if (redissonLock.isLocked() && redissonLock.isHeldByCurrentThread()){
                    redissonLock.unlock();
                }
    
            }
        }
    }
    
    
    
    
     
     
    
    展开全文
  • Redisson 使用

    2020-01-13 11:31:14
    import org.redisson.Redisson; import org.redisson.api.RedissonClient; import org.redisson.config.Config; import org.springframework.beans.factory.annotation.Value; import org.springframewor...

    1配置连接服务器

    import org.redisson.Redisson;
    import org.redisson.api.RedissonClient;
    import org.redisson.config.Config;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    public class RedissonConfig {
    	
    	@Value("${spring.redis.host}")
    	private String ip;
    	
    	@Value("${spring.redis.port}")
    	private String port;
    	
    	@Bean
    	public RedissonClient getRedisson() {
    		Config config = new Config();
    		// 单机模式 依次设置redis地址和密码
    		config.useSingleServer().setAddress("redis://"+ip+":"+port+"").setDatabase(5);
    		return Redisson.create(config);
    	}
    }

    2依赖注入

    	@Autowired
    	private RedissonClient redissonClient;

     

    展开全文
  • redisson 使用

    2020-03-24 15:53:16
    loadBalancer(负载均衡算法类的选择) 默认值: org.redisson.connection.balancer.RoundRobinLoadBalancer 在使用多个Redis服务节点的环境里,可以选用以下几种负载均衡方式选择一个节点: org.redisson....
    1.引用jar
    	<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>org.redisson</groupId>
            <artifactId>redisson</artifactId>
            <version>3.11.3</version>
        </dependency>
    2.redisson 配置
    /**
    
    • redisson配置

    • 公共配置

      • 多主节点的环境里,每个 主节点的连接池最大容量。连接池的连接数量自动弹性伸缩。
      • idleConnectionTimeout(连接空闲超时,单位:毫秒)
      • 默认值:10000
      • 如果当前连接池里的连接数量超过了最小空闲连接数,而同时有连接空闲时间超过了该数值,那么这些连接将会自动被关闭,并从连接池里去掉。时间单位是毫秒。
      • connectTimeout(连接超时,单位:毫秒)
      • 默认值:10000
      • 同任何节点建立连接时的等待超时。时间单位是毫秒。
      • timeout(命令等待超时,单位:毫秒)
      • 默认值:3000
      • 等待节点回复命令的时间。该时间从命令发送成功时开始计时。
      • retryAttempts(命令失败重试次数)
      • 默认值:3
      • 如果尝试达到 retryAttempts(命令失败重试次数) 仍然不能将命令发送至某个指定的节点时,将抛出错误。如果尝试在此限制之内发送成功,则开始启用 timeout(命令等待超时) 计时。
      • retryInterval(命令重试发送时间间隔,单位:毫秒)
      • 默认值:1500
      • 在一条命令发送失败以后,等待重试发送的时间间隔。时间单位是毫秒。
      • reconnectionTimeout(重新连接时间间隔,单位:毫秒)
      • 默认值:3000
      • 当与某个节点的连接断开时,等待与其重新建立连接的时间间隔。时间单位是毫秒。
      • failedAttempts(执行失败最大次数)
      • 默认值:3
      • 在某个节点执行相同或不同命令时,连续 失败 failedAttempts(执行失败最大次数) 时,该节点将被从可用节点列表里清除,直到 reconnectionTimeout(重新连接时间间隔) 超时以后再次尝试。
      • password(密码)
      • 默认值:null
      • 用于节点身份验证的密码。
      • subscriptionsPerConnection(单个连接最大订阅数量)
      • 默认值:5
      • 每个连接的最大订阅数量。
      • clientName(客户端名称)
      • 默认值:null
      • 在Redis节点里显示的客户端名称。
      • sslEnableEndpointIdentification(启用SSL终端识别)
      • 默认值:true
      • 开启SSL终端识别能力。
      • sslProvider(SSL实现方式)
      • 默认值:JDK
      • 确定采用哪种方式(JDK或OPENSSL)来实现SSL连接。
      • sslTruststore(SSL信任证书库路径)
      • 默认值:null
      • 指定SSL信任证书库的路径。
      • sslTruststorePassword(SSL信任证书库密码)
      • 默认值:null
      • 指定SSL信任证书库的密码。
      • sslKeystore(SSL钥匙库路径)
      • 默认值:null
      • 指定SSL钥匙库的路径。
      • sslKeystorePassword(SSL钥匙库密码)
      • 默认值:null
      • 指定SSL钥匙库的密码。
    • 集群设置

    • config.useClusterServers();
      //可以用"rediss://"来启用SSL连接
      .addNodeAddress(“redis://127.0.0.1:7000”, “redis://127.0.0.1:7001”)
      .addNodeAddress(“redis://127.0.0.1:7002”);

    • nodeAddresses(添加节点地址)

    • 可以通过host:port的格式来添加Redis集群节点的地址。多个节点可以一次性批量添加。

    • scanInterval(集群扫描间隔时间)

    • 默认值: 1000

    • 对Redis集群节点状态扫描的时间间隔。单位是毫秒。

    • slots(分片数量)

    • 默认值: 231 用于指定数据分片过程中的分片数量。支持数据分片/框架结构有:集(Set)、映射(Map)、BitSet、Bloom filter, Spring Cache和Hibernate Cache等.

    • readMode(读取操作的负载均衡模式)

    • 默认值: SLAVE(只在从服务节点里读取)

    • 注:在从服务节点里读取的数据说明已经至少有两个节点保存了该数据,确保了数据的高可用性。

    • 设置读取操作选择节点的模式。 可用值为: SLAVE - 只在从服务节点里读取。 MASTER - 只在主服务节点里读取。 MASTER_SLAVE - 在主从服务节点里都可以读取。

    • subscriptionMode(订阅操作的负载均衡模式)

    • 默认值:SLAVE(只在从服务节点里订阅)

    • 设置订阅操作选择节点的模式。 可用值为: SLAVE - 只在从服务节点里订阅。 MASTER - 只在主服务节点里订阅。

    • loadBalancer(负载均衡算法类的选择)

    • 默认值: org.redisson.connection.balancer.RoundRobinLoadBalancer

    • 在多Redis服务节点的环境里,可以选用以下几种负载均衡方式选择一个节点: org.redisson.connection.balancer.WeightedRoundRobinBalancer - 权重轮询调度算法 org.redisson.connection.balancer.RoundRobinLoadBalancer - 轮询调度算法 org.redisson.connection.balancer.RandomLoadBalancer - 随机调度算法

    • subscriptionConnectionMinimumIdleSize(从节点发布和订阅连接的最小空闲连接数)

    • 默认值:1

    • 多从节点的环境里,每个 从服务节点里用于发布和订阅连接的最小保持连接数(长连接)。Redisson内部经常通过发布和订阅来实现许多功能。长期保持一定数量的发布订阅连接是必须的。

    • subscriptionConnectionPoolSize(从节点发布和订阅连接池大小)

    • 默认值:50

    • 多从节点的环境里,每个 从服务节点里用于发布和订阅连接的连接池最大容量。连接池的连接数量自动弹性伸缩。

    • slaveConnectionMinimumIdleSize(从节点最小空闲连接数)

    • 默认值:32

    • 多从节点的环境里,每个 从服务节点里用于普通操作(非 发布和订阅)的最小保持连接数(长连接)。长期保持一定数量的连接有利于提高瞬时读取反映速度。

    • slaveConnectionPoolSize(从节点连接池大小)

    • 默认值:64

    • 多从节点的环境里,每个 从服务节点里用于普通操作(非 发布和订阅)连接的连接池最大容量。连接池的连接数量自动弹性伸缩。

    • masterConnectionMinimumIdleSize(主节点最小空闲连接数)

    • 默认值:32

    • 多节点的环境里,每个 主节点的最小保持连接数(长连接)。长期保持一定数量的连接有利于提高瞬时写入反应速度。

    • masterConnectionPoolSize(主节点连接池大小)

    • 默认值:64

    • 单Redis节点模式

    • 2.6.1. 单节点设置

    • Redis程序的配置和架设文档在这里。Redisson的单Redis节点模式的使用方法如下: SingleServerConfig singleConfig = config.useSingleServer();

    • SingleServerConfig 类的设置参数如下:

    • address(节点地址)

    • 可以通过host:port的格式来指定节点地址。

    • subscriptionConnectionMinimumIdleSize(发布和订阅连接的最小空闲连接数)

    • 默认值:1

    • 用于发布和订阅连接的最小保持连接数(长连接)。Redisson内部经常通过发布和订阅来实现许多功能。长期保持一定数量的发布订阅连接是必须的。

    • subscriptionConnectionPoolSize(发布和订阅连接池大小)

    • 默认值:50

    • 用于发布和订阅连接的连接池最大容量。连接池的连接数量自动弹性伸缩。

    • connectionMinimumIdleSize(最小空闲连接数)

    • 默认值:32

    • 最小保持连接数(长连接)。长期保持一定数量的连接有利于提高瞬时写入反应速度。

    • connectionPoolSize(连接池大小)

    • 默认值:64

    • 连接池最大容量。连接池的连接数量自动弹性伸缩。

    • dnsMonitoring(是否启用DNS监测)

    • 默认值:false

    • 在启用该功能以后,Redisson将会监测DNS的变化情况。

    • dnsMonitoringInterval(DNS监测时间间隔,单位:毫秒)

    • 默认值:5000

    • 监测DNS的变化情况的时间间隔。

    • 哨兵模式

    • config.useSentinelServers();

    • 可以用"rediss://"来启用SSL连接

    • .addSentinelAddress(“127.0.0.1:26389”, “127.0.0.1:26379”)

    • .addSentinelAddress(“127.0.0.1:26319”);

    • dnsMonitoringInterval(DNS监控间隔,单位:毫秒)

    • 默认值:5000

    • 用来指定检查节点DNS变化的时间间隔。使用的时候应该确保JVM里的DNS数据的缓存时间保持在足够低的范围才有意义。用-1来禁用该功能。

    • masterName(主服务器的名称)

    • 主服务器的名称是哨兵进程中用来监测主从服务切换情况的。

    • addSentinelAddress(添加哨兵节点地址)

    • 可以通过host:port的格式来指定哨兵节点的地址。多个节点可以一次性批量添加。

    • readMode(读取操作的负载均衡模式)

    • 默认值: SLAVE(只在从服务节点里读取)

    • 注:在从服务节点里读取的数据说明已经至少有两个节点保存了该数据,确保了数据的高可用性。

    • 设置读取操作选择节点的模式。 可用值为: SLAVE - 只在从服务节点里读取。 MASTER - 只在主服务节点里读取。 MASTER_SLAVE - 在主从服务节点里都可以读取。

    • subscriptionMode(订阅操作的负载均衡模式)

    • 默认值:SLAVE(只在从服务节点里订阅)

    • 设置订阅操作选择节点的模式。 可用值为: SLAVE - 只在从服务节点里订阅。 MASTER - 只在主服务节点里订阅。

    • loadBalancer(负载均衡算法类的选择)

    • 默认值: org.redisson.connection.balancer.RoundRobinLoadBalancer

    • 在使用多个Redis服务节点的环境里,可以选用以下几种负载均衡方式选择一个节点: org.redisson.connection.balancer.WeightedRoundRobinBalancer - 权重轮询调度算法 org.redisson.connection.balancer.RoundRobinLoadBalancer - 轮询调度算法 org.redisson.connection.balancer.RandomLoadBalancer - 随机调度算法

    • subscriptionConnectionMinimumIdleSize(从节点发布和订阅连接的最小空闲连接数)

    • 默认值:1

    • 多从节点的环境里,每个 从服务节点里用于发布和订阅连接的最小保持连接数(长连接)。Redisson内部经常通过发布和订阅来实现许多功能。长期保持一定数量的发布订阅连接是必须的。

    • subscriptionConnectionPoolSize(从节点发布和订阅连接池大小)

    • 默认值:50

    • 多从节点的环境里,每个 从服务节点里用于发布和订阅连接的连接池最大容量。连接池的连接数量自动弹性伸缩。

    • slaveConnectionMinimumIdleSize(从节点最小空闲连接数)

    • 默认值:32

    • 多从节点的环境里,每个 从服务节点里用于普通操作(非 发布和订阅)的最小保持连接数(长连接)。长期保持一定数量的连接有利于提高瞬时读取反映速度。

    • slaveConnectionPoolSize(从节点连接池大小)

    • 默认值:64

    • 多从节点的环境里,每个 从服务节点里用于普通操作(非 发布和订阅)连接的连接池最大容量。连接池的连接数量自动弹性伸缩。

    • masterConnectionMinimumIdleSize(主节点最小空闲连接数)

    • 默认值:32

    • 多从节点的环境里,每个 主节点的最小保持连接数(长连接)。长期保持一定数量的连接有利于提高瞬时写入反应速度。

    • masterConnectionPoolSize(主节点连接池大小)

    • 默认值:64

    • 主节点的连接池最大容量。连接池的连接数量自动弹性伸缩。

    • 主从模式

    • config.useMasterSlaveServers();
      *.setMasterAddress(“redis://127.0.0.1:6379”)

    • .addSlaveAddress(“redis://127.0.0.1:6389”, “redis://127.0.0.1:6332”, “redis://127.0.0.1:6419”)

    • .addSlaveAddress(“redis://127.0.0.1:6399”);

    • dnsMonitoringInterval(DNS监控间隔,单位:毫秒)

    • 默认值:5000

    • 用来指定检查节点DNS变化的时间间隔。使用的时候应该确保JVM里的DNS数据的缓存时间保持在足够低的范围才有意义。用-1来禁用该功能。

    • masterAddress(主节点地址)

    • 可以通过host:port的格式来指定主节点地址。

    • addSlaveAddress(添加从主节点地址)

    • 可以通过host:port的格式来指定从节点的地址。多个节点可以一次性批量添加。

    • readMode(读取操作的负载均衡模式)

    • 默认值: SLAVE(只在从服务节点里读取)

    • 注:在从服务节点里读取的数据说明已经至少有两个节点保存了该数据,确保了数据的高可用性。

    • 设置读取操作选择节点的模式。 可用值为: SLAVE - 只在从服务节点里读取。 MASTER - 只在主服务节点里读取。 MASTER_SLAVE - 在主从服务节点里都可以读取。

    • subscriptionMode(订阅操作的负载均衡模式)

    • 默认值:SLAVE(只在从服务节点里订阅)

    • 设置订阅操作选择节点的模式。 可用值为: SLAVE - 只在从服务节点里订阅。 MASTER - 只在主服务节点里订阅。

    • loadBalancer(负载均衡算法类的选择)

    • 默认值: org.redisson.connection.balancer.RoundRobinLoadBalancer

    • 在使用多个Redis服务节点的环境里,可以选用以下几种负载均衡方式选择一个节点: org.redisson.connection.balancer.WeightedRoundRobinBalancer - 权重轮询调度算法 org.redisson.connection.balancer.RoundRobinLoadBalancer - 轮询调度算法 org.redisson.connection.balancer.RandomLoadBalancer - 随机调度算法

    • subscriptionConnectionMinimumIdleSize(从节点发布和订阅连接的最小空闲连接数)

    • 默认值:1

    • 多从节点的环境里,每个 从服务节点里用于发布和订阅连接的最小保持连接数(长连接)。Redisson内部经常通过发布和订阅来实现许多功能。长期保持一定数量的发布订阅连接是必须的。

    • subscriptionConnectionPoolSize(从节点发布和订阅连接池大小)

    • 默认值:50

    • 多从节点的环境里,每个 从服务节点里用于发布和订阅连接的连接池最大容量。连接池的连接数量自动弹性伸缩。

    • slaveConnectionMinimumIdleSize(从节点最小空闲连接数)

    • 默认值:32

    • 多从节点的环境里,每个 从服务节点里用于普通操作(非 发布和订阅)的最小保持连接数(长连接)。长期保持一定数量的连接有利于提高瞬时读取反映速度。

    • slaveConnectionPoolSize(从节点连接池大小)

    • 默认值:64

    • 多从节点的环境里,每个 从服务节点里用于普通操作(非 发布和订阅)连接的连接池最大容量。连接池的连接数量自动弹性伸缩。

    • masterConnectionMinimumIdleSize(主节点最小空闲连接数)

    • 默认值:32

    • 多从节点的环境里,每个 主节点的最小保持连接数(长连接)。长期保持一定数量的连接有利于提高瞬时写入反应速度。

    • masterConnectionPoolSize(主节点连接池大小)

    • 默认值:64

    • 主节点的连接池最大容量。连接池的连接数量自动弹性伸缩。

    */
    @Configuration
    public class RedissonManager{

    @Bean
    public RedissonClient getRedisson(){
        //redisson版本是3.5,集群的ip前面要加上“redis://”,不然会报错,3.2版本可不加
        RedissonClient redisson = null;
        Config config = new Config();
        config.useSingleServer()
              .setAddress("redis://127.0.0.1:6379");
        redisson = Redisson.create(config);
        return redisson;
    }
    

    }

    3.定义工具类方便调用方使用
    @Component
    public class RedissonLockUtil {

    private static DistributedLocker redissLock;
    
    @Autowired
    private DistributedLocker redisClient;
    
    @PostConstruct
    public void init() {
        this.redissLock = redisClient;
    }
    
    /**
     * 加锁
     * @param lockKey
     * @return
     */
    public static RLock lock(String lockKey) {
        return redissLock.lock(lockKey);
    }
    
    /**
     * 释放锁
     * @param lockKey
     */
    public static void unlock(String lockKey) {
        redissLock.unlock(lockKey);
    }
    
    /**
     * 释放锁
     * @param lock
     */
    public static void unlock(RLock lock) {
        redissLock.unlock(lock);
    }
    
    /**
     * 带超时的锁
     * @param lockKey
     * @param timeout 超时时间 单位:秒
     */
    public static RLock lock(String lockKey, int timeout) {
        return redissLock.lock(lockKey, timeout);
    }
    
    /**
     * 带超时的锁
     * @param lockKey
     * @param unit 时间单位
     * @param timeout 超时时间
     */
    public static RLock lock(String lockKey, TimeUnit unit , int timeout) {
        return redissLock.lock(lockKey, unit, timeout);
    }
    
    /**
     * 尝试获取锁
     * @param lockKey
     * @param waitTime 最多等待时间
     * @param leaseTime 上锁后自动释放锁时间
     * @return
     */
    public static boolean tryLock(String lockKey, int waitTime, int leaseTime) {
        return redissLock.tryLock(lockKey, TimeUnit.SECONDS, waitTime, leaseTime);
    }
    
    /**
     * 尝试获取锁
     * @param lockKey
     * @param unit 时间单位
     * @param waitTime 最多等待时间
     * @param leaseTime 上锁后自动释放锁时间
     * @return
     */
    public static boolean tryLock(String lockKey, TimeUnit unit, int waitTime, int leaseTime) {
        return redissLock.tryLock(lockKey, unit, waitTime, leaseTime);
    }
    
    public static String getString(String key){
        return redissLock.getString(key);
    }
    
    public static void setString(String key, Object value){
        redissLock.setString(key,value);
    }
    

    }

    5.定一个接口和实现类
    public interface DistributedLocker {

    RLock lock(String lockKey);
    
    RLock lock(String lockKey, long timeout);
    
    RLock lock(String lockKey, TimeUnit unit, long timeout);
    
    boolean tryLock(String lockKey, TimeUnit unit, long waitTime, long leaseTime);
    
    void unlock(String lockKey);
    
    void unlock(RLock lock);
    
    String getString(String key);
    
    void setString(String key, Object value);
    
    boolean hasString(String key);
    
    long incr(String key, long delta);
    

    }
    @Service
    public class RedissonDistributedLocker implements DistributedLocker {

    //RedissonClient已经由配置类生成,这里自动装配即可
    @Autowired
    private RedissonClient redissonClient;
    
    //lock(), 拿不到lock就不罢休,不然线程就一直block
    @Override
    public RLock lock(String lockKey) {
        RLock lock = redissonClient.getLock(lockKey);
        lock.lock();
        return lock;
    }
    
    //leaseTime为加锁时间,单位为秒
    @Override
    public RLock lock(String lockKey, long leaseTime) {
        RLock lock = redissonClient.getLock(lockKey);
        lock.lock(leaseTime, TimeUnit.SECONDS);
        return lock;
    }
    
    //timeout为加锁时间,时间单位由unit确定
    @Override
    public RLock lock(String lockKey, TimeUnit unit ,long timeout) {
        RLock lock = redissonClient.getLock(lockKey);
        lock.lock(timeout, unit);
        return lock;
    }
    //tryLock(),马上返回,拿到lock就返回true,不然返回false。
    //带时间限制的tryLock(),拿不到lock,就等一段时间,超时返回false.
    @Override
    public boolean tryLock(String lockKey, TimeUnit unit, long waitTime, long leaseTime) {
        RLock lock = redissonClient.getLock(lockKey);
        try {
            return lock.tryLock(waitTime, leaseTime, unit);
        } catch (InterruptedException e) {
            return false;
        }
    }
    
    @Override
    public void unlock(String lockKey) {
        RLock lock = redissonClient.getLock(lockKey);
        lock.unlock();
    }
    
    @Override
    public void unlock(RLock lock) {
        lock.unlock();
    }
    
    @Override
    public String getString(String key) {
        RBucket<Object> bucket = redissonClient.getBucket(key);
        return bucket.get() == null ? null : bucket.get().toString();
    }
    
    @Override
    public void setString(String key, Object value) {
        RBucket<Object> result = this.redissonClient.getBucket(key);
        if (!result.isExists()) {
            result.set(value, 5, TimeUnit.MINUTES);
        }
    }
    
    @Override
    public boolean hasString(String key) {
        RBucket<Object> result = redissonClient.getBucket(key);
        if (result.isExists()) {
            return true;
        } else {
            return false;
        }
    }
    
    @Override
    public long incr(String key, long delta) {
        return redissonClient.getAtomicLong(key).addAndGet(delta);
    }
    

    }
    6.controller
    @RestController
    @RequestMapping("/redisson")
    public class AdvMaterialController {

    // @Autowired
    // private DistributedLocker distributedLocker;
    @RequestMapping("/test")
    public void redissonTest() {
    String key = “redisson_key”;
    for (int i = 0; i < 100; i++) {
    Thread t = new Thread(new Runnable() {
    @Override
    public void run() {
    try {
    System.err.println("=线程开启"+Thread.currentThread().getName());
    /*distributedLocker.lock(key,10L); //直接加锁,获取不到锁则一直等待获取锁
    Thread.sleep(100); //获得锁之后可以进行相应的处理
    System.err.println(“获得锁后进行相应的操作”+Thread.currentThread().getName());
    distributedLocker.unlock(key); //解锁
    System.err.println("============================="+Thread.currentThread().getName());*/

                        boolean isGetLock =  RedissonLockUtil.tryLock(key, TimeUnit.SECONDS,5,10); //尝试获取锁,等待5秒,自己获得锁后一直不解锁则10秒后自动解锁
                        if(isGetLock){
                            Thread.sleep(100); //获得锁之后可以进行相应的处理
                            System.err.println("======获得锁后进行相应的操作======"+Thread.currentThread().getName());
                            //distributedLocker.unlock(key);
                            System.err.println("============================="+Thread.currentThread().getName());
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }finally {
                        RedissonLockUtil.unlock(key);
                    }
                }
            });
            t.start();
        }
    }
    
    @RequestMapping("/test1")
    public void redissonSetTest() {
        RedissonLockUtil.setString("test","abc");
    }
    
    @RequestMapping("/test2")
    public String redissonGetTest() {
        return RedissonLockUtil.getString("test");
    }
    
    展开全文
  • redis redisson 使用说明

    千次阅读 2019-11-23 16:36:26
    redisredisson 使用说明 redisson将数据存储在redis中,提供了一系列的分布式对象(Set、Map、List、Queue、Lock、发布/订阅、信号量、布隆过滤器等),提高了开发效率 官网:...
  • Redisson使用-springmvc

    千次阅读 2018-12-22 16:19:37
    Redisson使用-springmvc 日前在学习redisson,记录一下。 配置 1.首先官网连接:https://github.com/redisson/redisson 2.我采用的是xml配置,一下是官网配置(哨兵模式,其他模式在官网wiki中可以看到): &...
  • Redisson使用 redisConfig配置 使用 测试 jemeter进行压测 成功! 完善 finally 那样写有可能会报错! 推荐写法
  • springboot引入redisson使用分布式锁 网址:https://github.com/redisson/redisson/ 1.加依赖(pom.xml) <dependency> <groupId>org.redisson</groupId> <artifactId>redisson</...
  • Redisson 使用手册

    2020-12-16 11:29:30
    原文链接:https://www.bookstack.cn/read/redisson-wiki-zh/Redisson%E9%A1%B9%E7%9B%AE%E4%BB%8B%E7%BB%8D.md
  • Redisson - Redis Java clientwith features of an in-memory data grid Quick start | Documentation | Javadocs | Changelog | Code examples | FAQs | Report an issue Based on high-performance async and ...
  • Redisson 是一个在 Redis 的基础上实现的 Java 驻内存数据网格,相较于暴露底层操作的Jedis,Redisson提供了一系列的分布式的 Java 常用对象,还提供了许多分布式服务。特性 & 功能:支持 Redis 单节点(single)...
  • springboot整合redisson使用redis集群做分布式锁说明maven依赖Redisson配置yml配置client配置使用最后 说明 springboot集群部署时,定时任务存在多份,所以需要一个分布式锁来进行竞争,在zookeeper和redis之间选择...
  • Redisson 使用手册.pdf

    2021-05-10 07:56:45
    redission 内存数据网格,中文文档
  • Redisson使用(可重入锁,信号量,闭锁) 在分布式系统大行其道的年代,JUC包下的单机锁,已经不能适用了。这时分布式锁应运而生。分布式锁的实现方法有很多,相信大家最最常用的,应该是结合redis的分布式锁了。...
  • Redisson使用起来很方便,但是需要redis环境支持eval命令,否则一切都是悲剧,比如me.结果还是要用RedisCommands去写一套。例子就如下,获得一个RLock锁对象,然后tryLock 和unlock。trylock方法提供了锁重入的实现...
  • redisson使用第一次碰到的坑

    万次阅读 热门讨论 2017-07-10 19:57:08
    1、由于用的jersey,而jersey使用的jack-json版本和redison使用的不一样,导致maven依赖冲突。 解决思路,优先考虑使用exclusions排除重复的jar包。如果解决不了,那就添加不同版本的...2、官方配置redisson的单机配置
  • 线程并发redisson使用遇到的坑

    千次阅读 2020-06-01 23:00:01
    因为业务上的一个购买需求,需要对库存进行行程保护,防止超卖的出现(我们不是电商公司),经过调研,最终选择使用Redission来进行控制。主要因为Redission丰富的API,开源框架,已经被广泛应用于实际生产环境。 ....

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,487
精华内容 594
关键字:

redisson使用

redis 订阅