SpringBoot整合Redis解決叢集共享快取問題
阿新 • • 發佈:2018-11-04
需求分析:
應用程式採用整合的方式部署在3臺伺服器上,每臺伺服器上應用請求同一臺資料庫伺服器,應用程式中獲取當前使用者資訊是從當前伺服器上選取的,當前臺傳送求後需在後臺修改當前使用者的相關屬性,然後查詢當前屬性下的一些資料資訊
產生問題:
採用整合的方式部署,會導致當前修改請求傳送到其中一臺伺服器上,該臺伺服器上的使用者資訊修改了,而其他伺服器的使用者資訊並沒有修改,當下一次的請求傳送到的是另一個伺服器,再查詢資料時,查詢到的資料並不是根據修改後屬性下的資料資訊
解決方法:
通過部署redis,將當前使用者資訊儲存在Redis上,幾臺伺服器共同連線一個Redis,獲取當前使用者資訊時,從Redis中獲取,因Redis是一個高效能的key-value資料庫,避免了修改從傳統的關係型資料庫存取值,可以提高效能
SpringBoot中整合Redis
下面詳細描述一下在SpringBoot中整合Redis的步驟,以及當中踩到的坑
下載Redis
中國官網:http://redis.cn/
官網: https://redis.io/
github網址:https://github.com/antirez/redis
可以通過如下方式,下載相應版本
在Windows中安裝Redis和啟動
本人下載版本為Redis-x64-2.8.2402,存放路徑D:\BaiduNetdiskDownload\Redis-x64-2.8.2402
在當前檔案加下,開啟cmd命令,輸入命令:redis-server redis.windows.conf
遇到的問題:
解決辦法:redis-server redis.windows.conf –maxmemory 200m
正確啟動後介面:
SpringBoot專案中的pom.xml檔案中引入依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-redis</artifactId>
</dependency>
在application.properties加入redis配置
# Redis資料庫索引(預設為0)
spring.redis.database=0
# Redis伺服器地址
#spring.redis.host=10.28.124.201
spring.redis.host=10.0.11.210
# Redis伺服器連線埠
spring.redis.port=6379
# Redis伺服器連線密碼(預設為空)
spring.redis.password=
# 連線池最大連線數(使用負值表示沒有限制)
spring.redis.pool.max-active=8
# 連線池最大阻塞等待時間(使用負值表示沒有限制)
spring.redis.pool.max-wait=-1
# 連線池中的最大空閒連線
spring.redis.pool.max-idle=8
# 連線池中的最小空閒連線
spring.redis.pool.min-idle=0
# 連線超時時間(毫秒)
spring.redis.timeout=0
RedisConfig配置類,其中@EnableCaching開啟註解 (特別注意,不然redis配置可能不生效)
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
/**
* 〈Redis配置〉
* @author
* @create 2018/6/4
* @since 1.0.0
*/
@Configuration
@EnableCaching//開啟快取
public class RedisConfig extends CachingConfigurerSupport{
@Bean
public CacheManager cacheManager(RedisTemplate<?,?> redisTemplate) {
CacheManager cacheManager = new RedisCacheManager(redisTemplate);
return cacheManager;
}
@Bean
public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, String> redisTemplate = new RedisTemplate<String, String>();
redisTemplate.setConnectionFactory(factory);
return redisTemplate;
}
}
編寫RedisService服務,便於存取資料
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.*;
import org.springframework.stereotype.Component;
import java.io.Serializable;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
/**
* 〈Redis操作類〉
* @author
* @create 2018/6/5
* @since 1.0.0
*/
@Component
public class RedisService {
@Autowired
private RedisTemplate redisTemplate;
/**
* 寫入快取
* @param key
* @param value
* @return
*/
public boolean set(final String key, Object value) {
boolean result = false;
try {
ValueOperations operations = redisTemplate.opsForValue();
operations.set(key, value);
result = true;
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
* 寫入快取設定時效時間
* @param key
* @param value
* @return
*/
public boolean set(final String key, Object value, Long expireTime) {
boolean result = false;
try {
ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
operations.set(key, value);
redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);
result = true;
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
* 批量刪除對應的value
* @param keys
*/
public void remove(final String... keys) {
for (String key : keys) {
remove(key);
}
}
/**
* 批量刪除key
* @param pattern
*/
public void removePattern(final String pattern) {
Set<Serializable> keys = redisTemplate.keys(pattern);
if (keys.size() > 0)
redisTemplate.delete(keys);
}
/**
* 刪除對應的value
* @param key
*/
public void remove(final String key) {
if (exists(key)) {
redisTemplate.delete(key);
}
}
/**
* 判斷快取中是否有對應的value
* @param key
* @return
*/
public boolean exists(final String key) {
return redisTemplate.hasKey(key);
}
/**
* 讀取快取
* @param key
* @return
*/
public Object get(final String key) {
Object result = null;
ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
result = operations.get(key);
return result;
}
/**
* 雜湊 新增
* @param key
* @param hashKey
* @param value
*/
public void hmSet(String key, Object hashKey, Object value){
HashOperations<String, Object, Object> hash = redisTemplate.opsForHash();
hash.put(key,hashKey,value);
}
/**
* 雜湊獲取資料
* @param key
* @param hashKey
* @return
*/
public Object hmGet(String key, Object hashKey){
HashOperations<String, Object, Object> hash = redisTemplate.opsForHash();
return hash.get(key,hashKey);
}
/**
* 列表新增
* @param k
* @param v
*/
public void lPush(String k,Object v){
ListOperations<String, Object> list = redisTemplate.opsForList();
list.rightPush(k,v);
}
/**
* 列表獲取
* @param k
* @param l
* @param l1
* @return
*/
public List<Object> lRange(String k, long l, long l1){
ListOperations<String, Object> list = redisTemplate.opsForList();
return list.range(k,l,l1);
}
/**
* 集合新增
* @param key
* @param value
*/
public void add(String key,Object value){
SetOperations<String, Object> set = redisTemplate.opsForSet();
set.add(key,value);
}
/**
* 集合獲取
* @param key
* @return
*/
public Set<Object> setMembers(String key){
SetOperations<String, Object> set = redisTemplate.opsForSet();
return set.members(key);
}
/**
* 有序集合新增
* @param key
* @param value
* @param scoure
*/
public void zAdd(String key,Object value,double scoure){
ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
zset.add(key,value,scoure);
}
/**
* 有序集合獲取
* @param key
* @param scoure
* @param scoure1
* @return
*/
public Set<Object> rangeByScore(String key,double scoure,double scoure1){
ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
return zset.rangeByScore(key, scoure, scoure1);
}
}
使用例項
@RestController
@RequestMapping
public class LoginController {
@Resource
RedisService redisService;
@RequestMapping("login")
@ResponseBody
public Result login(@RequestBody Map<String, Object> param,
HttpServletResponse response, HttpSession session) {
String account = param.get("userName").toString();
redisService.remove("account");//若存在,則刪除
redisService.set("account",account);//設定
redisService.get("account");//獲取
return ResultTool.successData(account);
}
}
關於redis的整合,本文主要參考的了《SpringBoot整合Redis》