zoukankan      html  css  js  c++  java
  • Springboot集成Jedis + Redisson(已自测)

    原文:https://blog.csdn.net/c_zyer/article/details/79415728

    本文主要跟大家分享在Springboot中集成Jedis和Redisson的方法。为什么要集成两个redis客户端?那是因为它们各有所长也各有所缺,合在一起才能完善彼此。Jedis作为Redis客户端的java版实现实现了绝大部分的Redis原生功能,但是却没有对分布式线程控制做很好的支持。而Redisson是Redis官方推荐的支持分布式操作的Redis Java版客户端,但它却不支持一些基础的Redis原生功能,所以Jedis和Redisson只有整合到一起使用,才能更好的满足用户的需求。

    接下来,分几个步骤分享给大家如何在Springboot中集成Jedis和Redisson。

    首先,通过start.spring.io生成一个支持redis的web项目

    将生成的项目导入IDE,e.g., Intellij IDEA.

    在pom文件中加入redisson依赖 (添加完后,可以做下Maven -> Reimport)

    为每个环境创建一套配置文件

    本地开发环境以-local结尾,测试环境以-test结尾,生产环境以-prod结尾。然后在application.yml配置文件中指定激活那个环境的配置文件

    spring:
      application:
        name: demo
      profiles:
        active: '@profileActive@'

    此处别忘了

    在相应环境的application配置文件中添加相应的Redis配置(Redis服务做成了哨兵模式),比如,在application-local.yml加入

    spring:
      redis:
        database: 0
        password: 12345678 #密码
        port: 6379
        timeout: 0
        pool:
          max-active: 8 #最大连接数
          max-idle: 8 #最大空闲连接数
          max-wait: -1 #最大等待时间
          min-idle: 0
        sentinel:
          master: master1
          nodes: 172.16.33.216:16001,172.16.33.216:16002
    server:
      port: 9090

    在相应环境的Redisson配置文件中加入Redisson的配置信息(配置来源Redisson官方,点击查看

    ---
    sentinelServersConfig:
      idleConnectionTimeout: 10000
      pingTimeout: 1000
      connectTimeout: 10000
      timeout: 3000
      retryAttempts: 3
      retryInterval: 1500
      reconnectionTimeout: 3000
      failedAttempts: 3
      password: 12345678
      subscriptionsPerConnection: 5
      clientName: null
      loadBalancer: !<org.redisson.connection.balancer.RoundRobinLoadBalancer> {}
      slaveSubscriptionConnectionMinimumIdleSize: 1
      slaveSubscriptionConnectionPoolSize: 50
      slaveConnectionMinimumIdleSize: 10
      slaveConnectionPoolSize: 64
      masterConnectionMinimumIdleSize: 10
      masterConnectionPoolSize: 64
      readMode: "SLAVE"
      sentinelAddresses:
      - "redis://172.16.33.216:16001"
      - "redis://172.16.33.216:16002"
      masterName: "master1"
      database: 0
    threads: 0
    nettyThreads: 0
    codec: !<org.redisson.codec.JsonJacksonCodec> {}
    useLinuxNativeEpoll: false

    配置文件配好后,还需要注册一个Springboot的启动类(DemoApplication.java)中注册一个RedissonClient Bean,方法如下:

    @Autowired
    private Environment env;
    
    @Bean(destroyMethod = "shutdown")
    public RedissonClient redissonClient() throws IOException {
    	String[] profiles = env.getActiveProfiles();
    	String profile = "";
    	if(profiles.length > 0) {
    		profile = "-" + profiles[0];
    	}
    	return Redisson.create(
    			Config.fromYAML(new ClassPathResource("redisson" + profile + ".yml").getInputStream())
    	);
    }

    Everything is ready. Now let's rock.

    创建一个Controller类

    @RestController
    @RequestMapping("/demo")
    public class DemoController {
    
        private static Logger logger = LoggerFactory.getLogger(DemoController.class);
    
        @Autowired
        private RedisTemplate<String, String> redisTemplate;
        @Autowired
        private RedissonClient redissonClient;
    
        @ResponseBody
        @RequestMapping("/lock")
        public String lock(@RequestParam("sid") String serverId) {
            Long counter = redisTemplate.opsForValue().increment("COUNTER", 1);
            RLock lock = redissonClient.getLock("TEST");
            try {
                lock.lock();
                logger.info("Request Thread - " + counter + "[" + serverId +"] locked and begun...");
                Thread.sleep(5000); // 5 sec
                logger.info("Request Thread - " + counter + "[" + serverId +"] ended successfully...");
            } catch (Exception ex) {
                logger.error("Error occurred");
            } finally {
                lock.unlock();
                logger.info("Request Thread - " + counter + "[" + serverId +"] unlocked...");
            }
    
            return "lock-" + counter + "[" + serverId +"]";
        }
    }

    Code 完成,启动程序,在浏览器中试一把先

    =================================================================

    以下自己实现的

    import java.io.IOException;
    
    import org.redisson.Redisson;
    import org.redisson.api.RedissonClient;
    import org.redisson.config.Config;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Bean;
    import org.springframework.core.env.Environment;
    import org.springframework.core.io.ClassPathResource;
    import org.springframework.stereotype.Component;
    
    @Component
    public class RedissonClientConfig {
    
        @Autowired
        private Environment env;
    
        @Bean(destroyMethod = "shutdown")
        public RedissonClient redissonClient() throws IOException {
            String[] profiles = env.getActiveProfiles();
            String profile = "";
            if(profiles.length > 0) {
                profile = "-" + profiles[0];
            }
            return Redisson.create(Config.fromYAML(new ClassPathResource("redisson" + profile + ".yml").getInputStream()));
        }
        
    }

    配置文件  redisson-prod.yml

    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://192.168.20.123:6379"
      password: 123456
      subscriptionConnectionMinimumIdleSize: 1
      subscriptionConnectionPoolSize: 50
      connectionMinimumIdleSize: 32
      connectionPoolSize: 64
      database: 15
      dnsMonitoring: false
      dnsMonitoringInterval: 5000
    threads: 0
    nettyThreads: 0
    codec: !<org.redisson.codec.JsonJacksonCodec> {}
    "transportMode": "NIO"

    controller

    import java.util.concurrent.TimeUnit;
    
    import org.redisson.api.RLock;
    import org.redisson.api.RedissonClient;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.ResponseBody;
    import org.springframework.web.bind.annotation.RestController;
    
    
    @RestController
    @RequestMapping("/demo")
    public class DemoController {
    
        private static Logger logger = LoggerFactory.getLogger(DemoController.class);
    
        @Autowired
        private RedisTemplate<String, String> redisTemplate;
        @Autowired
        private RedissonClient redissonClient;
    
        public static int COUNT = 3;
        
        @ResponseBody
        @RequestMapping("/lock")
        public String lock(@RequestParam("sid") String serverId) {
            Long counter = redisTemplate.opsForValue().increment("COUNTER", 1);
            redisTemplate.expire("COUNTER", 43200, TimeUnit.SECONDS);
            
            if (counter>3) {
                return "大于3了";
            }
            RLock lock = redissonClient.getFairLock("TEST");
            try {
                lock.lock(5, TimeUnit.SECONDS);
                
                logger.info("Request Thread - " + counter + "[" + serverId +"] locked and begun...");
                if (COUNT > 0) {
                    COUNT = COUNT - 1;
                    Thread.sleep(1000);
                } else {
                    return "为0了";
                }
                logger.info("Request Thread - " + counter + "[" + serverId +"] ended successfully...");
            } catch (Exception ex) {
                logger.error("Error occurred");
            } finally {
                if (lock != null && lock.isLocked()) {
                    lock.unlock();
                }
                logger.info("Request Thread - " + counter + "[" + serverId +"] unlocked...");
            }
    
            return "卖出lock-" + counter + "[" + serverId +"]" + COUNT;
        }
        
    }

    写个多线程测试

    import java.util.HashMap;
    import java.util.Map;
    import java.util.concurrent.CountDownLatch;
    
    import com.hyb.util.HttpClientUtil;
    
    //多线程的写法1
    public class Thread12 {
        
        
        private static Map<String,String> parms = new HashMap<String,String>();
        
        public static void main(String[] args) {
            testCountDownLatch();
        }
        
        public static void testCountDownLatch(){
            
            int threadCount = 2000;
            
            final CountDownLatch latch = new CountDownLatch(threadCount);
            for(int i=0; i< threadCount; i++){
                 
                new Thread(new Runnable() {
                    
                    @Override
                    public void run() {
    
                        System.out.println("线程" + Thread.currentThread().getId() + "开始出发");
    
                        try {
                            parms.put("sid", "线程id=" +Thread.currentThread().getId());
                            String result = HttpClientUtil.doGet("http://192.168.20.234:8061/demo/lock", parms, 20000);
                            System.out.println("线程result" + result);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
    
                        System.out.println("线程" + Thread.currentThread().getId() + "已到达终点");
    
                        latch.countDown();
                    }
                }).start();
            }
            
            try {
                latch.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    
            System.out.println(threadCount+"个线程已经执行完毕");
        }
    
    }    
    import java.util.HashMap;
    import java.util.Map;
    
    import com.hyb.util.HttpClientUtil;
    
    //多线程的写法1
    public class Thread12 {
        
        
        
        
    
    public static void main(String args[]) {
        
    MyThread myThread =new MyThread();
    //myThread.run();
    //把这个MyThread包装称为Thread
    Thread t1 =new Thread(myThread);
    Thread t2=new Thread(myThread);
    Thread t3=new Thread(myThread);
    Thread t4=new Thread(myThread);
    Thread t5=new Thread(myThread);
    Thread t6=new Thread(myThread);
    Thread t7=new Thread(myThread);
    Thread t8=new Thread(myThread);
    Thread t9=new Thread(myThread);
    Thread t10=new Thread(myThread);
    Thread t11=new Thread(myThread);
    Thread t12=new Thread(myThread);
    t1.start();
    t2.start();
    t3.start();
    t4.start();
    t5.start();
    t6.start();
    t7.start();
    t8.start();
    t9.start();
    t10.start();
    t11.start();
    t12.start();
    }
    
    }
    
    
    class MyThread implements Runnable {
        
        private static Map<String,String> parms = new HashMap<String,String>();
        
        @Override
        public void run() {
            parms.put("sid", Thread.currentThread().getName());
            String result = HttpClientUtil.doGet("http://192.168.20.234:8061/demo/lock", parms, 20000);
            System.out.println("返回:"+result);
        }
    
    }
  • 相关阅读:
    The server selected protocol version TLS10 is not accepted by client preferences [TLS12]
    修改阿里云xshell下的实例名
    ElasticSearch数据及其使用
    super()内置方法的使用
    python私有变量+路径解读+三元运算+any/all
    Anconada基础使用
    Tomcat安全基线
    Windows 安装mysql及修改默认文件存储路径
    解决IDEA下使用logback控制台打印日志中文字符为乱码,全网最全保证配置为不乱码
    基于SpringBoot开发一个Restful服务,实现增删改查功能(转载自https://www.cnblogs.com/xuwujing/p/8260935.html)
  • 原文地址:https://www.cnblogs.com/shihaiming/p/8760439.html
Copyright © 2011-2022 走看看