温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

springboot中如何接入cachecloudredis

发布时间:2021-06-23 16:32:45 来源:亿速云 阅读:232 作者:Leah 栏目:编程语言

springboot中如何接入cachecloudredis,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。

java项目中 接入 CacheCloud redis的方式主要有两种。

第一种就是在 CacheCloud 上创建好redis实例后将对应的IP,端口直接配置以配置形式应用到项目中,优点是通用性好,原有项目改造成本低,不过万一后期CacheCloud上对redis进行管理扩容,那只能手动把每个项目的redis配置都改一遍了。

第二种CacheCloud 上创建好实例后有一个对应的appId,程序调用CacheCloud 平台的rest接口通过 appId获取redis相关配置,将程序中的redis配置 统一交给CacheCloud平台去管理维护,后期管理和扩容及其方便,不过程序改造成本比较高。

现在采用第二种方式接入,工程采用springboot,redis采用哨兵模式,redis客户端主要用spring-data-redis和redisson,  接入流程如下:

添加配置到pom.xml文件

<!--cachecloud 相关jar包-->    <dependency>      <groupId>com.sohu.tv</groupId>      <artifactId>cachecloud-open-client-redis</artifactId>      <version>1.0-SNAPSHOT</version>    </dependency>     <dependency>      <groupId>com.sohu.tv</groupId>      <artifactId>cachecloud-open-client-basic</artifactId>      <version>1.0-SNAPSHOT</version>    </dependency>     <dependency>      <groupId>com.sohu.tv</groupId>      <artifactId>cachecloud-open-common</artifactId>      <version>1.0-SNAPSHOT</version>    </dependency>    <!--spring redis 和 redisson-->     <dependency>      <groupId>org.springframework.boot</groupId>      <artifactId>spring-boot-starter-data-redis</artifactId>      <exclusions>        <exclusion>          <artifactId>jedis</artifactId>          <groupId>redis.clients</groupId>        </exclusion>      </exclusions>    </dependency>    <dependency>      <groupId>org.redisson</groupId>      <artifactId>redisson</artifactId>      <version>3.9.0</version>    </dependency>

准备配置文件 cacheCloudClient.properties,启动项目时 VM参数追加 -Dcachecloud.config= 配置文件路径

http_conn_timeout = 3000http_socket_timeout = 5000client_version = 1.0-SNAPSHOTdomain_url = http://192.168.33.221:8585  #cachecloud实际路径redis_cluster_suffix = /cache/client/redis/cluster/%s.json?clientVersion=redis_sentinel_suffix = /cache/client/redis/sentinel/%s.json?clientVersion=redis_standalone_suffix = /cache/client/redis/standalone/%s.json?clientVersion=cachecloud_report_url = /cachecloud/client/reportData.json

基本思路是先通过cachecloud的restapi接口获取并解析redis节点的配置信息,然后就可以按照传统的访问redis的方式进行初始化,获取RedisTemplate对象。

java代码如下:

import com.alibaba.fastjson.JSONObject;import com.sohu.tv.cachecloud.client.basic.heartbeat.ClientStatusEnum;import com.sohu.tv.cachecloud.client.basic.util.ConstUtils;import com.sohu.tv.cachecloud.client.basic.util.HttpUtils;import com.sohu.tv.cachecloud.client.jedis.stat.ClientDataCollectReportExecutor;import lombok.Getter;import lombok.Setter;import org.apache.commons.lang3.tuple.Pair;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Value;import org.springframework.stereotype.Component; import javax.annotation.PostConstruct;import java.util.HashSet;import java.util.Random;import java.util.Set;import java.util.concurrent.TimeUnit;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock; @Componentpublic class RedisProperties {   public static Logger logger = LoggerFactory.getLogger(RedisProperties.class);   /**   * 构建锁   */  private static final Lock LOCK = new ReentrantLock();   @Value("${cacheCloud.appId}") //cahcecloud 开通redis实例 应用id  private Integer appId;   @Getter  @Setter  private String masterName;   @Getter  @Setter  private Set<Pair<String, String>> sentinelSet = new HashSet<>();   private Boolean clientStatIsOpen=true;   @Getter  @Setter  private String password;   private Boolean getConfigSuccess = false;   @PostConstruct  public void init() {     while (true) {      try {        LOCK.tryLock(10, TimeUnit.MILLISECONDS);        if (!getConfigSuccess) {          /**           * http请求返回的结果是空的;           */          String response = HttpUtils.doGet(String.format(ConstUtils.REDIS_SENTINEL_URL, appId));          if (response == null || response.isEmpty()) {            logger.warn("get response from remote server error, appId: {}, continue...", appId);            continue;          }           /**           * http请求返回的结果是无效的;           */          JSONObject jsonObject = null;          try {            jsonObject = JSONObject.parseObject(response);          } catch (Exception e) {            logger.error("heartbeat error, appId: {}. continue...", appId, e);          }          if (jsonObject == null) {            logger.error("get sentinel info for appId: {} error. continue...", appId);            continue;          }          int status = jsonObject.getIntValue("status");          String message = jsonObject.getString("message");           /** 检查客户端版本 **/          if (status == ClientStatusEnum.ERROR.getStatus()) {            throw new IllegalStateException(message);          } else if (status == ClientStatusEnum.WARN.getStatus()) {            logger.warn(message);          } else {            logger.info(message);          }           /**           * 有效的请求:取出masterName和sentinels;           */          masterName = jsonObject.getString("masterName");          String sentinels = jsonObject.getString("sentinels");          for (String sentinelStr : sentinels.split(" ")) {            String[] sentinelArr = sentinelStr.split(":");            if (sentinelArr.length == 2) {              sentinelSet.add(Pair.of(sentinelArr[0], sentinelArr[1]));            }          }           //收集上报数据          if (clientStatIsOpen) {            ClientDataCollectReportExecutor.getInstance();          }          password = jsonObject.getString("password");          getConfigSuccess = true;          return;        }      } catch (Throwable e) {//容错        logger.error("error in build, appId: {}", appId, e);      } finally {        LOCK.unlock();      }      try {        TimeUnit.MILLISECONDS.sleep(200 + new Random().nextInt(1000));//活锁      } catch (InterruptedException e) {        logger.error(e.getMessage(), e);      }    }  }}

import com.shunwang.buss.dispatchPay.provider.config.PropertiesUtil;import org.apache.commons.lang3.StringUtils;import org.redisson.Redisson;import org.redisson.api.RedissonClient;import org.redisson.config.Config;import org.redisson.config.ReadMode;import org.redisson.config.SentinelServersConfig;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.Primary;import org.springframework.data.redis.connection.RedisConnectionFactory;import org.springframework.data.redis.connection.RedisNode;import org.springframework.data.redis.connection.RedisSentinelConfiguration;import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;import org.springframework.data.redis.core.RedisTemplate;import org.springframework.data.redis.serializer.StringRedisSerializer;import redis.clients.jedis.JedisPoolConfig; import java.net.UnknownHostException;import java.util.List;import java.util.Set;import java.util.stream.Collectors; import static java.util.stream.Collectors.toList;  @Configurationpublic class RedisConfig {   /**   * JedisPoolConfig 连接池   */  @Bean  public JedisPoolConfig jedisPoolConfig(RedisProperties properties) {    JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();    // 最大空闲数    jedisPoolConfig.setMaxIdle(20);    // 连接池的最大数据库连接数    jedisPoolConfig.setMaxTotal(20);    // 最大建立连接等待时间    jedisPoolConfig.setMaxWaitMillis(3000);    return jedisPoolConfig;  }   /**   * 配置redis的哨兵   */  @Bean  public RedisSentinelConfiguration sentinelConfiguration(RedisProperties properties) {    RedisSentinelConfiguration redisSentinelConfiguration = new RedisSentinelConfiguration();    // 配置redis的哨兵sentinel    Set<RedisNode> redisNodeSet = properties.getSentinelSet().stream()        .map(pair -> new RedisNode(pair.getLeft(), Integer.parseInt(pair.getRight())))        .collect(Collectors.toSet());    redisSentinelConfiguration.setSentinels(redisNodeSet);    redisSentinelConfiguration.setMaster(properties.getMasterName());    return redisSentinelConfiguration;  }   /**   * 配置工厂   */  @Bean  public RedisConnectionFactory jedisConnectionFactory(JedisPoolConfig jedisPoolConfig, RedisSentinelConfiguration sentinelConfig) {    JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(sentinelConfig, jedisPoolConfig);    return jedisConnectionFactory;  }    @Bean  public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory)      throws UnknownHostException {    RedisTemplate template = new RedisTemplate();    template.setConnectionFactory(redisConnectionFactory);    FastJsonRedisSerializer<Object> fastJsonRedisSerializer = new FastJsonRedisSerializer<>(Object.class);    // 设置值(value)的序列化采用FastJsonRedisSerializer。    template.setValueSerializer(fastJsonRedisSerializer);    template.setHashValueSerializer(fastJsonRedisSerializer);    // 设置键(key)的序列化采用StringRedisSerializer。    template.setKeySerializer(new StringRedisSerializer());    template.setHashKeySerializer(new StringRedisSerializer());    template.afterPropertiesSet();    return template;  }   /**   * Redisson 配置   */  @Bean  public RedissonClient redissonClient(RedisProperties properties) {    Config config = new Config();    List<String> newNodes = properties.getSentinelSet().stream()        .map(pa -> "redis://" + pa.getLeft() + ":" + pa.getRight()).collect(toList());    SentinelServersConfig serverConfig = config.useSentinelServers()        .addSentinelAddress(newNodes.toArray(new String[newNodes.size()]))        .setMasterName(properties.getMasterName())        .setReadMode(ReadMode.SLAVE);     if (StringUtils.isNotBlank(properties.getPassword())){      serverConfig.setPassword(properties.getPassword());    }    return Redisson.create(config);  }}

看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注亿速云行业资讯频道,感谢您对亿速云的支持。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI