溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

springboot中如何接入cachecloudredis

發(fā)布時(shí)間:2021-06-23 16:32:45 來(lái)源:億速云 閱讀:253 作者:Leah 欄目:編程語(yǔ)言

springboot中如何接入cachecloudredis,很多新手對(duì)此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來(lái)學(xué)習(xí)下,希望你能有所收獲。

java項(xiàng)目中 接入 CacheCloud redis的方式主要有兩種。

第一種就是在 CacheCloud 上創(chuàng)建好redis實(shí)例后將對(duì)應(yīng)的IP,端口直接配置以配置形式應(yīng)用到項(xiàng)目中,優(yōu)點(diǎn)是通用性好,原有項(xiàng)目改造成本低,不過(guò)萬(wàn)一后期CacheCloud上對(duì)redis進(jìn)行管理擴(kuò)容,那只能手動(dòng)把每個(gè)項(xiàng)目的redis配置都改一遍了。

第二種CacheCloud 上創(chuàng)建好實(shí)例后有一個(gè)對(duì)應(yīng)的appId,程序調(diào)用CacheCloud 平臺(tái)的rest接口通過(guò) appId獲取redis相關(guān)配置,將程序中的redis配置 統(tǒng)一交給CacheCloud平臺(tái)去管理維護(hù),后期管理和擴(kuò)容及其方便,不過(guò)程序改造成本比較高。

現(xiàn)在采用第二種方式接入,工程采用springboot,redis采用哨兵模式,redis客戶端主要用spring-data-redis和redisson,  接入流程如下:

添加配置到pom.xml文件

<!--cachecloud 相關(guān)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>

準(zhǔn)備配置文件 cacheCloudClient.properties,啟動(dòng)項(xiàng)目時(shí) VM參數(shù)追加 -Dcachecloud.config= 配置文件路徑

http_conn_timeout = 3000http_socket_timeout = 5000client_version = 1.0-SNAPSHOTdomain_url = http://192.168.33.221:8585  #cachecloud實(shí)際路徑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

基本思路是先通過(guò)cachecloud的restapi接口獲取并解析redis節(jié)點(diǎn)的配置信息,然后就可以按照傳統(tǒng)的訪問(wèn)redis的方式進(jìn)行初始化,獲取RedisTemplate對(duì)象。

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);   /**   * 構(gòu)建鎖   */  private static final Lock LOCK = new ReentrantLock();   @Value("${cacheCloud.appId}") //cahcecloud 開通redis實(shí)例 應(yīng)用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請(qǐng)求返回的結(jié)果是空的;           */          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請(qǐng)求返回的結(jié)果是無(wú)效的;           */          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);          }           /**           * 有效的請(qǐng)求:取出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]));            }          }           //收集上報(bào)數(shù)據(jù)          if (clientStatIsOpen) {            ClientDataCollectReportExecutor.getInstance();          }          password = jsonObject.getString("password");          getConfigSuccess = true;          return;        }      } catch (Throwable e) {//容錯(cuò)        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();    // 最大空閑數(shù)    jedisPoolConfig.setMaxIdle(20);    // 連接池的最大數(shù)據(jù)庫(kù)連接數(shù)    jedisPoolConfig.setMaxTotal(20);    // 最大建立連接等待時(shí)間    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);    // 設(shè)置值(value)的序列化采用FastJsonRedisSerializer。    template.setValueSerializer(fastJsonRedisSerializer);    template.setHashValueSerializer(fastJsonRedisSerializer);    // 設(shè)置鍵(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);  }}

看完上述內(nèi)容是否對(duì)您有幫助呢?如果還想對(duì)相關(guān)知識(shí)有進(jìn)一步的了解或閱讀更多相關(guān)文章,請(qǐng)關(guān)注億速云行業(yè)資訊頻道,感謝您對(duì)億速云的支持。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI