通过redis对指定信息的缓冲,适当情况下可以设置超时时间,便于自动移除,redis存储,在分布式架构中,不用关心高并发带来的线程安全问题,redis本身也可集群。
主要设置key值时要保证唯一性。
/**
* 全局配置
*
* @Time 2017-08-29
*/
@Configuration
public class GlobalConfig {
private final static int DEFAULT_TIMEOUT = 5000;
private final static int DEFAULT_MAX_ATTEMPTS = 6;
@Bean
@ConditionalOnMissingBean
public JedisCluster jedisCLuster(@Qualifier("redisPoolConfig") RedisPoolConfig redisPoolConfig) {
String[] servers = XConfProperty.get("redis.cluster.hosts").split(",");
Set<HostAndPort> nodes = new HashSet<>();
for (String server : servers) {
String[] hostAndPort = server.split(":");
nodes.add(new HostAndPort(hostAndPort[0], Integer.parseInt(hostAndPort[1])));
}
String password = XConfProperty.get("redis.cluster.password");
if (StringUtils.isEmpty(password)) {
return new JedisCluster(nodes, redisPoolConfig);
}
return new JedisCluster(nodes, DEFAULT_TIMEOUT, DEFAULT_TIMEOUT, DEFAULT_MAX_ATTEMPTS, password, redisPoolConfig);
}
@Bean
@ConditionalOnMissingBean
public RedisConnectionFactory connectionFactory() {
String[] servers = XConfProperty.get("redis.cluster.hosts").split(",");
JedisConnectionFactory factory = new JedisConnectionFactory(new RedisClusterConfiguration(Arrays.asList(servers)));
factory.setPassword(XConfProperty.get("redis.cluster.password"));
return factory;
}
@SuppressWarnings({"rawtypes", "unchecked"})
@Bean(name = "clusterRedisTemplate")
public RedisTemplate<String, String> redisTemplate() {
RedisTemplate template = new RedisTemplate();
template.setConnectionFactory(connectionFactory());
// 开启事务支持
template.setEnableTransactionSupport(true);
// 使用String格式序列化缓存键
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
template.setKeySerializer(stringRedisSerializer);
template.setHashKeySerializer(stringRedisSerializer);
// 使用json格式序列化缓存值
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
template.setValueSerializer(jackson2JsonRedisSerializer);
template.setDefaultSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
// kafka客户端初始化
@Bean
@ConditionalOnMissingBean
public KafkaConsumerClient kafkaConsumerClient() {
String topics = XConfProperty.get("kafka.consumer.topics");
return new KafkaConsumerClient(XConfProperty.getProperties(), topics);
}
// 邮件服务器kafka客户端
@Bean
@ConditionalOnMissingBean
public KafkaProducerClient kafkaProducerClient() {
return new KafkaProducerClient(XConfProperty.getProperties());
}
@Bean
@ConditionalOnMissingBean
public FileClient lixinFileClient() {
String baseUrl = XConfProperty.get("fileClient.baseURL");
String appId = XConfProperty.get("fileClient.appID");
String accessKey = XConfProperty.get("fileClient.accessKey");
FileClient fileClient = new FileClient(baseUrl, Integer.parseInt(appId), accessKey);
return fileClient;
}
@Bean
@ConditionalOnMissingBean
public RedisSequenceFactory redisSequence() {
RedisSequenceFactory factory = new RedisSequenceFactory(redisTemplate());
return factory;
}
@Bean
@ConditionalOnMissingBean
public JavaMailSender genMailSender() {
JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
mailSender.setHost(XConfProperty.get("spring.mail.host"));
mailSender.setUsername(XConfProperty.get("spring.mail.username"));
mailSender.setPassword(XConfProperty.get("spring.mail.password"));
mailSender.setDefaultEncoding(XConfProperty.get("spring.mail.default-encoding"));
return mailSender;
}
}
/**
* redis配置
* @Time 2017-08-22
*/
@ConfigurationProperties("redis.pool")
@Component("redisPoolConfig")
@Order(10)
public class RedisPoolConfig extends JedisPoolConfig {
}
package com.pohoocredit.profitcard.backend.service.impl;
import com.pohoocredit.profitcard.backend.exception.ServiceException;
import com.pohoocredit.profitcard.backend.service.RedisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import java.util.concurrent.TimeUnit;
/**
* @Author:li_shuai
* @desc:redis服务接口实现
* @date:Create in 11:51 2017/9/13
*/
@Service
public class RedisServiceImpl implements RedisService{
@Qualifier("clusterRedisTemplate")
@Autowired
private RedisTemplate clusterRedisTemplate;
@Override
public String getValueByKeyStr(String key) throws ServiceException {
ValueOperations<String, String> operations=clusterRedisTemplate.opsForValue();
return operations.get(key);
}
@Override
public Object getValueByKeyObj(String key) throws ServiceException {
ValueOperations<String, Object> operations=clusterRedisTemplate.opsForValue();
return operations.get(key);
}
@Override
public void setKeyToValueStr(String key, String value) throws ServiceException {
ValueOperations<String, String> operations=clusterRedisTemplate.opsForValue();
operations.set(key, value);
}
@Override
public void setKeyToValueObj(String key, Object value) throws ServiceException {
ValueOperations<String, Object> operations=clusterRedisTemplate.opsForValue();
operations.set(key, value);
}
@Override
public void setKeyToValue(String key, Boolean f) throws ServiceException {
ValueOperations<String, Boolean> operations = clusterRedisTemplate.opsForValue();
operations.set(key, f);
}
@Override
public void setKeyToValueTimeout(String key, Boolean f, long expireTime) throws ServiceException {
ValueOperations<String, Boolean> operations = clusterRedisTemplate.opsForValue();
operations.set(key, f, expireTime, TimeUnit.SECONDS);
}
@Override
public void setKeyToValueTimeout(String key, Boolean f, long expireTime, TimeUnit unit) throws ServiceException {
ValueOperations<String, Boolean> operations = clusterRedisTemplate.opsForValue();
operations.set(key, f, expireTime, unit);
}
@Override
public void setKeyToValueCount(String key, Integer count, long expireTime, TimeUnit unit) throws ServiceException {
ValueOperations<String, Integer> operations = clusterRedisTemplate.opsForValue();
operations.set(key, count, expireTime, unit);
}
@Override
public Boolean getValueByKey(String key) throws ServiceException {
ValueOperations<String, Boolean> operations = clusterRedisTemplate.opsForValue();
return operations.get(key);
}
@Override
public Integer getValueByKeyInt(String key) throws ServiceException {
ValueOperations<String, Integer> operations = clusterRedisTemplate.opsForValue();
return operations.get(key);
}
@Override
public void removeKey(String key) throws ServiceException {
clusterRedisTemplate.delete(key);
}
}
service服务中的realNameValidate方法实名认证调用
/**
* 认证失败的情况下,一个用户最多一天对多只能进行5次调用
* count等于null时,默认count=1,小于5时,每次加1
*/
Integer count = redisService.getValueByKeyInt(BConstants.BIND_CERTNO_COUNT + phone);
if(count==null||count<5){
count = count==null?1:++count;
redisService.setKeyToValueCount(BConstants.BIND_CERTNO_COUNT+phone,count,1, TimeUnit.DAYS);
}
//redis缓存调用结果30天,防止重复调用,缓存失败的记录结果
redisService.setKeyToValueTimeout(BConstants.NAME_IDCARD_PHONE + certNo + "_" + name, flag, 30, TimeUnit.DAYS);
controller中
//验证身份证是否重复
boolean b = liCardUserService.certNoRepeatValidate(certNo);
if (b) {
return RestResponseUtil.err(1, "身份证号【"+certNo+"】重复");
}
//判断一天是否超过5次实名
Integer count = redisService.getValueByKeyInt(BConstants.BIND_CERTNO_COUNT + user.getMobile());
if (count != null && count >= 5) {
return RestResponseUtil.err(1, "每天最多只能实名5次!");
}
//判断缓存结果,针对失败的情况
Boolean flag = redisService.getValueByKey(BConstants.NAME_IDCARD_PHONE + certNo + "_" + name);
if(flag==null){
flag = liCardUserService.realNameValidate(user.getMobile(), user.getCustId(), name, certNo);
}else{//缓存有数据
count = count==null?1:++count;
redisService.setKeyToValueCount(BConstants.BIND_CERTNO_COUNT+user.getMobile(),count,1, TimeUnit.DAYS);
}
/* //判断缓存结果
Boolean flag = redisService.getValueByKey(BConstants.NAME_IDCARD_PHONE + certNo);
//redis结果缓存为null,则第一次调用,否则直接使用缓存结果
if(flag==null){
flag = liCardUserService.realNameValidate(user.getMobile(), user.getCustId(), name, certNo);
}
Boolean flag = liCardUserService.realNameValidate(user.getMobile(), user.getCustId(), name, certNo);*/
if (flag) {
//调用反欺诈
liCardUserService.blackListValidate(user.getCustId(), user.getMobile(), certNo);
return RestResponseUtil.succ();
} else {
return RestResponseUtil.err(1, "实名认证失败,请核查后填写!");
}
存redis进行重复提交验证
if(redisService.getValueByKey(BConstants.CREDIT_SUBMIT_REPEAT+custId)!=null){ return RestResponseUtil.err(1, "请求处理中,不能重复提交"); } //设置设置redis有值 5s超时时间 redisService.setKeyToValueTimeout(BConstants.CREDIT_SUBMIT_REPEAT+custId,true,5);