您好,登錄后才能下訂單哦!
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ì)億速云的支持。
免責(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)容。