1.diamond-utils 工程里的com.taobao.diamond.common.Constants
修改成这个值
public static final String HTTP_URI_FILE = "/diamond-server/config.co";
2.创建一个类
public class DiamondClient {
public static void main(String[] str) {
DiamondManager diamondManager = new DefaultDiamondManager("one", "a",
new ManagerListener() {
public void receiveConfigInfo(String configInfo) {
System.out.println("receiveConfigInfo" + configInfo);
}
public Executor getExecutor() {
return null;
}
});
diamondManager.getDiamondConfigure().setPort(8080);
String availableConfigureInfomation = diamondManager
.getAvailableConfigureInfomation(5000);
System.out.println("diamond值" + availableConfigureInfomation);
}
}
执行这个方法就可以获得相应的数据
3.报错信息
<span style="color:#FF0000;">java.lang.RuntimeException: 获取修改过的DataID列表超时 <title>Redirect</title>, 超时时间为:10000
at com.taobao.diamond.client.impl.DefaultDiamondSubscriber.checkUpdateDataIds(DefaultDiamondSubscriber.java:871)
at com.taobao.diamond.client.impl.DefaultDiamondSubscriber.checkDiamondServerConfigInfo(DefaultDiamondSubscriber.java:317)
at com.taobao.diamond.client.impl.DefaultDiamondSubscriber.access$4(DefaultDiamondSubscriber.java:316)
at com.taobao.diamond.client.impl.DefaultDiamondSubscriber$2.run(DefaultDiamondSubscriber.java:243)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:98)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:206)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)</span>
4.错误分析
4.1当出现这个错误的时候,个人认为就是从网络获取server列表时候出错了
com.taobao.diamond.client.processor.ServerAddressProcessor
/**
* 获取diamond服务器地址列表
*
* @param acquireCount
* 根据0或1决定从日常或线上获取
* @return
*/
private boolean acquireServerAddressOnce(int acquireCount) {
HostConfiguration hostConfiguration = configHttpClient.getHostConfiguration();
String configServerAddress;
int port;
if (null != diamondConfigure.getConfigServerAddress()) {
configServerAddress = diamondConfigure.getConfigServerAddress();
port = diamondConfigure.getConfigServerPort();
}
else {
if (acquireCount == 0) {
configServerAddress = Constants.DEFAULT_DOMAINNAME;
port = Constants.DEFAULT_PORT;
}
else {
configServerAddress = Constants.DAILY_DOMAINNAME;
port = Constants.DEFAULT_PORT;
}
}
hostConfiguration.setHost(configServerAddress, port);
String serverAddressUrl = Constants.CONFIG_HTTP_URI_FILE;
HttpMethod httpMethod = new GetMethod(serverAddressUrl);
// 设置HttpMethod的参数
HttpMethodParams params = new HttpMethodParams();
params.setSoTimeout(diamondConfigure.getOnceTimeout());
// ///////////////////////
httpMethod.setParams(params);
try {
if (SC_OK == configHttpClient.executeMethod(httpMethod)) {
InputStreamReader reader = new InputStreamReader(httpMethod.getResponseBodyAsStream());
BufferedReader bufferedReader = new BufferedReader(reader);
String address = null;
List<String> newDomainNameList = new LinkedList<String>();
while ((address = bufferedReader.readLine()) != null) {
address = address.trim();
if (StringUtils.isNotBlank(address)) {
newDomainNameList.add(address);
}
}
if (newDomainNameList.size() > 0) {
log.debug("更新使用的服务器列表");
this.diamondConfigure.setDomainNameList(newDomainNameList);
return true;
}
}
else {
log.warn("没有可用的新服务器列表");
}
}
catch (HttpException e) {
log.error(getErrorMessage(configServerAddress) + ", " + e);
}
catch (IOException e) {
log.error(getErrorMessage(configServerAddress) + ", " + e);
}
catch (Exception e) {
log.error(getErrorMessage(configServerAddress) + ", " + e);
}
finally {
httpMethod.releaseConnection();
}
return false;
}返回的流是一段html代码
<html>
<script language=javascript type="text/javascript">
window.location.replace("http://bjdnserror5.wo.com.cn:8080?HOST="
+ location.hostname + "&R="
+ location.pathname + "&" + location.search.substr(location.search.indexOf("\?")+1));
</script>
<noscript>
<meta http-equiv="refresh" content="0;URL=http://bjdnserror5.wo.com.cn:8080">
</noscript>
<head>
<title>Redirect</title>
</head>
<body bgcolor="white" text="black">
</body>
</html>
5.解决方案
5.1在C:\Users\用户名称\diamond\下创建ServerAddress文件
内容是diamond-server的实例ip地址
5.2com.taobao.diamond.client.processor.ServerAddressProcessor
修改以下代码
public synchronized void start() {
if (isRun) {
return;
}
isRun = true;
initHttpClient();
if (this.diamondConfigure.isLocalFirst()) {
acquireServerAddressFromLocal();
}
else {
synAcquireServerAddress();
// asynAcquireServerAddress();
}
}
protected void synAcquireServerAddress() {
if (!isRun) {
throw new RuntimeException("ServerAddressProcessor不在运行状态,无法同步获取服务器地址列表");
}
if (MockServer.isTestMode()) {
diamondConfigure.addDomainName("测试模式,没有使用的真实服务器");
return;
}
// int acquireCount = 0;
if (diamondConfigure.getDomainNameList().size() == 0) {
reloadServerAddresses();
// if (!acquireServerAddressOnce(acquireCount)) {
// acquireCount++;
// if (acquireServerAddressOnce(acquireCount)) {
// // 存入本地文件
// storeServerAddressesToLocal();
// log.info("在同步获取服务器列表时,向日常ConfigServer服务器获取到了服务器列表");
// }
// else {
// log.info("从本地获取Diamond地址列表");
// reloadServerAddresses();
// if (diamondConfigure.getDomainNameList().size() == 0)
// throw new RuntimeException("当前没有可用的服务器列表");
// }
// }
// else {
// log.info("在同步获取服务器列表时,向线上ConfigServer服务器获取到了服务器列表");
// // 存入本地文件
// storeServerAddressesToLocal();
// }
}
}
此时应该就不会报刚才的错误信息了
本文介绍了在淘宝的Diamond客户端中进行动态配置的准备工作,包括修改diamond-utils工程的Constants值,处理报错信息,特别是针对网络获取服务器列表失败的错误进行分析,并提供了创建ServerAddress文件及修改相应代码的解决方案。
1286





