Redis缓存业务实践


通过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);


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值