概述
CacheCloud,最早知道这个组件,是在《Redis开发与运维》这本书里面看到的。
GitHub,搜狐开源的一套Redis集群管理、可视化平台;
GitHub-READMEGitHub-wiki 除了GitHub站点的文档,还有停更的官方GitPage
安装
问题
appId合法性校验
背景:在我们团队维护的一个数据产品中,有个数据同步功能,如支持MySQL数据同步到Redis。然后我们的Redis集群使用的是开源的CacheCloud,不同的研发团队或部门被分配有一个全局唯一的appId。此appId即代表数据同步的源头或者目标。大致如此。
需求:校验用户输入的appId是一个合法的CacheCloud appId,否则数据同步从何谈起?
import com.ppdai.cachecloud.builder.ClientBuilder;
import com.ppdai.cachecloud.redis.clients.jedis.JedisCluster;
@Slf4j
@ProviderName(name = "redis")
public class RedisDataProvider extends DataProvider {
@Override
public void check() throws Exception {
getConnection();
}
private JedisCluster getConnection() {
long appId = Long.parseLong(dataSource.get("appId"));
return ClientBuilder.redisCluster(appId)
.setJedisPoolConfig(getPoolConfig())
.setConnectionTimeout(2000)
.setSoTimeout(1000)
.build();
}
}
maven依赖(经过我们公司二次开发修改groupId)为:
<dependency>
<groupId>com.ppdai.cachecloud</groupId>
<artifactId>cachecloud-jedis</artifactId>
<version>2.2.0</version>
</dependency>
<dependency>
<groupId>com.ppdai.cachecloud</groupId>
<artifactId>cachecloud-open-client-redis</artifactId>
<version>2.1.1</version>
</dependency>
上面的代码在appId合法时,没有任何问题。但是输入非法的appId时,报错一直停留在.build();
这一行,且是无限次的循环重试:
2021-11-19 11:46:26.806 [ERROR][http-nio-8080-exec-2]:com.ppdai.cachecloud.builder.RedisClusterBuilder [load:198] remote build error, appId: 123122
com.fasterxml.jackson.databind.exc.MismatchedInputException: No content to map due to end-of-input
at [Source: (String)""; line: 1, column: 0]
at com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:59)
at com.fasterxml.jackson.databind.ObjectMapper._initForReading(ObjectMapper.java:4666)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4511)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3466)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3434)
at com.ppdai.cachecloud.builder.RedisClusterBuilder.load(RedisClusterBuilder.java:196)
at com.ppdai.cachecloud.builder.RedisClusterBuilder.build(RedisClusterBuilder.java:123)
at com.xy.cloudiview.common.dataprovider.impl.RedisDataProvider.getConnection(RedisDataProvider.java:43)
at com.xy.cloudiview.common.dataprovider.impl.RedisDataProvider.check(RedisDataProvider.java:33)
at com.xy.cloudiview.common.services.DataProviderService.testConnection(DataProviderService.java:102)
at com.xy.cloudiview.web.controller.datasource.DataSourceController.checkDatasource(DataSourceController.java:248)
2021-11-19 11:46:26.807 [ERROR][http-nio-8080-exec-2]:com.ppdai.cachecloud.builder.RedisClusterBuilder [build:130] [status code: 404] jedis node 信息找不到
com.ctrip.framework.apollo.exceptions.ApolloConfigStatusCodeException: [status code: 404] jedis node 信息找不到
at com.ppdai.cachecloud.builder.RedisClusterBuilder.build(RedisClusterBuilder.java:124)
at com.xy.cloudiview.common.dataprovider.impl.RedisDataProvider.getConnection(RedisDataProvider.java:43)
at com.xy.cloudiview.common.dataprovider.impl.RedisDataProvider.check(RedisDataProvider.java:33)
at com.xy.cloudiview.common.services.DataProviderService.testConnection(DataProviderService.java:102)
at com.xy.cloudiview.web.controller.datasource.DataSourceController.checkDatasource(DataSourceController.java:248)
不知道是不是和建造者模式有关。即使加上try...catch{}
语句块,也不能捕获异常。。
借助于IDEA强大的源码阅读功能,最终发现源码提供有一个工具类方法CachecloudJedisFactoryUtil.getHostAndPortForStandAlone
:
private JedisCluster getConnection() throws Exception {
long appId = Long.parseLong(dataSource.get("appId"));
try {
CachecloudJedisFactoryUtil.getHostAndPortForStandAlone(dataSource.get("appId"));
} catch (IllegalArgumentException e) {
throw new Exception(e.getMessage());
}
return ClientBuilder.redisCluster(appId)
.setJedisPoolConfig(getPoolConfig())
.setConnectionTimeout(2000)
.setSoTimeout(1000)
.build();
}
需要加入一个依赖:
<dependency>
<groupId>com.ppdai.cachecloud</groupId>
<artifactId>cachecloud-spring-boot-apollo</artifactId>
<version>2.1.1</version>
</dependency>