redis 的集群配置实例-短信项目有感2 短信防刷控制

1.短信防刷设置有感

我们做redis集群 可能有2种方式 :
1.使用JedisCluster
2.使用RedisTemplate

短信功能使用的是第一种

 

一定要注意 使用这些组件一定要写一个配置类将属性值注入到相应的+工具类里面,就像是 对一个jdbc连接赋值连接配置一样,特别是这种集群的配置更有点意思需要好好琢磨

这两种功能均遇到了一些问题
比如端口连不上 但是根据断点源码发现 没有加重试次数 该值一直为0,但是改成1 就解决了这个问题,接着在本地再次重启发现还是连不上 估计是本地环境问题,就发到docker2环境进行发布发现
可以正常启动

中间发生了不少问题,比如 我们在 yml 文件 写了配置之后 需要写一个 ExtProperties 类 该类上需要加一个注解
@ConfigurationProperties(prefix = "ext", ignoreInvalidFields = false)

prefix就是我们yml 配置的 大 key,如下:key 下面的每个key 是一个类,类下面的key 是属性

ext 大key,redisCluster 类 ,clusterNodes成员属性
ext:
    swagger: # swagger is enabled. It can be disabled by pasing 'no-swagger' profile at run time as well
        enabled: true
    userConfiguration:
        adminUsername: sms-admin
        apiUsername: sms-user
        adminPassword: $2a$10$ECbjM49.ZUe.YwUisEmA0.gxVMDUb81u7MqORBmKsE.Jo9PJhgYlW
        apiPassword: $2a$10$S8CPC5eM6QbNaAtyO0Im6eCKtJAVuyHXmFmemP/HUtMgV2BdduL4.
    couponMq:
        topicName: Topic_sms_prod
        tag: coupon_sms
    serviceName:
        vip: LIQUAN-VIP
    redisCluster:
        clusterNodes: 121.43.172.116:7000,121.43.172.116:7001,121.43.172.116:7002,121.43.172.116:7003,121.43.172.116:7004,121.43.172.116:7005
        commandTimeout: 5
        password: v7sxIHPkrT91
        tryNum: 1
    messageSendLimit:
        oneMinuteLimit: 1
        oneDayLimit: 5
在ExtProperties类中要么写set get 方法 要么直接实例化,就不需要写set 方法 ,但是需要写get 方法 否则获取对象报空指针


还有JedisCluster 的key-value 映射一般都是String,当然value也可以是其他格式,但是如果我们存的是字符串1、2、3 之类的 是可以直接使用jedisCluster.incr(key);方法对值加1
一开始我使用的是 jedisCluster.getSet(key, value);  发现根本没有用 过期时间和 值都是最新的 没起到防刷的作用,这个问题上栽了跟头浪费了时间


还有根据经验来谈 我们写redis 服务时最好都写一个redis 的 服务基类 不要在其他Java 代码里面直接使用 redis 类,有污染不方便维护


下面我们会将 集群的配置代码附上:

 

第一步:配置属性application-docker2.yml

ext:
    redisCluster:
        clusterNodes: 121.43.172.116:7000,121.43.172.116:7001,121.43.172.116:7002,121.43.172.116:7003,121.43.172.116:7004,121.43.172.116:7005
        commandTimeout: 5
        password: v7sxIHPkrT91
        tryNum: 1
    messageSendLimit:
        oneMinuteLimit: 1
        oneDayLimit: 5

第二步:配置属性文件

@Configuration
@ConfigurationProperties(prefix = "ext", ignoreInvalidFields = false)
public class ExtProperties {

private MessageSendLimit messageSendLimit;          // 方式一 不直接new 而是写set/get 方法
    
 private final RedisCluster redisCluster = new RedisCluster();      // 直接new 只需写get 方法

public RedisCluster getRedisCluster() {
        return redisCluster;
    }
public MessageSendLimit getMessageSendLimit() {
        return messageSendLimit;
    }
    
    public void setMessageSendLimit(MessageSendLimit messageSendLimit) {
        this.messageSendLimit = messageSendLimit;
    }

@Data
    public static class RedisCluster {

        private int        expireSeconds;
        private String    clusterNodes;
        private int        commandTimeout;
        private String    password;
        private int        timeout;
        private int        maxRedirections;
        private int        tryNum;

    }
    @Data
    public static class MessageSendLimit {
        private int    oneMinuteLimit;
        private int    oneDayLimit;   }

第三步:写redis 服务类:

@Service
@Slf4j
public class RedisService {

    @Autowired
    private JedisCluster  jedisCluster;
   
    public <T> boolean cacheObject(String key, int time ,String value) {
        try {
            jedisCluster.setex(key, time, value);
            log.info("cacheString>>> key:{}, value:{}, expire time:{}(s) success!!!", key, value, time);
            return true;
        } catch (Exception t) {
            log.error("cacheString>>> key:{}, value:{}, expire time:{}(s) error!!!", key, value, time, t);
            return false;
        }
    }

}

第四步:redis 集群配置类 ,需要加上@Configuration注解


@Configuration
public class RedisConfig {

    @Autowired
    private ExtProperties        extProperties;
    
    @Bean
    public JedisCluster getJedisCluster() {
        RedisCluster redisCluster = extProperties.getRedisCluster();
        String[] serverArray = redisCluster.getClusterNodes().split(",");
        Set<HostAndPort> nodes = new HashSet<>();

        for (String ipPort : serverArray) {
            String[] ipPortPair = ipPort.split(":");
            nodes.add(new HostAndPort(ipPortPair[0].trim(), Integer.valueOf(ipPortPair[1].trim())));
        }

        JedisPoolConfig pool = new JedisPoolConfig();
        pool.setMaxWaitMillis(3000);
        pool.setMaxTotal(3000);
        pool.setMinIdle(10);
        pool.setMaxIdle(100);

        JedisCluster jedisCluster = new JedisCluster(nodes, redisCluster.getCommandTimeout(), redisCluster.getMaxRedirections(), redisCluster.getTryNum(), redisCluster.getPassword(), pool);
        return jedisCluster;
    }
    
    @Bean
    public <V> RedisTemplate<String, V> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, V> redisTemplate = new RedisTemplate<>();
        StringRedisSerializer serializer = new StringRedisSerializer();
        redisTemplate.setConnectionFactory(factory);
        redisTemplate.setKeySerializer(serializer);
        redisTemplate.setValueSerializer(redisSerializer());
        redisTemplate.setHashKeySerializer(serializer);
        redisTemplate.setHashValueSerializer(redisSerializer());
        return redisTemplate;
    }
   
     @Bean
        public GenericJackson2JsonRedisSerializer redisSerializer() {
            ObjectMapper om = new ObjectMapper();
            om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
            om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
            om.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
            om.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
            return new GenericJackson2JsonRedisSerializer(om);
        }
    
}
 

这样就大功告成了 接着就可以在其他service类直接使用了

 

别忘了引入pom 依赖哦~ 版本号自己定

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

 

}

 

 

 

 


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值