问题
在当前的性能管理系统中,系统会通过Java自带的MD5 Digest为性能指标生成一个固定的列名。
但是在测试的过程中,总是会发现有些指标生成列名失败,或者列名相同。
定位及原因
生成列名代码大概如下
private static volatile MessageDigest md5MessageDigest = null;
public static String getField(String value) throws NoSuchAlgorithmException {
if (md5MessageDigest == null) {
md5MessageDigest = MessageDigest.getInstance("MD5");
}
byte[] digestBytes = md5MessageDigest.digest(value.getBytes(StandardCharsets.UTF_8));
return toField(digestBytes);
}
public static String toField(byte[] digestBytes) {
// 实际生成比下面的复杂,仅为了演示。
return "ind_" + String(digestBytes, StandardCharsets.UTF_8);
}
MessageDigest对应的MD5 Digest实例包含了个多个非静态变量,不加锁时使用同个MD5 Digest会出现多线程问题。
系统的性能指标一般是通过Excel一次性导入,导入是并发的,所以会引发上面的问题。
解决方法
每次使用MessageDigest.getInstance获取唯一的MD5 Digest。
public static String getField(String value) throws NoSuchAlgorithmException {
MessageDigest md5MessageDigest = MessageDigest.getInstance("MD5");
byte[] digestBytes = md5MessageDigest.digest(value.getBytes(StandardCharsets.UTF_8));
return toField(digestBytes);
}
public static String toField(byte[] digestBytes) {
// 实际生成比下面的复杂,仅为了演示。
return "ind_" + String(digestBytes, StandardCharsets.UTF_8);
}