diff --git a/sentinel-core/src/main/java/com/alibaba/csp/sentinel/node/metric/ExtractedMetricSearcher.java b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/node/metric/ExtractedMetricSearcher.java new file mode 100644 index 0000000000..5159ab703c --- /dev/null +++ b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/node/metric/ExtractedMetricSearcher.java @@ -0,0 +1,107 @@ +package com.alibaba.csp.sentinel.node.metric; + +import java.io.BufferedReader; +import java.io.FileInputStream; +import java.io.InputStreamReader; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.List; + +class ExtractedMetricSearcher { + /** + * avoid OOM in any case + */ + private static final int maxLinesReturn = 100000; + private Charset charset; + + public ExtractedMetricSearcher(Charset charset) { + this.charset = charset; + } + + /** + * @return if should continue read, return true, else false. + */ + boolean readMetricsInOneFileByEndTime(List list, String fileName, + long offset, long endTimeMs, String identity) throws Exception { + FileInputStream in = null; + long endSecond = endTimeMs / 1000; + try { + in = new FileInputStream(fileName); + in.getChannel().position(offset); + BufferedReader reader = new BufferedReader(new InputStreamReader(in, charset)); + String line; + while ((line = reader.readLine()) != null) { + MetricNode node = MetricNode.fromFatString(line); + long currentSecond = node.getTimestamp() / 1000; + if (currentSecond <= endSecond) { + // read all + if (identity == null) { + list.add(node); + } else if (node.getResource().equals(identity)) { + list.add(node); + } + } else { + return false; + } + if (list.size() >= maxLinesReturn) { + return false; + } + } + } finally { + if (in != null) { + in.close(); + } + } + return true; + } + + void readMetricsInOneFile(List list, String fileName, + long offset, int recommendLines) throws Exception { + //if(list.size() >= recommendLines){ + // return; + //} + long lastSecond = -1; + if (list.size() > 0) { + lastSecond = list.get(list.size() - 1).getTimestamp() / 1000; + } + FileInputStream in = null; + try { + in = new FileInputStream(fileName); + in.getChannel().position(offset); + BufferedReader reader = new BufferedReader(new InputStreamReader(in, charset)); + String line; + while ((line = reader.readLine()) != null) { + MetricNode node = MetricNode.fromFatString(line); + long currentSecond = node.getTimestamp() / 1000; + + if (list.size() < recommendLines) { + list.add(node); + } else if (currentSecond == lastSecond) { + list.add(node); + } else { + break; + } + lastSecond = currentSecond; + } + } finally { + if (in != null) { + in.close(); + } + } + } + + /** + * When identity is null, all metric between the time intervalMs will be read, otherwise, only the specific + * identity will be read. + */ + List readMetricsByEndTime(List fileNames, int pos, + long offset, long endTimeMs, String identity) throws Exception { + List list = new ArrayList(1024); + if (readMetricsInOneFileByEndTime(list, fileNames.get(pos++), offset, endTimeMs, identity)) { + while (pos < fileNames.size() + && readMetricsInOneFileByEndTime(list, fileNames.get(pos++), 0, endTimeMs, identity)) { + } + } + return list; + } +} \ No newline at end of file diff --git a/sentinel-core/src/main/java/com/alibaba/csp/sentinel/node/metric/MetricSearcher.java b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/node/metric/MetricSearcher.java index 8151d4b1c9..2c6cca7e5e 100755 --- a/sentinel-core/src/main/java/com/alibaba/csp/sentinel/node/metric/MetricSearcher.java +++ b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/node/metric/MetricSearcher.java @@ -15,12 +15,10 @@ */ package com.alibaba.csp.sentinel.node.metric; -import java.io.BufferedReader; import java.io.DataInputStream; import java.io.EOFException; import java.io.File; import java.io.FileInputStream; -import java.io.InputStreamReader; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.List; @@ -37,18 +35,13 @@ public class MetricSearcher { private static final Charset defaultCharset = Charset.forName(SentinelConfig.charset()); + private final ExtractedMetricSearcher extractedMetricSearcher; private String baseDir; private String baseFileName; - private Charset charset; private Position lastPosition = new Position(); - /** - * avoid OOM in any case - */ - private static final int maxLinesReturn = 100000; - /** * @param baseDir metric文件所在目录 * @param baseFileName metric文件名的关键字,比如 alihot-metrics.log @@ -77,7 +70,7 @@ public MetricSearcher(String baseDir, String baseFileName, Charset charset) { this.baseDir += File.separator; } this.baseFileName = baseFileName; - this.charset = charset; + extractedMetricSearcher = new ExtractedMetricSearcher(charset); } /** @@ -142,7 +135,7 @@ public synchronized List findByTimeAndResource(long beginTimeMs, lon fileName + MetricWriter.METRIC_FILE_INDEX_SUFFIX, offsetInIndex); offsetInIndex = 0; if (offset != -1) { - return readMetricsByEndTime(fileNames, i, offset, endTimeMs, identity); + return extractedMetricSearcher.readMetricsByEndTime(fileNames, i, offset, endTimeMs, identity); } } return null; @@ -198,99 +191,12 @@ private boolean validPosition(long beginTimeMs) { } } - /** - * @return if should continue read, return true, else false. - */ - private boolean readMetricsInOneFileByEndTime(List list, String fileName, - long offset, long endTimeMs, String identity) throws Exception { - FileInputStream in = null; - long endSecond = endTimeMs / 1000; - try { - in = new FileInputStream(fileName); - in.getChannel().position(offset); - BufferedReader reader = new BufferedReader(new InputStreamReader(in, charset)); - String line; - while ((line = reader.readLine()) != null) { - MetricNode node = MetricNode.fromFatString(line); - long currentSecond = node.getTimestamp() / 1000; - if (currentSecond <= endSecond) { - // read all - if (identity == null) { - list.add(node); - } else if (node.getResource().equals(identity)) { - list.add(node); - } - } else { - return false; - } - if (list.size() >= maxLinesReturn) { - return false; - } - } - } finally { - if (in != null) { - in.close(); - } - } - return true; - } - - private void readMetricsInOneFile(List list, String fileName, - long offset, int recommendLines) throws Exception { - //if(list.size() >= recommendLines){ - // return; - //} - long lastSecond = -1; - if (list.size() > 0) { - lastSecond = list.get(list.size() - 1).getTimestamp() / 1000; - } - FileInputStream in = null; - try { - in = new FileInputStream(fileName); - in.getChannel().position(offset); - BufferedReader reader = new BufferedReader(new InputStreamReader(in, charset)); - String line; - while ((line = reader.readLine()) != null) { - MetricNode node = MetricNode.fromFatString(line); - long currentSecond = node.getTimestamp() / 1000; - - if (list.size() < recommendLines) { - list.add(node); - } else if (currentSecond == lastSecond) { - list.add(node); - } else { - break; - } - lastSecond = currentSecond; - } - } finally { - if (in != null) { - in.close(); - } - } - } - private List readMetrics(List fileNames, int pos, long offset, int recommendLines) throws Exception { List list = new ArrayList(recommendLines); - readMetricsInOneFile(list, fileNames.get(pos++), offset, recommendLines); + extractedMetricSearcher.readMetricsInOneFile(list, fileNames.get(pos++), offset, recommendLines); while (list.size() < recommendLines && pos < fileNames.size()) { - readMetricsInOneFile(list, fileNames.get(pos++), 0, recommendLines); - } - return list; - } - - /** - * When identity is null, all metric between the time intervalMs will be read, otherwise, only the specific - * identity will be read. - */ - private List readMetricsByEndTime(List fileNames, int pos, - long offset, long endTimeMs, String identity) throws Exception { - List list = new ArrayList(1024); - if (readMetricsInOneFileByEndTime(list, fileNames.get(pos++), offset, endTimeMs, identity)) { - while (pos < fileNames.size() - && readMetricsInOneFileByEndTime(list, fileNames.get(pos++), 0, endTimeMs, identity)) { - } + extractedMetricSearcher.readMetricsInOneFile(list, fileNames.get(pos++), 0, recommendLines); } return list; }