Springboot集成Jedis + Redisson(已自測)

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

 

 

本文主要跟你們分享在Springboot中集成Jedis和Redisson的方法。爲何要集成兩個redis客戶端?那是由於它們各有所長也各有所缺,合在一塊兒才能完善彼此。Jedis做爲Redis客戶端的java版實現實現了絕大部分的Redis原生功能,可是卻沒有對分佈式線程控制作很好的支持。而Redisson是Redis官方推薦的支持分佈式操做的Redis Java版客戶端,但它卻不支持一些基礎的Redis原生功能,因此Jedis和Redisson只有整合到一塊兒使用,才能更好的知足用戶的需求。node

接下來,分幾個步驟分享給你們如何在Springboot中集成Jedis和Redisson。git

 

首先,經過start.spring.io生成一個支持redis的web項目github

將生成的項目導入IDE,e.g., Intellij IDEA.web

在pom文件中加入redisson依賴 (添加完後,能夠作下Maven -> Reimport)redis

爲每一個環境建立一套配置文件spring

本地開發環境以-local結尾,測試環境以-test結尾,生產環境以-prod結尾。而後在application.yml配置文件中指定激活那個環境的配置文件api

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);
    }

}
相關文章
相關標籤/搜索