Commit 8954fa72 authored by data-爬虫-任锋's avatar data-爬虫-任锋

助贷资金配置加载模块开发完成

parent 8adf88c5
package com.quantgroup.asset.distribution.constant;
import com.google.common.collect.Lists;
import com.quantgroup.asset.distribution.service.jpa.entity.AidLoanFundConfig;
import lombok.Data;
import java.util.List;
......@@ -13,5 +13,21 @@ public class FundingConstants {
/**
* 助贷资金池
*/
public final static List<AidLoanFundConfig> AID_LOAN_FUND_CONFIG_LIST = Lists.newArrayList();
public final static AidLoanFundConfigPool AID_LOAN_FUND_CONFIG_POOL = new AidLoanFundConfigPool();
@Data
public static class AidLoanFundConfigPool{
private String poolKey;
private List<AidLoanFundConfig> aidLoanFundConfigList;
//是否可用 默认下为false
private boolean enable;
}
}
......@@ -4,4 +4,10 @@ package com.quantgroup.asset.distribution.constant;
* Created by renfeng on 2019/7/22.
*/
public class RedisKeyConstants {
/**
* 助贷资金池所有key的hmset key
*/
public final static String AID_LOAN_POOLKEYS_HMSET_KEY="AID.LOAN.POOLKEYS.HMSET.KEY.8UJ2WS";
}
package com.quantgroup.asset.distribution.controller;
import com.quantgroup.asset.distribution.constant.RedisKeyConstants;
import com.quantgroup.asset.distribution.model.response.GlobalResponse;
import com.quantgroup.asset.distribution.service.redis.IRedisService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* Created by renfeng on 2019/7/22.
*/
@Slf4j
@RestController
@RequestMapping("/ex")
public class RedisFlushController {
private static String authKey="3ruhhdf9924hrodnfjkasdhf8209";
@Autowired
private IRedisService<String> redisService;
/**
* 助贷资金池刷新
* @param key
* @return
*/
@RequestMapping("/aid_loan_fund_pool_flush")
public GlobalResponse aidLoanFundPoolFlush(String key){
if(authKey.equals(key)){}
redisService.del(RedisKeyConstants.AID_LOAN_POOLKEYS_HMSET_KEY);
return GlobalResponse.success();
}
}
......@@ -3,14 +3,19 @@ package com.quantgroup.asset.distribution.service.funding.impl;
import com.quantgroup.asset.distribution.service.funding.IAidLoanFundConfigService;
import com.quantgroup.asset.distribution.service.jpa.entity.AidLoanFundConfig;
import com.quantgroup.asset.distribution.service.jpa.repository.IAidLoanFundConfigRepository;
import com.quantgroup.asset.distribution.service.redis.IRedisService;
import com.quantgroup.asset.distribution.util.UUIDUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.concurrent.TimeUnit;
import static com.quantgroup.asset.distribution.constant.FundingConstants.AID_LOAN_FUND_CONFIG_LIST;
import static com.quantgroup.asset.distribution.constant.FundingConstants.AID_LOAN_FUND_CONFIG_POOL;
import static com.quantgroup.asset.distribution.constant.RedisKeyConstants.AID_LOAN_POOLKEYS_HMSET_KEY;
/**
* Created by renfeng on 2019/7/22.
......@@ -21,6 +26,8 @@ public class AidLoanFundConfigServiceImpl implements IAidLoanFundConfigService {
@Autowired
private IAidLoanFundConfigRepository iAidLoanFundConfigRepository;
@Autowired
private IRedisService<String> redisService;
/**
* 查询全部可用助贷资金
......@@ -29,13 +36,20 @@ public class AidLoanFundConfigServiceImpl implements IAidLoanFundConfigService {
*/
@Override
public List<AidLoanFundConfig> findAll() {
if(AID_LOAN_FUND_CONFIG_LIST.size()<1) {
//助贷资金池key,存在说明有效 不存在说明失效,需要更新内存
String poolKey = AID_LOAN_FUND_CONFIG_POOL.isEnable()?redisService.hmget(AID_LOAN_POOLKEYS_HMSET_KEY, AID_LOAN_FUND_CONFIG_POOL.getPoolKey()):null;
if(StringUtils.isEmpty(poolKey)) {
List<AidLoanFundConfig> aidLoanFundConfigs = iAidLoanFundConfigRepository.findByEnableTrue();
if (CollectionUtils.isEmpty(aidLoanFundConfigs))
AID_LOAN_FUND_CONFIG_LIST.addAll(aidLoanFundConfigs);
if (CollectionUtils.isEmpty(aidLoanFundConfigs)) {
String key = UUIDUtil.getUuid();
AID_LOAN_FUND_CONFIG_POOL.setPoolKey(key);
AID_LOAN_FUND_CONFIG_POOL.setAidLoanFundConfigList(aidLoanFundConfigs);
AID_LOAN_FUND_CONFIG_POOL.setEnable(true);
//每个服务器节点上的助贷资金池poolKey都不一样,放进redis作为刷新标识
redisService.hmset(AID_LOAN_POOLKEYS_HMSET_KEY,key,key,7, TimeUnit.DAYS);
}
}
return AID_LOAN_FUND_CONFIG_LIST;
return AID_LOAN_FUND_CONFIG_POOL.getAidLoanFundConfigList();
}
/**
......
/**
*
*/
package com.quantgroup.asset.distribution.service.redis;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
*
* @author renfeng
* @date: 2017年3月30日 下午7:31:58
* @version v1.0
* @param <T>
*/
public interface IRedisService<T> {
/**
* 保存字符串
* @param key
* @param value
*/
public void setString(String key, String value);
/**
* 保存字符串 含过期时间
* @param key
* @param value
* @param time
* @param timeUnit
*/
public void setStringEx(String key, String value, long time, TimeUnit timeUnit);
/**
* 获取字符串
* @param key
* @return
*/
public String getString(String key);
/**
* 保存实体类
* @param key
* @param entity
*/
public void setEntity(String key, T entity);
public void setEntityEx(String key, T entity, long time, TimeUnit timeUnit);
/**
* 查询实体类
* @param key
* @return
*/
public T getEntity(String key);
/**
* 保存list
* @param key
* @param list
*/
public void setList(String key, List<T> list);
/**
*
* @param key
* @param list
* @param time
* @param timeUnit
*/
public void setListEx(String key, List<T> list, long time, TimeUnit timeUnit);
/**
* 查询list
* @param key
* @return
*/
public List<T> getList(String key);
/**
* 尾部追加
* @param key
* @param value
* @param time
* @param timeUnit
*/
public void rightPushEx(String key, T value, long time, TimeUnit timeUnit);
/**
* 头部移除
* @param key
*/
public T leftPop(String key);
/**
* 删除元素
* @param key
* @param value
* @param count
*/
public void listRemove(String key, T value, int count);
/**
* 保存map含过期时间
* @param key
* @param map
* @param time
* @param timeUnit
*/
public void setMapEx(String key, Map<String, T> map, long time, TimeUnit timeUnit);
/**
* 获取map
* @param key
* @return
*/
public Map<Object,Object> getMapEx(String key);
/**
* hmset
* @param key
* @param hashKey
* @param value
*/
public void hmset(String key, String hashKey, T value, long time, TimeUnit timeUnit);
/**
* hmget
* @param key
* @param hashKey
* @return
*/
public T hmget(String key, String hashKey);
/**
* 获取map长度
* @param key
* @return
*/
public Long hmgetSize(String key);
/**
* 原子性操作
* @param key
* @param time
* @param timeUnit
* @return
*/
public boolean setIfAbsent(String key, String value, long time, TimeUnit timeUnit);
/**
* 原子性自增
* @param key
* @param value
* @return
*/
public long setIncr(String key, long value, long time, TimeUnit timeUnit);
/**
* 删除
* @param key
*/
public void del(String key);
/**
* list size
* @param key
* @return
*/
public long listSize(String key);
/**
*
* @param key
* @param expireTime
* @param retryTimes 重试获取锁次数
* @param sleepMillis 休眠时间
* @return
*/
public boolean lock(String key, Long expireTime, Integer retryTimes, Long sleepMillis);
/**
* 默认尝试1次
* @param key
* @param expireTime
* @return
*/
public boolean lock(String key, Long expireTime);
/**
* 释放锁
* @param key
* @return
*/
public boolean releaseLock(String key);
}
/**
*
*/
package com.quantgroup.asset.distribution.service.redis.impl;
import com.quantgroup.asset.distribution.service.redis.IRedisService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
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.StringRedisTemplate;
import org.springframework.stereotype.Service;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisCommands;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
/**
*
* @author renfeng
* @date: 2017年3月30日 下午7:35:08
* @version v1.0
* @param <T>
* @param <T>
*/
@Service
public class RedisServiceImpl<T> implements IRedisService<T> {
private static final Logger logger = LoggerFactory.getLogger(RedisServiceImpl.class);
@Autowired
@Qualifier("redisTemplate")
private RedisTemplate<String, T> redisTemplate;
@Autowired
@Qualifier("stringRedisTemplate")
private StringRedisTemplate stringRedisTemplate;
private ThreadLocal<String> lockFlag = new ThreadLocal<String>();
public static final String UNLOCK_LUA;
static {
StringBuilder sb = new StringBuilder();
sb.append("if redis.call(\"get\",KEYS[1]) == ARGV[1] ");
sb.append("then ");
sb.append(" return redis.call(\"del\",KEYS[1]) ");
sb.append("else ");
sb.append(" return 0 ");
sb.append("end ");
UNLOCK_LUA = sb.toString();
}
@Override
public void setString(String key, String value) {
try{
stringRedisTemplate.opsForValue().set(key, value);
}catch(Exception e){
logger.error("REDIS保存String异常!",e);
}
}
@Override
public void setStringEx(String key, String value, long time, TimeUnit timeUnit) {
try{
stringRedisTemplate.opsForValue().set(key, value, time, timeUnit);
}catch(Exception e){
logger.error("REDIS保存StringEx异常!",e);
}
}
@Override
public String getString(String key) {
try{
return stringRedisTemplate.opsForValue().get(key);
}catch(Exception e){
logger.error("REDIS查询String异常!",e);
}
return null;
}
@Override
public void setEntity(String key, T entity) {
try{
redisTemplate.opsForValue().set(key, entity);
}catch(Exception e){
logger.error("REDIS保存Entity异常!",e);
}
}
@Override
public void setEntityEx(String key, T entity,long time, TimeUnit timeUnit) {
try{
redisTemplate.opsForValue().set(key, entity, time, timeUnit);
}catch(Exception e){
logger.error("REDIS保存EntityEx异常!",e);
}
}
@Override
public T getEntity(String key) {
if(StringUtils.isEmpty(key)) return null;
try{
return (T)redisTemplate.opsForValue().get(key);
}catch(Exception e){
logger.error("REDIS查询Entity异常!",e);
}
return null;
}
@Override
public void setList(String key, List<T> list) {
try{
redisTemplate.opsForList().leftPushAll(key, list);
}catch(Exception e){
logger.error("REDIS保存LIST异常!",e);
}
}
@Override
public void setListEx(String key, List<T> list,long time,TimeUnit timeUnit) {
try{
redisTemplate.opsForList().leftPushAll(key, list);
redisTemplate.expire(key, time, timeUnit);
}catch(Exception e){
logger.error("REDIS保存LISTEX异常!",e);
}
}
@Override
public List<T> getList(String key) {
try{
List<T> range = redisTemplate.opsForList().range(key, 0, 10000l);
if(range!=null && range.size()>0)
return range.parallelStream().filter(t->t!=null).collect(Collectors.toList());
}catch(Exception e){
logger.error("REDIS查询LIST异常!",e);
}
return null;
}
@Override
public boolean setIfAbsent(String key,String value,long time, TimeUnit timeUnit) {
try{
Boolean setIfAbsent = stringRedisTemplate.opsForValue().setIfAbsent(key, value);
if(setIfAbsent)
redisTemplate.expire(key, time, timeUnit);
return setIfAbsent;
}catch(Exception e){
logger.error("REDIS原子性操作异常!",e);
}
return true;
}
@Override
public long setIncr(String key, long value,long time,TimeUnit timeUnit) {
try{
Long increment = stringRedisTemplate.opsForValue().increment(key, value);
if(value!=0)
stringRedisTemplate.expire(key, time, timeUnit);
return increment;
}catch(Exception e){
logger.error("REDIS原子自增操作异常!",e);
}
return 0l;
}
@Override
public void del(String key) {
try{
redisTemplate.delete(key);
}catch(Exception e){
logger.error("REDIS删除操作异常!",e);
}
}
@Override
public void setMapEx(String key, Map<String,T> map, long time, TimeUnit timeUnit) {
try{
redisTemplate.opsForHash().putAll(key, map);
redisTemplate.expire(key, time, timeUnit);
}catch(Exception e){
logger.error("REDIS保存Map操作异常!",e);
}
}
@Override
public Map<Object, Object> getMapEx(String key) {
try{
return redisTemplate.opsForHash().entries(key);
}catch(Exception e){
logger.error("REDIS保存Map操作异常!",e);
}
return null;
}
@Override
public void hmset(String key, String hashKey, T value,long time,TimeUnit timeUnit) {
try{
redisTemplate.opsForHash().put(key, hashKey, value);
redisTemplate.expire(key, time, timeUnit);
}catch(Exception e){
logger.error("REDIS hmset操作异常!",e);
}
}
@SuppressWarnings("unchecked")
@Override
public T hmget(String key, String hashKey) {
try{
return (T) redisTemplate.opsForHash().get(key, hashKey);
}catch(Exception e){
logger.error("REDIS hmget操作异常!",e);
}
return null;
}
@Override
public Long hmgetSize(String key) {
try{
return redisTemplate.opsForHash().size(key);
}catch(Exception e){
logger.error("REDIS hmgetSize操作异常!",e);
}
return null;
}
@Override
public void rightPushEx(String key, T value,long time,TimeUnit timeUnit) {
try{
redisTemplate.opsForList().rightPush(key, value);
redisTemplate.expire(key, time, timeUnit);
}catch(Exception e){
logger.error("REDIS rightPush操作异常!",e);
}
}
@Override
public void listRemove(String key, T value, int count) {
try{
redisTemplate.opsForList().remove(key, count, value);
}catch(Exception e){
logger.error("REDIS listRemove操作异常!",e);
}
}
@Override
public T leftPop(String key) {
try{
return redisTemplate.opsForList().leftPop(key);
}catch(Exception e){
logger.error("REDIS rightPop操作异常!",e);
}
return null;
}
@Override
public long listSize(String key){
try{
return redisTemplate.opsForList().size(key);
}catch(Exception e){
logger.error("REDIS listSize操作异常!",e);
}
return 0;
}
@Override
public boolean lock(String key, Long expireTime, Integer retryTimes, Long sleepMillis) {
boolean result = setRedis(key, expireTime);
while ((!result) && retryTimes-- > 0) {
try {
TimeUnit.MILLISECONDS.sleep(sleepMillis);
} catch (InterruptedException e) {
return false;
}
result = setRedis(key, expireTime);
}
return result;
}
@Override
public boolean lock(String key, Long expireTime) {
return lock(key, expireTime, 0, 0L);
}
@Override
public boolean releaseLock(String key) {
try {
List<String> keys = new ArrayList<String>();
keys.add(key);
List<String> args = new ArrayList<String>();
args.add(lockFlag.get());
// 使用lua脚本删除redis中匹配value的key,可以避免由于方法执行时间过长而redis锁自动过期失效的时候误删其他线程的锁
// spring自带的执行脚本方法中,集群模式直接抛出不支持执行脚本的异常,所以只能拿到原redis的connection来执行脚本
Long result = redisTemplate.execute(new RedisCallback<Long>() {
public Long doInRedis(RedisConnection connection) throws DataAccessException {
Object nativeConnection = connection.getNativeConnection();
// 集群模式和单机模式虽然执行脚本的方法一样,但是没有共同的接口,所以只能分开执行
// 集群模式
if (nativeConnection instanceof JedisCluster) {
return (Long) ((JedisCluster) nativeConnection).eval(UNLOCK_LUA, keys, args);
}
// 单机模式
else if (nativeConnection instanceof Jedis) {
return (Long) ((Jedis) nativeConnection).eval(UNLOCK_LUA, keys, args);
}
return 0L;
}
});
return result != null && result > 0;
} catch (Exception e) {
logger.error("release lock occured an exception", e);
}
return false;
}
private boolean setRedis(String key, long expireTime) {
try {
String result = redisTemplate.execute(new RedisCallback<String>() {
@Override
public String doInRedis(RedisConnection connection) throws DataAccessException {
JedisCommands commands = (JedisCommands) connection.getNativeConnection();
String uuid = UUID.randomUUID().toString();
lockFlag.set(uuid);
return commands.set(key, uuid, "NX", "PX", expireTime);
}
});
return StringUtils.isNotEmpty(result);
} catch (Exception e) {
logger.error("设置redis分布式锁异常!", e);
return false;
}
}
}
......@@ -18,6 +18,14 @@ public class UUIDUtil {
public static String getAssetNo() {
return ASSET_STR + UUID.randomUUID().toString().replaceAll("-", "");
}
/**
* 获取uuid
* @return
*/
public static String getUuid(){
return UUID.randomUUID().toString().replaceAll("-", "");
}
public static void main(String[] args) {
System.out.println(getAssetNo());
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment