Spring boot與Redis的整合使用
阿新 • • 發佈:2018-12-20
關於Redis的安裝與叢集部署,可以參考《Linux下Redis的叢集部署》
一、Redis的單機使用
(1) 新建gradle專案,依賴如下:
dependencies { compile 'org.springframework.boot:spring-boot-starter-web' compile ('org.springframework.boot:spring-boot-starter-data-redis'){ exclude(group:'io.lettuce') } compile 'redis.clients:jedis' testImplementation('org.springframework.boot:spring-boot-starter-test') }
(2) 在application.yml中配置redis資訊
spring:
redis:
host: 127.0.0.1
port: 6379
password: ******* #密碼
timeout: 10000
(3) 配置redis資訊RedisConfig.java
@Bean public JedisPoolConfig jedisPoolConfig() { JedisPoolConfig jedisPoolConfig = new JedisPoolConfig(); // 最大空閒數 jedisPoolConfig.setMaxIdle(300); // 連線池的最大資料庫連線數 jedisPoolConfig.setMaxTotal(100); // 最大建立連線等待時間 jedisPoolConfig.setMaxWaitMillis(10000); // 逐出連線的最小空閒時間 預設1800000毫秒(30分鐘) return jedisPoolConfig; } @Bean public JedisConnectionFactory jedisConnectionFactory(JedisPoolConfig jedisPoolConfig){ RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration(); //設定redis伺服器的host或者ip地址 redisStandaloneConfiguration.setHostName(host); //設定預設使用的資料庫 redisStandaloneConfiguration.setDatabase(0); //設定密碼 redisStandaloneConfiguration.setPassword(RedisPassword.of(password)); //設定redis的服務的埠號 redisStandaloneConfiguration.setPort(port); //獲得預設的連線池構造器(怎麼設計的,為什麼不抽象出單獨類,供使用者使用呢) JedisClientConfiguration.JedisPoolingClientConfigurationBuilder jpcb = (JedisClientConfiguration.JedisPoolingClientConfigurationBuilder)JedisClientConfiguration.builder(); //指定jedisPoolConifig來修改預設的連線池構造器(真麻煩,濫用設計模式!) jpcb.poolConfig(jedisPoolConfig); //通過構造器來構造jedis客戶端配置 JedisClientConfiguration jedisClientConfiguration = jpcb.build(); //單機配置 + 客戶端配置 = jedis連線工廠 return new JedisConnectionFactory(redisStandaloneConfiguration, jedisClientConfiguration); } @Bean public RedisTemplate<String, Object> functionDomainRedisTemplate(RedisConnectionFactory redisConnectionFactory) { RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>(); initDomainRedisTemplate(redisTemplate, redisConnectionFactory); return redisTemplate; } /** * 設定資料存入 redis 的序列化方式,並開啟事務 * * @param redisTemplate * @param factory */ private void initDomainRedisTemplate(RedisTemplate<String, Object> redisTemplate, RedisConnectionFactory factory) { //如果不配置Serializer,那麼儲存的時候預設使用String,如果用User型別儲存,那麼會提示錯誤User can't cast to String! redisTemplate.setKeySerializer(new StringRedisSerializer()); redisTemplate.setHashKeySerializer(new StringRedisSerializer()); redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer()); redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer()); // 開啟事務 redisTemplate.setEnableTransactionSupport(true); redisTemplate.setConnectionFactory(factory); } /** * 注入封裝RedisTemplate * @date 2017年12月21日 * @throws */ @Bean(name = "redisUtils") public RedisUtils redisUtil(RedisTemplate<String, Object> redisTemplate) { RedisUtils redisUtil = new RedisUtils(); redisUtil.setRedisTemplate(redisTemplate); return redisUtil; }
(4) redis工具類RedisUtils.java
public class RedisUtils { private RedisTemplate<String, Object> redisTemplate; public void setRedisTemplate(RedisTemplate<String, Object> redisTemplate) { this.redisTemplate = redisTemplate; } //=============================common============================ /** * 指定快取失效時間 * * @param key 鍵 * @param time 時間(秒) * @return */ public boolean expire(String key, long time) { try { if (time > 0) { redisTemplate.expire(key, time, TimeUnit.SECONDS); } return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 根據key 獲取過期時間 * * @param key 鍵 不能為null * @return 時間(秒) 返回0代表為永久有效 */ public long getExpire(String key) { return redisTemplate.getExpire(key, TimeUnit.SECONDS); } /** * 判斷key是否存在 * * @param key 鍵 * @return true 存在 false不存在 */ public boolean hasKey(String key) { try { return redisTemplate.hasKey(key); } catch (Exception e) { e.printStackTrace(); return false; } } /** * 刪除快取 * * @param key 可以傳一個值 或多個 */ @SuppressWarnings("unchecked") public void del(String... key) { if (key != null && key.length > 0) { if (key.length == 1) { redisTemplate.delete(key[0]); } else { redisTemplate.delete(CollectionUtils.arrayToList(key)); } } } // ..... 其餘的見原始碼 }
(5) 測試redis功能RedisController.java
@RestController
@RequestMapping("/redis")
public class RedisController {
@Autowired
private RedisUtils redisUtils;
@GetMapping("/set-string")
public ResponseEntity setString(){
boolean result = redisUtils.set("nsk","handsome",1000);
return ResponseEntity.ok(result);
}
}
測試結果:
檢視redis資訊:
此時,可以看出可以在Spring boot專案中正常使用單機版Redis.
二、Redis叢集的使用
(1) 修改上述的application.yml檔案
spring:
redis:
cache:
cluster-nodes: 127.0.0.1:6001,127.0.0.1:6002,127.0.0.1:6003
command-timeout: 5000
password: ******* # 密碼
host: 127.0.0.1
port: 6379
password: ****** # 密碼
timeout: 10000
(2) 獲取Redis叢集連線屬性JedisProperties.java
@Component
@ConfigurationProperties(prefix = "spring.redis.cache")
public class JedisProperties {
private String clusterNodes;
private Integer commandTimeout;
private String password;
// ... 省略getter和setter方法
}
(3) 配置Redis叢集JedisClusterConfig.java
@Configuration
@EnableConfigurationProperties(JedisProperties.class)
public class JedisClusterConfig {
private static final Logger LOGGER = LoggerFactory.getLogger(JedisClusterConfig.class);
@Autowired
private JedisProperties jedisProperties;
private int maxTotal = 100;
private int maxIdle = 5;
private int maxWaitMills = 1000;
private int soTimeout = 5000;
private int maxAttempts = 5;
@Bean
public JedisCluster getJedisCluster() {
String[] serverArray = jedisProperties.getClusterNodes().split(",");
GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
poolConfig.setMaxIdle(maxIdle);
poolConfig.setMaxTotal(maxTotal);
poolConfig.setMaxWaitMillis(maxWaitMills);
LOGGER.info("***************" + jedisProperties.getClusterNodes());
Set<HostAndPort> nodes = new HashSet<>();
for (String ipPort : serverArray) {
String[] ipPortPair = ipPort.split(":");
nodes.add(new HostAndPort(ipPortPair[0].trim(), Integer.valueOf(ipPortPair[1].trim())));
}
return new JedisCluster(nodes, jedisProperties.getCommandTimeout(), soTimeout, maxAttempts,
jedisProperties.getPassword(), poolConfig);
}
}
(4) 測試redis叢集JedisController.java
@RestController
@RequestMapping("/jedis")
public class JedisController {
@Autowired
private JedisCluster jedisCluster;
@GetMapping("/set-string")
public ResponseEntity setString(){
long result = jedisCluster.setnx("weight","168");
return ResponseEntity.ok(result);
}
@GetMapping("/{key}")
public ResponseEntity getValueByKey(@PathVariable String key){
String name = jedisCluster.get(key);
return ResponseEntity.ok(name);
}
}
結果如下:
檢視Redis叢集資訊:
-> redis-cli -c -h 127.0.0.1 -p 6001 -a ******
127.0.0.1:6001> get weight
-> Redirected to slot [16280] located at 127.0.0.1:6003
"62"
127.0.0.1:6003>
原始碼地址:《Redis-demo》