Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feature] Expose jmx endpoint for sentinel. #2275

Merged
merged 34 commits into from
Sep 15, 2021
Merged
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
9f296ef
expose the MetricNode AS MBean
brotherlu-xcq Dec 31, 2020
a163bac
add the notes
brotherlu-xcq Jan 4, 2021
c78ef02
expose the MetricNode as the jmx bean
brotherlu-xcq Jan 5, 2021
024241d
Merge branches 'feature-#1848' and 'master' of https://github.com/bro…
brotherlu-xcq Jan 5, 2021
afb0123
integration test for MBean
brotherlu-xcq Jan 5, 2021
cc4a7d0
rename the class and add the notes
brotherlu-xcq Jan 5, 2021
3d55d71
perfect the notes
brotherlu-xcq Jan 6, 2021
fd1c3f7
solve the thread-safe issue
brotherlu-xcq Jan 18, 2021
840f9fc
add notes in MetricMXBean
brotherlu-xcq Jan 18, 2021
72e4604
current the collect issue of JMX
brotherlu-xcq Jan 21, 2021
d7e80e2
fix the blockQps data issue
brotherlu-xcq Jan 21, 2021
3316cd3
change the unit of period in metricMbeanListener
brotherlu-xcq Jan 21, 2021
752b697
add the MBean register log
brotherlu-xcq Jan 22, 2021
5c49633
add Listener log
brotherlu-xcq Jan 26, 2021
46eb451
make the mbean listener flush interval configurable
brotherlu-xcq Feb 2, 2021
0977c0a
Merge branch 'master' of https://github.com/alibaba/Sentinel into fea…
brotherlu-xcq Jul 1, 2021
1740381
Jmx exporter optimize.
brotherlu-xcq Jul 1, 2021
f27d1c8
Jmx exporter optimize, add notes.
brotherlu-xcq Jul 1, 2021
b118345
test and add unit test.
brotherlu-xcq Jul 1, 2021
f0c84d3
add classification.
brotherlu-xcq Jul 2, 2021
ecab855
write bug fixes.
brotherlu-xcq Jul 2, 2021
1cc344b
fix javadoc.
brotherlu-xcq Jul 2, 2021
3883d89
remove the old implement.
brotherlu-xcq Jul 2, 2021
4eb0e1b
remove the wrong import.
brotherlu-xcq Jul 2, 2021
cd5723e
fix ci issue.
brotherlu-xcq Jul 2, 2021
fad02c6
change the name of thread.
brotherlu-xcq Jul 2, 2021
b702923
[ISSUE #1848] change the code after review.
brotherlu-xcq Sep 8, 2021
1e91589
[ISSUE #1848] fix ci.
brotherlu-xcq Sep 8, 2021
8c6b926
[ISSUE #1848] fix ci.
brotherlu-xcq Sep 8, 2021
b1b40cf
[ISSUE #1848] fix ci.
brotherlu-xcq Sep 8, 2021
115b54c
Merge branches 'feature-#1848-new' and 'master' of https://github.com…
brotherlu-xcq Sep 9, 2021
556e064
[ISSUE #1848] change the version.
brotherlu-xcq Sep 9, 2021
3929df0
[ISSUE #1848] add the version for removing the not exist mbeans.
brotherlu-xcq Sep 13, 2021
28e3a6d
[ISSUE #1848] add javadoc.
brotherlu-xcq Sep 13, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,13 @@
<artifactId>sentinel-adapter</artifactId>
<version>${project.version}</version>
</dependency>


<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-metric-exporter</artifactId>
<version>${project.version}</version>
</dependency>

<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,23 @@
*/
package com.alibaba.csp.sentinel.slots.block.flow;

import java.util.ArrayList;
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 com.alibaba.csp.sentinel.concurrent.NamedThreadFactory;
import com.alibaba.csp.sentinel.config.SentinelConfig;
import com.alibaba.csp.sentinel.log.RecordLog;
import com.alibaba.csp.sentinel.util.AssertUtil;
import com.alibaba.csp.sentinel.util.StringUtil;
import com.alibaba.csp.sentinel.node.metric.MetricTimerListener;
import com.alibaba.csp.sentinel.property.DynamicSentinelProperty;
import com.alibaba.csp.sentinel.property.PropertyListener;
import com.alibaba.csp.sentinel.property.SentinelProperty;
import com.alibaba.csp.sentinel.util.AssertUtil;
import com.alibaba.csp.sentinel.util.StringUtil;

import java.util.ArrayList;
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;

/**
* <p>
Expand All @@ -53,6 +53,7 @@ public class FlowRuleManager {
private static final FlowPropertyListener LISTENER = new FlowPropertyListener();
private static SentinelProperty<List<FlowRule>> currentProperty = new DynamicSentinelProperty<List<FlowRule>>();

/** the corePool size of SCHEDULER must be set at 1, so the two task ({@link #startMetricTimerListener()} can run orderly by the SCHEDULER **/
@SuppressWarnings("PMD.ThreadPoolCreationRule")
private static final ScheduledExecutorService SCHEDULER = Executors.newScheduledThreadPool(1,
new NamedThreadFactory("sentinel-metrics-record-task", true));
Expand All @@ -61,7 +62,7 @@ public class FlowRuleManager {
currentProperty.addListener(LISTENER);
startMetricTimerListener();
}

brotherlu-xcq marked this conversation as resolved.
Show resolved Hide resolved
/**
* <p> Start the MetricTimerListener
* <ol>
Expand Down
1 change: 1 addition & 0 deletions sentinel-extension/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
<module>sentinel-datasource-etcd</module>
<module>sentinel-datasource-eureka</module>
<module>sentinel-annotation-cdi-interceptor</module>
<module>sentinel-metric-exporter</module>
</modules>

</project>
27 changes: 27 additions & 0 deletions sentinel-extension/sentinel-metric-exporter/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-extension</artifactId>
<version>1.8.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>sentinel-metric-exporter</artifactId>
<packaging>jar</packaging>

<dependencies>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-core</artifactId>
</dependency>

<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
* Copyright 1999-2021 Alibaba Group Holding Ltd.
*
* Licensed 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.alibaba.csp.sentinel.metric;

import com.alibaba.csp.sentinel.init.InitFunc;
import com.alibaba.csp.sentinel.log.RecordLog;
import com.alibaba.csp.sentinel.metric.collector.MetricCollector;
import com.alibaba.csp.sentinel.metric.exporter.MetricExporter;
import com.alibaba.csp.sentinel.metric.exporter.jmx.JMXMetricExporter;

import java.util.ArrayList;
import java.util.List;

/**
* The{@link MetricExporterInit} work on load Metric exporters.
*
* @author chenglu
* @date 2021-07-01 19:58
* @since 1.8.3
*/
public class MetricExporterInit implements InitFunc {

/**
* the list of metric exporters.
*/
private static List<MetricExporter> metricExporters = new ArrayList<>();

/**
* the metric collector.
*/
private static MetricCollector metricCollector = new MetricCollector();
brotherlu-xcq marked this conversation as resolved.
Show resolved Hide resolved

/*
load metric exporters.
*/
static {
// now we use this simple way to load MetricExporter.
metricExporters.add(new JMXMetricExporter(metricCollector));
}

@Override
public void init() throws Exception {
RecordLog.info("[MetricExporterInit] MetricExporter start init.");
// start the metric exporters.
for (MetricExporter metricExporter : metricExporters) {
try {
metricExporter.start();
} catch (Exception e) {
RecordLog.warn("[MetricExporterInit] MetricExporterInit start the metricExport[{}] failed, will ignore it.",
metricExporter.getClass().getName(), e);
}
}

// add shutdown hook.
Runtime.getRuntime().addShutdownHook(new Thread(
() -> metricExporters.forEach(metricExporter -> {
try {
metricExporter.shutdown();
} catch (Exception e) {
RecordLog.warn("[MetricExporterInit] MetricExporterInit shutdown the metricExport[{}] failed, will ignore it.",
metricExporter.getClass().getName(), e);
}
})
));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/*
* Copyright 1999-2021 Alibaba Group Holding Ltd.
*
* Licensed 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.alibaba.csp.sentinel.metric.collector;

import com.alibaba.csp.sentinel.Constants;
import com.alibaba.csp.sentinel.node.ClusterNode;
import com.alibaba.csp.sentinel.node.metric.MetricNode;
import com.alibaba.csp.sentinel.slotchain.ResourceWrapper;
import com.alibaba.csp.sentinel.slots.clusterbuilder.ClusterBuilderSlot;
import com.alibaba.csp.sentinel.util.TimeUtil;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
* The {@link MetricCollector} work on collecting metrics in {@link MetricNode}.
*
* @author chenglu
* @date 2021-07-01 20:01
* @since 1.8.3
*/
public class MetricCollector {

/**
* collect the metrics in {@link MetricNode}.
*
* @return the metric grouped by resource name.
*/
public Map<String, MetricNode> collectMetric() {
Map<String, MetricNode> metricNodeMap = new HashMap<>();
for (Map.Entry<ResourceWrapper, ClusterNode> e : ClusterBuilderSlot.getClusterNodeMap().entrySet()) {
ClusterNode node = e.getValue();
List<MetricNode> metrics = getLastMetrics(node);
aggregate(metricNodeMap, metrics, node);
}
aggregate(metricNodeMap, getLastMetrics(Constants.ENTRY_NODE), Constants.ENTRY_NODE);
return metricNodeMap;
}


/**
* Get the last second {@link MetricNode} of {@link ClusterNode}
* @param node {@link ClusterNode}
* @return the list of {@link MetricNode}
*/
private List<MetricNode> getLastMetrics(ClusterNode node) {
final long currentTime = TimeUtil.currentTimeMillis();
final long maxTime = currentTime - currentTime % 1000;
final long minTime = maxTime - 1000;
brotherlu-xcq marked this conversation as resolved.
Show resolved Hide resolved
return node.rawMetricsInMin(time -> time >= minTime && time < maxTime);
}


/**
* aggregate the metrics, the metrics under the same resource will left the lasted value
* @param metricNodeMap metrics map
* @param metrics metrics info group by timestamp
* @param node the node
*/
private void aggregate(Map<String, MetricNode> metricNodeMap, List<MetricNode> metrics, ClusterNode node) {
if (metrics == null || metrics.size() == 0) {
return;
}
for (MetricNode metricNode : metrics) {
String resource = node.getName();
metricNode.setResource(resource);
metricNode.setClassification(node.getResourceType());
MetricNode existMetricNode = metricNodeMap.get(resource);
// always keep the MetricNode is the last
if (existMetricNode != null && existMetricNode.getTimestamp() > metricNode.getTimestamp()) {
continue;
}
metricNodeMap.put(resource, metricNode);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Copyright 1999-2021 Alibaba Group Holding Ltd.
*
* Licensed 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.alibaba.csp.sentinel.metric.exporter;

/**
* {@link MetricExporter} work on export metric to target monitor.
* you can implement your export ways by this class.
*
* @author chenglu
* @date 2021-07-01 21:16
*/
public interface MetricExporter {

/**
* start the {@link MetricExporter}.
*
* @throws Exception start exception.
*/
void start() throws Exception;

/**
* export the data to target monitor by the implement.
*
* @throws Exception export exception.
*/
void export() throws Exception;

/**
* shutdown the {@link MetricExporter}.
*
* @throws Exception shutdown exception.
*/
void shutdown() throws Exception;
}
Loading