- redis是一個緩存服務器,他比其他的數據庫的處理效率要高,就是因爲他是以key-value的形式存儲數的,同時它的數據是存放在內存中的,而其他的數據庫大多是存放在磁盤中的,並且他是單線程的多路複用IO,單線程避免了線程切換的開銷,而多路複用IO避免了IO等待的開銷,在多核處理器下提高處理器的使用效率可以對數據進行分區,然後每個處理器處理不同的數據。所以,redis效率是比其他常見的數據庫速度更快的(mysql、oracle等)
- redis在項目中比較常用的就是用來作爲我們的一個分佈式事務緩存處理。主要處理在分佈式情況下,session共享,以及一些常用並且熱點數據的緩存,在涉及高併發的情況下,也可使用redis作爲分佈式鎖,解決高併發引發的一些數據不一致問題等。在這裏只介紹了一種,在分佈式下實現session共享。
- 在分佈式下,session是不存在的,他無法直接調用其他的服務,並且將session傳遞過去,因爲session是存在同一個會話下的,但是分佈式是一個個獨立的服務,有自己的處理方式、功能,這時候我們就需要引進token(session的大哥),通過token進行跨域訪問,將每一個會話進行攜帶過去,實現所謂的session共享.
- 對於token的生成,就是將一些指的內容,一些屬於自己的規矩進行數據加密,並且對於用戶的信息進行加密,作爲key鍵以及value值,存放到redis中,每一次請求的時候,將token存放於請求同中進行攜帶過來,服務端進行數據分離,獲取token信息,同時與redis中的數據進行比較進行token的置換,更新,刪除等一系列的操作,從而實現對特定功能的安全保護。這裏對token的加密規則就不做過多的介紹。
- 下面是一個簡單的redis使用,希望對大家有所幫助!
這是一個redis的配置類,通過在配置類中進行配置信息,開啓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.core.RedisTemplate;
@Configuration
@EnableCaching//開啓註解
public class RedisConfig extends CachingConfigurerSupport {
@Bean
public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, String> redisTemplate = new RedisTemplate<String, String>();
redisTemplate.setConnectionFactory(factory);
return redisTemplate;
}
}
這redis的工具類,主要用於對redis的操作方法封裝,方便使用
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* RedisAPI
*
* @author liuhui
* @date 2018-1-10
*/
@Component
public class RedisUtils {
private Logger logger = LoggerFactory.getLogger(RedisUtils.class);
@Resource
private RedisTemplate<String, Object> redisTemplate;
/**
* set key and value to redis
*
* @param key
* @param value
* @return
*/
public boolean set(String key, String value) {
redisTemplate.setKeySerializer(new StringRedisSerializer());
//設置序列化Value的實例化對象
redisTemplate.setValueSerializer(new StringRedisSerializer());
ValueOperations<String, Object> vo = redisTemplate.opsForValue();
vo.set(key, value);
return true;
}
/**
* set key and value to redis
*
* @param key
* @param seconds 有效期
* @param value
* @return
*/
public boolean set(String key, long seconds, String value) {
redisTemplate.setKeySerializer(new StringRedisSerializer());
//設置序列化Value的實例化對象
redisTemplate.setValueSerializer(new StringRedisSerializer());
ValueOperations<String, Object> vo = redisTemplate.opsForValue();
vo.set(key, value);
expire(key, seconds);
return true;
}
/**
* 更新指定key的value,剩餘過期時間不變
* @param key
* @param value
* @return
*/
public boolean update(String key, String value) {
redisTemplate.setKeySerializer(new StringRedisSerializer());
//設置序列化Value的實例化對象
redisTemplate.setValueSerializer(new StringRedisSerializer());
ValueOperations<String, Object> vo = redisTemplate.opsForValue();
//獲取當前key的過期時間
Long expireTime = redisTemplate.getExpire(key);
//重新設置設置過期時間
if (expireTime == null)
return false;
if (expireTime == -2 || expireTime == 0)
return false;
vo.set(key, value);
if (expireTime > 0)
expire(key, expireTime);
return true;
}
/**
* 獲取剩餘過期時間
* @param key
* @return
*/
public Long getExpire(String key) {
redisTemplate.setKeySerializer(new StringRedisSerializer());
//設置序列化Value的實例化對象
redisTemplate.setValueSerializer(new StringRedisSerializer());
ValueOperations<String, Object> vo = redisTemplate.opsForValue();
//獲取當前key的過期時間
return redisTemplate.getExpire(key);
}
/**
* 判斷某個key是否存在
*
* @param key
* @return
*/
public boolean exist(String key) {
redisTemplate.setKeySerializer(new StringRedisSerializer());
//設置序列化Value的實例化對象
redisTemplate.setValueSerializer(new StringRedisSerializer());
ValueOperations<String, Object> vo = redisTemplate.opsForValue();
Object value = vo.get(key);
return EmptyUtils.isEmpty(value) ? false : true;
}
public Object get(String key) {
redisTemplate.setKeySerializer(new StringRedisSerializer());
//設置序列化Value的實例化對象
redisTemplate.setValueSerializer(new StringRedisSerializer());
ValueOperations<String, Object> vo = redisTemplate.opsForValue();
return vo.get(key);
}
public void delete(String key) {
try {
redisTemplate.setKeySerializer(new StringRedisSerializer());
//設置序列化Value的實例化對象
redisTemplate.setValueSerializer(new StringRedisSerializer());
redisTemplate.delete(key);
} catch (Exception e) {
e.printStackTrace();
}
}
public Boolean setnx(final String key, final String value) throws Exception {
return redisTemplate.execute(new RedisCallback<Boolean>() {
@Override
public Boolean doInRedis(RedisConnection redisConnection) {
boolean flag = false;
try {
redisTemplate.setKeySerializer(new StringRedisSerializer());
//設置序列化Value的實例化對象
redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
byte keys[] = stringRedisSerializer.serialize(key);
byte values[] = stringRedisSerializer.serialize(value);
flag = redisConnection.setNX(keys, values);
} catch (Exception e) {
e.printStackTrace();
} finally {
return flag;
}
}
});
}
public Boolean expire(final String key, final long expireTime) {
return redisTemplate.execute(new RedisCallback<Boolean>() {
@Override
public Boolean doInRedis(RedisConnection redisConnection) throws DataAccessException {
boolean flag = false;
try {
redisTemplate.setKeySerializer(new StringRedisSerializer());
//設置序列化Value的實例化對象
redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
byte keys[] = stringRedisSerializer.serialize(key);
flag = redisConnection.expire(keys, expireTime);
} catch (Exception e) {
e.printStackTrace();
}
return flag;
}
});
}
public boolean lock(String key) {
boolean flag = false;
try {
String lockKey = generateLockKey(key);
flag = setnx(lockKey, "lock");
if (flag) {
System.out.println(expire(lockKey, Constants.Redis_Expire.DEFAULT_EXPIRE));
}
return flag;
} catch (Exception e) {
e.printStackTrace();
}
return flag;
}
public Object getValueNx(String key) {
String lockKey = generateLockKey(key);
Object object = get(lockKey);
return object;
}
public void unlock(String key) {
redisTemplate.setKeySerializer(new StringRedisSerializer());
//設置序列化Value的實例化對象
redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
String lockKey = generateLockKey(key);
RedisConnection connection = redisTemplate.getConnectionFactory().getConnection();
connection.del(lockKey.getBytes());
connection.close();
}
private String generateLockKey(String key) {
return String.format("LOCK:%s", key);
}
public boolean validate(String token) {
return exist(token);
}
}
這是一些簡單的使用,獲取,生成,更新token
@Autowired
private RedisUtils redisUtils;
@PostMapping("/setToken")
@ApiOperation(value = "設置token")
public String setToken(String token){
/*設置生成有效期*/
long time = 60;
boolean falge = redisUtils.set("token",time, token);
return falge ? "redis測試成功":"redis測試失敗";
}
@PostMapping("/getToken")
@ApiOperation(value = "獲取token")
public String getToken(String token){
Long expire = redisUtils.getExpire(token); /*獲取有效時間*/
return redisUtils.get(token).toString()+"剩餘有效時間爲:"+expire.toString();
}
@PostMapping("/updateToken")
@ApiOperation(value = "更新token")
public String updateToken(String token,String value){
if(redisUtils.exist(token)){
Long expire1 = redisUtils.getExpire(token);
if(expire1 >= 10){
return "token不允許更新";
}
String newToken = "newToken";
redisUtils.set(token,30L,value); /*設置舊token的過期時間*/
redisUtils.set(newToken,120L,value); /*設置新token的過期時間*/
return newToken; /*將新的token返回給前臺,前臺將新的token進行放入請求同頭中*/
}
Long expire = redisUtils.getExpire(token); /*獲取有效時間*/
return redisUtils.get(token).toString()+"剩餘有效時間爲:"+expire.toString();
}
到這裏就結束了,希望對大家有所幫助。如有不對,歡迎指正!