Skip to content

Commit

Permalink
Fix data rigorous. (sofastack#356)
Browse files Browse the repository at this point in the history
  • Loading branch information
leizhiyuan authored and ujjboy committed Nov 30, 2018
1 parent 6484b57 commit 0f6f528
Show file tree
Hide file tree
Showing 3 changed files with 133 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,9 @@ public class LocalRegistry extends Registry {
protected Map<String, List<ConsumerConfig>> notifyListeners = new ConcurrentHashMap<String, List<ConsumerConfig>>();

/**
* 最后一次扫描文件时间
* 最后一次digest值
*/
private long lastLoadTime;
private String lastDigest;

/**
* 扫描周期,毫秒
Expand Down Expand Up @@ -116,7 +116,7 @@ public void init() {
throw new SofaRpcRuntimeException("File of LocalRegistry is null");
}
// 先加载一些
lastLoadTime = LocalRegistryHelper.loadBackupFileToCache(regFile, memoryCache);
lastDigest = LocalRegistryHelper.calMD5Checksum(regFile);
// 开始扫描
this.scanPeriod = CommonUtils.parseInt(registryConfig.getParameter("registry.local.scan.period"),
scanPeriod);
Expand All @@ -128,18 +128,17 @@ public void run() {
doWriteFile();

// 订阅变化(默认是不订阅的)
// 检查最后修改时间,如果有有变,则自动重新加载
if (subscribe && LocalRegistryHelper.checkModified(regFile, lastLoadTime)) {
// 检查摘要,如果有有变,则自动重新加载
if (subscribe && LocalRegistryHelper.checkModified(regFile, lastDigest)) {
// 加载到内存
Map<String, ProviderGroup> tempCache = new ConcurrentHashMap<String, ProviderGroup>();
long currentTime = LocalRegistryHelper.loadBackupFileToCache(regFile, tempCache);
Map<String, ProviderGroup> tempCache = LocalRegistryHelper.loadBackupFileToCache(regFile);
// 比较旧列表和新列表,通知订阅者变化部分
notifyConsumer(tempCache);

// 通知完保存到内存
memoryCache = tempCache;
// 如果有文件更新,将上一次更新时间保持为当前时间
lastLoadTime = currentTime;
lastDigest = LocalRegistryHelper.calMD5Checksum(regFile);
}
} catch (Throwable e) {
LOGGER.error(e.getMessage(), e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,17 +35,20 @@
import com.alipay.sofa.rpc.log.Logger;
import com.alipay.sofa.rpc.log.LoggerFactory;

import javax.xml.bind.DatatypeConverter;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
* Util method of local registry.
Expand All @@ -60,16 +63,16 @@ public class LocalRegistryHelper {
private static final Logger LOGGER = LoggerFactory.getLogger(LocalRegistryHelper.class);

/**
* Check file's lastmodified.
* Check file's digest.
*
* @param address the address
* @param updateDate the update date
* @param lastDigest the update digest
* @return true被修改,false未被修改
*/
public static boolean checkModified(String address, long updateDate) {
public static boolean checkModified(String address, String lastDigest) {
// 检查文件是否被修改了
File xmlFile = new File(address);
return xmlFile.lastModified() > updateDate;
String newDigest = calMD5Checksum(address);
return StringUtils.equals(newDigest, lastDigest);
}

/**
Expand All @@ -94,7 +97,9 @@ public static ProviderInfo convertProviderToProviderInfo(ProviderConfig config,
return providerInfo;
}

static long loadBackupFileToCache(String address, Map<String, ProviderGroup> memoryCache) {
static Map<String, ProviderGroup> loadBackupFileToCache(String address) {

Map<String, ProviderGroup> memoryCache = new ConcurrentHashMap<String, ProviderGroup>();
// 从文件夹下读取指定文件
File regFile = new File(address);
if (!regFile.exists()) {
Expand All @@ -116,7 +121,7 @@ static long loadBackupFileToCache(String address, Map<String, ProviderGroup> mem
throw new SofaRpcRuntimeException("Error when read backup file: " + regFile.getAbsolutePath(), e);
}
}
return RpcRuntimeContext.now();
return memoryCache;
}

static synchronized boolean backup(String address, Map<String, ProviderGroup> memoryCache) {
Expand Down Expand Up @@ -268,4 +273,38 @@ static String buildListDataId(AbstractInterfaceConfig config, String protocol) {
return ConfigUniqueNameGenerator.getUniqueName(config) + "@" + protocol;
}
}

private static byte[] createChecksum(String filename) {
MessageDigest complete = null;
try {
complete = MessageDigest.getInstance("MD5");
} catch (Exception e) {
//ignore
}
String content = null;
try {
final File file = new File(filename);
content = FileUtils.file2String(file);
} catch (IOException e) {
//ignore
}

if (content == null) {
content = "";
}
byte[] digest = new byte[0];

if (complete != null) {
digest = complete.digest(content.getBytes());
}

return digest;
}

public static String calMD5Checksum(String filename) {
byte[] b;
b = createChecksum(filename);
String digestInHex = DatatypeConverter.printHexBinary(b).toUpperCase();
return digestInHex;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alipay.sofa.rpc.registry.local;

import com.alipay.sofa.rpc.common.utils.FileUtils;
import org.junit.Assert;
import org.junit.Test;

import java.io.File;
import java.io.IOException;
import java.util.Random;

/**
* @author bystander
* @version $Id: LocalRegistryHelperTest.java, v 0.1 2018年11月07日 11:34 AM bystander Exp $
*/
public class LocalRegistryHelperTest {

private static String filePath = System.getProperty("user.home") + File.separator
+ "localFileTest"
+ new Random().nextInt(1000);

@Test
public void testModify() {

final File file = new File(filePath);
FileUtils.cleanDirectory(file);

try {
FileUtils.string2File(file, "a");
} catch (IOException e) {
e.printStackTrace();
}

String oldDigest = LocalRegistryHelper.calMD5Checksum(filePath);

try {
FileUtils.string2File(file, "b");
} catch (IOException e) {
e.printStackTrace();
}

String newDigest = LocalRegistryHelper.calMD5Checksum(filePath);

Assert.assertNotSame("digest不能一样", oldDigest, newDigest);
}

@Test
public void testNotModify() {

final File file = new File(filePath);
FileUtils.cleanDirectory(file);

try {
FileUtils.string2File(file, "a");
} catch (IOException e) {
e.printStackTrace();
}

String oldDigest = LocalRegistryHelper.calMD5Checksum(filePath);

String newDigest = LocalRegistryHelper.calMD5Checksum(filePath);

Assert.assertEquals("digest不一样", oldDigest, newDigest);
}
}

0 comments on commit 0f6f528

Please sign in to comment.