package com.oppo.baed.ids.service.service.impl;
import com.oppo.baed.ids.service.constant.BussinessConstats;
import com.oppo.baed.ids.service.domain.MessageRecord;
import com.oppo.baed.ids.service.service.RedisService;
import com.oppo.baed.ids.service.util.DateUtil;
import com.oppo.baed.ids.service.util.FastJsonConvertUtil;
import com.oppo.basic.heracles.client.core.spring.annotation.HeraclesDynamicConfig;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import redis.clients.jedis.JedisCluster;
import java.util.Collections;
import java.util.List;
/**
* @description:Redis集群缓存处理服务
*/
@Service
public class RedisServiceImpl implements RedisService {
@Autowired
private JedisCluster jedisCluster;
//存储短信记录信息
final static String SHORT_MESSAGE_RECORD_LIST = "short_message_reocrd_list";
//用于实现分布式key
final static String SHORT_MESSAGE_DISTRIBUTED_KEY = "short_message_distributed_key";
private static final String LOCK_SUCCESS = "OK";
private static final Long RELEASE_SUCCESS = 1L;
private static final String SET_IF_NOT_EXIST = "NX";
private static final String SET_WITH_EXPIRE_TIME = "PX";
Logger logger = LogManager.getLogger(RedisServiceImpl.class.getName());
@HeraclesDynamicConfig(key = "spring.redis.prefix", fileName = "application.properties")
@Value("${spring.redis.prefix}")
private String prefix;
@Override
public Long delete(String key) {
return jedisCluster.del(prefix + key);
}
@Override
public String get(String key) {
return jedisCluster.get(prefix + key);
}
@Override
public String set(String key, String value, int ttl) {
return jedisCluster.setex(prefix + key, ttl, value);
}
@Override
public long rPush(String key,String content) {
return jedisCluster.lpush(key,content);
}
@Override
public List getShortMessageByRedis(String key, long start, long end) {
List messgeItem = null;
boolean exists = jedisCluster.exists(SHORT_MESSAGE_DISTRIBUTED_KEY);
/**
* 使用过期key和setnx模拟实现分布式锁
* key值存在 说明锁被定义,直接退出
*/
if(exists){//
System.out.println("key 值 存在");
return null;
}
else{
/**
* key不值存在,使用setnx创建锁key
*/
Long isSuccese = jedisCluster.setnx(SHORT_MESSAGE_DISTRIBUTED_KEY,"xx");
if(isSuccese==1){
//成功
System.out.println(Thread.currentThread().getName()+":锁SHORT_MESSAGE_DISTRIBUTED_KEY创建完成");
//给锁设置过期时间
jedisCluster.expire(SHORT_MESSAGE_DISTRIBUTED_KEY,10);
//获取指定范围集合元素
messgeItem = jedisCluster.lrange(key,start,end);
//删除已获取的数据
jedisCluster.ltrim(key, end+1, -1);
//释放锁
jedisCluster.del(SHORT_MESSAGE_DISTRIBUTED_KEY);
System.out.println(Thread.currentThread().getName()+":释放锁 SHORT_MESSAGE_DISTRIBUTED_KEY");
return messgeItem;
}else{
//失败
System.out.println(Thread.currentThread().getName()+":setnx创建key:SHORT_MESSAGE_DISTRIBUTED_KEY冲突");
//高并发情况下,可能会出现创建已存在的key
return null;
}
}
}
@Override
public void addToRedisShortMessage(String mobile) {
//记录发送的记录
MessageRecord messageRecord = new MessageRecord();
messageRecord.setMsgType(BussinessConstats.BussinessType.IDS.getBussType());
String timeStr = String.valueOf(System.currentTimeMillis());
timeStr = timeStr.substring(0,10);
messageRecord.setSendTime(DateUtil.timeStamp2Date(timeStr,"yyyy-MM-dd HH:mm:ss"));
messageRecord.setMobile(mobile);
System.out.println(rPush(SHORT_MESSAGE_RECORD_LIST, FastJsonConvertUtil.convertObjectToJSON(messageRecord)));
}
}
package com.oppo.baed.ids.service.service.impl;
import com.oppo.baed.ids.service.constant.BussinessConstats;
import com.oppo.baed.ids.service.domain.MessageRecord;
import com.oppo.baed.ids.service.service.RedisService;
import com.oppo.baed.ids.service.util.DateUtil;
import com.oppo.baed.ids.service.util.FastJsonConvertUtil;
import com.oppo.basic.heracles.client.core.spring.annotation.HeraclesDynamicConfig;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import redis.clients.jedis.JedisCluster;
import java.util.Collections;
import java.util.List;
/**
* @description:Redis集群缓存处理服务
*/
@Service
public class RedisServiceImpl implements RedisService {
@Autowired
private JedisCluster jedisCluster;
//存储短信记录信息
final static String SHORT_MESSAGE_RECORD_LIST = "short_message_reocrd_list";
//用于实现分布式key
final static String SHORT_MESSAGE_DISTRIBUTED_KEY = "short_message_distributed_key";
private static final String LOCK_SUCCESS = "OK";
private static final Long RELEASE_SUCCESS = 1L;
private static final String SET_IF_NOT_EXIST = "NX";
private static final String SET_WITH_EXPIRE_TIME = "PX";
Logger logger = LogManager.getLogger(RedisServiceImpl.class.getName());
@HeraclesDynamicConfig(key = "spring.redis.prefix", fileName = "application.properties")
@Value("${spring.redis.prefix}")
private String prefix;
@Override
public Long delete(String key) {
return jedisCluster.del(prefix + key);
}
@Override
public String get(String key) {
return jedisCluster.get(prefix + key);
}
@Override
public String set(String key, String value, int ttl) {
return jedisCluster.setex(prefix + key, ttl, value);
}
@Override
public long lPush(String key,String content) {
return jedisCluster.lpush(key,content);
}
@Override
public List getShortMessageByRedis(String key, long start, long end) {
List messgeItem = null;
try {
Boolean lock = lock(SHORT_MESSAGE_DISTRIBUTED_KEY,Thread.currentThread().getName(),20);
if(lock){
//获取指定范围集合元素
messgeItem = jedisCluster.lrange(key,start,end);
//删除已获取的数据
jedisCluster.ltrim(key, end+1, -1);
return messgeItem;
}
}catch (Exception e){
}finally {
unlock(SHORT_MESSAGE_DISTRIBUTED_KEY,Thread.currentThread().getName());
}
return messgeItem;
}
public boolean lock(String key, String requestId, int ttl) {
String result = jedisCluster.set(key, requestId, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, ttl);
if (LOCK_SUCCESS.equals(result)) {
return true;
}
return false;
}
public boolean unlock(String key, String requestId) {
String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
Object result = jedisCluster.eval(script, Collections.singletonList(key), Collections.singletonList(requestId));
if (RELEASE_SUCCESS.equals(result)) {
return true;
}
return false;
}
@Override
public void addToRedisShortMessage(String mobile) {
//记录发送的记录
MessageRecord messageRecord = new MessageRecord();
messageRecord.setMsgType(BussinessConstats.BussinessType.IDS.getBussType());
String timeStr = String.valueOf(System.currentTimeMillis());
timeStr = timeStr.substring(0,10);
messageRecord.setSendTime(DateUtil.timeStamp2Date(timeStr,"yyyy-MM-dd HH:mm:ss"));
messageRecord.setMobile(mobile);
System.out.println(lPush(SHORT_MESSAGE_RECORD_LIST, FastJsonConvertUtil.convertObjectToJSON(messageRecord)));
}
}
以上两种方式是经过本人实测,也是公司项目中用到的。
建议使用第二种