Skip to content

Instantly share code, notes, and snippets.

@yangl
Created August 16, 2013 07:28
Show Gist options
  • Save yangl/6247974 to your computer and use it in GitHub Desktop.
Save yangl/6247974 to your computer and use it in GitHub Desktop.
将远程配置中心配置通过Dubbo RPC远程调用保存至本地客户端JVM,这是之前做服务治理时的部分代码;
package com.jd.market.servicemanagement.token.collect;
import java.io.File;
import java.util.Calendar;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.base.Strings;
import com.google.common.io.Files;
import com.jd.market.servicemanagement.token.common.Constants;
import com.jd.market.servicemanagement.token.configinfo.SystemModel;
import com.jd.market.servicemanagement.token.utils.JsonMapper;
import com.jd.market.servicemanagement.token.utils.JsonMappers;
/**
*
* 系统启动时将本地配置存至jvm
*
* @author YANGLiiN
* @date 13-4-27 下午2:42
*/
public class FileToJvm {
private static final Logger logger = LoggerFactory.getLogger(FileToJvm.class);
// 从本地配置文件加载数据至jvm
public void toJvm(String system, File confJson) throws Exception {
SystemModel local;
String content = Files.toString(confJson, Constants.DEFAULT_CHARSET);
if (!Strings.isNullOrEmpty(content)) {
JsonMapper mapper = JsonMappers.get();
local = mapper.getMapper().readValue(confJson, SystemModel.class);
if (local != null
&& !Strings.isNullOrEmpty(local.getSystem())
&& system.equals(local.getSystem())
&& local.getLastLogId() > 0) {
logger.info("********从本地配置文件加载数据至jvm,内容如下[{}]**********", content);
JvmLocalData.cache = local;
JvmLocalData.lastModified = Calendar.getInstance().getTime();
}
}
}
}
package com.jd.market.servicemanagement.token.collect;
import java.io.File;
import java.io.IOException;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.dubbo.common.utils.NamedThreadFactory;
import com.jd.market.servicemanagement.client.domain.Operate;
import com.jd.market.servicemanagement.client.domain.OperateLogQueryResult;
import com.jd.market.servicemanagement.client.service.ServiceManagementOperateLogService;
import com.jd.market.servicemanagement.token.common.AccessStateEnum;
import com.jd.market.servicemanagement.token.common.Constants;
import com.jd.market.servicemanagement.token.common.DegradeTypeEnum;
import com.jd.market.servicemanagement.token.common.OperateTypeEnum;
import com.jd.market.servicemanagement.token.configinfo.MethodModel;
import com.jd.market.servicemanagement.token.configinfo.SystemModel;
import com.jd.market.servicemanagement.token.configinfo.TokenModel;
import com.jd.market.servicemanagement.token.utils.JsonMapper;
import com.jd.market.servicemanagement.token.utils.JsonMappers;
/**
* 将服务端配置保存至客户端
*
* @author YANGLiiN
* @date 13-4-27 下午4:17
*/
public class RemoteToLocal {
private static final Logger logger = LoggerFactory.getLogger(RemoteToLocal.class);
// saf 服务
private ServiceManagementOperateLogService operateLogService;
public void collectScheduled(final String system,
final File confJson,
long initialDelay,
long delay) {
ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(new NamedThreadFactory("remoteToLocal",
true));
// 启动同步数据定时器
scheduledExecutorService.scheduleWithFixedDelay(new Runnable() {
public void run() {
// 同步数据
try {
logger.info("*********开始收集数据*********");
collect(system, confJson);
logger.info("*********收集数据结束*********");
}
catch (Throwable t) { // 防御性容错
logger.error("Unexpected error occur at send statistic, cause: "
+ t.getMessage(),
t);
}
}
},
initialDelay,
delay,
TimeUnit.MILLISECONDS);
}
// 将远程配置加载至本地:json配置文件与jvm
public void collect(String system, File confJson) throws IOException {
Map<String, MethodModel> methods = new HashMap<String, MethodModel>();
boolean hasMore;
int lastLogId = JvmLocalData.cache == null ? 0 : JvmLocalData.cache.getLastLogId();
long startTime = System.currentTimeMillis();
do {
// 先拷贝一份暫存
if (JvmLocalData.cache != null && JvmLocalData.cache.getMethods() != null) {
methods = new HashMap<String, MethodModel>(JvmLocalData.cache.getMethods());
}
OperateLogQueryResult rs = operateLogService.queryOperateLog(system, lastLogId);
logger.info("*******获取远程数据[{}]********", JsonMappers.get().toJson(rs));
hasMore = rs.hasMore;
if (rs != null && rs.getOperateList() != null) {
List<Operate> operates = rs.getOperateList();
for (Operate op : operates) {
lastLogId = op.getLogId();
int accessState = op.getAccessState();
String methodName = op.getMethodName();
MethodModel methodModel = methods.get(methodName);
OperateTypeEnum operateTypeEnum = OperateTypeEnum.toOperateTypeEnum(op.getOpType());
switch (operateTypeEnum) {
// token对应某方法访问权限变更
case TOKEN:
String tokenStr = op.getTokenStr();
String[] token = tokenStr.split(Constants.TOKEN_SPLIT);
if (token != null && token.length == 2) {
String clientId = token[0];
String clientSecret = token[1];
Map<String, TokenModel> tokenModels = methodModel.getTokens();
AccessStateEnum accessStateEnum = AccessStateEnum.toAccessStateEnum(accessState);
switch (accessStateEnum) {
case FORBIDDEN:
if (tokenModels != null) {
tokenModels.remove(clientId);
}
break;
case ENABLED:
if (tokenModels == null) {
tokenModels = new HashMap<String, TokenModel>();
}
TokenModel tokenModel = new TokenModel(clientId, clientSecret);
tokenModels.put(clientId, tokenModel);
break;
default:
break;
}
methodModel.setTokens(tokenModels);
}
break;
// 添加/修改方法
case METHOD:
MethodModel mu = new MethodModel();
mu.setMethodName(methodName);
mu.setStatus(accessState);
mu.setDegradeType(DegradeTypeEnum.toDegradeTypeEnum(op.getDegradeWay()));
mu.setMockContent(op.getDegradeContent());
mu.setMockMd5(op.getDegradeContentMd5());
// 如果是修改就得加上之前设置的tokens
if (methodModel != null
&& methodModel.getTokens() != null
&& !methodModel.getTokens().isEmpty()) {
mu.setTokens(methodModel.getTokens());
}
methods.put(methodName, mu);
break;
// 未知操作
default:
break;
}
}
}
} while (hasMore);
// guava stopwathch 11与14 api有变化
logger.info("*********同步远程数据耗时[{} ms]**********", System.currentTimeMillis() - startTime);
// 有数据更新的时候才写文件及更新jvm数据
if (lastLogId > (JvmLocalData.cache == null ? 0 : JvmLocalData.cache.getLastLogId())) {
SystemModel model = new SystemModel();
model.setSystem(system);
model.setLastLogId(lastLogId);
model.setMethods(methods);
JsonMapper mapper = JsonMappers.get();
mapper.getMapper().writeValue(confJson, model);
// 设置数据
JvmLocalData.cache = model;
JvmLocalData.lastModified = Calendar.getInstance().getTime();
logger.info("*********加载远程数据至本地confJson/jvm[{}]**********", mapper.toJson(model));
}
}
// --------- getter setter ----------
public ServiceManagementOperateLogService getOperateLogService() {
return operateLogService;
}
public void setOperateLogService(ServiceManagementOperateLogService operateLogService) {
this.operateLogService = operateLogService;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment