package com.sohu.tv.builder;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
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 org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.Protocol;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* 构造redis单机的builder;
*
* @author: lingguo
* @time: 2014/9/23 17:42
*/
public class RedisStandaloneBuilder {
private Logger logger = LoggerFactory.getLogger(RedisStandaloneBuilder.class);
private static final Lock LOCK = new ReentrantLock();
private volatile JedisPool jedisPool;
private GenericObjectPoolConfig poolConfig;
private final long appId;
private int timeout = Protocol.DEFAULT_TIMEOUT;
/**
* 构造函数package访问域,package外直接构造实例;
*
* @param appId
*/
RedisStandaloneBuilder(final long appId) {
this.appId = appId;
poolConfig = new GenericObjectPoolConfig();
poolConfig.setMaxTotal(GenericObjectPoolConfig.DEFAULT_MAX_TOTAL * 3);
poolConfig.setMaxIdle(GenericObjectPoolConfig.DEFAULT_MAX_IDLE * 2);
poolConfig.setMinIdle(GenericObjectPoolConfig.DEFAULT_MIN_IDLE);
poolConfig.setJmxEnabled(true);
poolConfig.setJmxNamePrefix("jedis-pool");
}
public JedisPool build() {
if (jedisPool == null) {
while (true) {
try {
LOCK.tryLock(100, TimeUnit.MILLISECONDS);
if (jedisPool == null) {
/**
* 心跳返回的请求为空;
*/
String response = HttpUtils.doGet(String.format(ConstUtils.REDIS_STANDALONE_URL, appId));
if (response == null || response.isEmpty()) {
logger.warn("cannot get response from server, appId={}. continue...", appId);
continue;
}
/**
* 心跳返回的请求无效;
*/
ObjectMapper mapper = new ObjectMapper();
JsonNode responseJson = null;
try {
responseJson = mapper.readTree(response);
} catch (Exception e) {
logger.error("read json from response error, appId: {}.", appId, e);
}
if (responseJson == null) {
logger.warn("invalid response, appId: {}. continue...", appId);
continue;
}
/**
* 从心跳中提取HostAndPort,构造JedisPool实例;
*/
String instance = responseJson.get("standalone").asText();
String[] instanceArr = instance.split(":");
if (instanceArr.length != 2) {
logger.warn("instance info is invalid, instance: {}, appId: {}, continue...", instance, appId);
continue;
}
//收集上报数据
// ClientDataCollectReportExecutor.getInstance();
jedisPool = new JedisPool(poolConfig, instanceArr[0], Integer.valueOf(instanceArr[1]), timeout);
return jedisPool;
}
} catch (InterruptedException e) {
logger.error("error in build().", e);
}
}
}
return jedisPool;
}
/**
* 配置
*
* @param poolConfig
* @return
*/
public RedisStandaloneBuilder setPoolConfig(GenericObjectPoolConfig poolConfig) {
this.poolConfig = poolConfig;
return this;
}
/**
*
* @param timeout 单位:毫秒
* @return
*/
public RedisStandaloneBuilder setTimeout(int timeout) {
this.timeout = timeout;
return this;
}
}