Skip to content

Commit 030ec23

Browse files
committed
Make CommandCenterProvider and HeartBeatSenderProvider choose the instance with highest precedence
Signed-off-by: Eric Zhao <[email protected]>
1 parent 79211f0 commit 030ec23

File tree

5 files changed

+92
-26
lines changed

5 files changed

+92
-26
lines changed

sentinel-transport/sentinel-transport-common/src/main/java/com/alibaba/csp/sentinel/command/CommandCenterProvider.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
* @author cdfive
2626
* @since 1.5.0
2727
*/
28-
public class CommandCenterProvider {
28+
public final class CommandCenterProvider {
2929

3030
private static CommandCenter commandCenter = null;
3131

@@ -34,10 +34,10 @@ public class CommandCenterProvider {
3434
}
3535

3636
private static void resolveInstance() {
37-
CommandCenter resolveCommandCenter = SpiLoader.loadFirstInstance(CommandCenter.class);
37+
CommandCenter resolveCommandCenter = SpiLoader.loadHighestPriorityInstance(CommandCenter.class);
3838

3939
if (resolveCommandCenter == null) {
40-
RecordLog.warn("[CommandCenterProvider] No existing CommandCenter, resolve failed");
40+
RecordLog.warn("[CommandCenterProvider] WARN: No existing CommandCenter found");
4141
} else {
4242
commandCenter = resolveCommandCenter;
4343
RecordLog.info("[CommandCenterProvider] CommandCenter resolved: " + resolveCommandCenter.getClass()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
* Copyright 1999-2019 Alibaba Group Holding Ltd.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.alibaba.csp.sentinel.heartbeat;
17+
18+
import com.alibaba.csp.sentinel.log.RecordLog;
19+
import com.alibaba.csp.sentinel.transport.HeartbeatSender;
20+
import com.alibaba.csp.sentinel.util.SpiLoader;
21+
22+
/**
23+
* @author Eric Zhao
24+
* @since 1.6.0
25+
*/
26+
public final class HeartbeatSenderProvider {
27+
28+
private static HeartbeatSender heartbeatSender = null;
29+
30+
static {
31+
resolveInstance();
32+
}
33+
34+
private static void resolveInstance() {
35+
HeartbeatSender resolved = SpiLoader.loadHighestPriorityInstance(HeartbeatSender.class);
36+
if (resolved == null) {
37+
RecordLog.warn("[HeartbeatSenderProvider] WARN: No existing HeartbeatSender found");
38+
} else {
39+
heartbeatSender = resolved;
40+
RecordLog.info("[HeartbeatSenderProvider] HeartbeatSender activated: " + resolved.getClass()
41+
.getCanonicalName());
42+
}
43+
}
44+
45+
/**
46+
* Get resolved {@link HeartbeatSender} instance.
47+
*
48+
* @return resolved {@code HeartbeatSender} instance
49+
*/
50+
public static HeartbeatSender getHeartbeatSender() {
51+
return heartbeatSender;
52+
}
53+
54+
private HeartbeatSenderProvider() {}
55+
}

sentinel-transport/sentinel-transport-common/src/main/java/com/alibaba/csp/sentinel/transport/init/HeartbeatSenderInitFunc.java

+30-23
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,16 @@
1515
*/
1616
package com.alibaba.csp.sentinel.transport.init;
1717

18-
import java.util.Iterator;
19-
import java.util.ServiceLoader;
20-
import java.util.concurrent.Executors;
2118
import java.util.concurrent.ScheduledExecutorService;
19+
import java.util.concurrent.ScheduledThreadPoolExecutor;
20+
import java.util.concurrent.ThreadPoolExecutor.DiscardOldestPolicy;
2221
import java.util.concurrent.TimeUnit;
2322

2423
import com.alibaba.csp.sentinel.concurrent.NamedThreadFactory;
2524
import com.alibaba.csp.sentinel.config.SentinelConfig;
25+
import com.alibaba.csp.sentinel.heartbeat.HeartbeatSenderProvider;
2626
import com.alibaba.csp.sentinel.init.InitFunc;
27+
import com.alibaba.csp.sentinel.init.InitOrder;
2728
import com.alibaba.csp.sentinel.log.RecordLog;
2829
import com.alibaba.csp.sentinel.transport.HeartbeatSender;
2930
import com.alibaba.csp.sentinel.transport.config.TransportConfig;
@@ -33,30 +34,35 @@
3334
*
3435
* @author Eric Zhao
3536
*/
37+
@InitOrder(-1)
3638
public class HeartbeatSenderInitFunc implements InitFunc {
3739

38-
@SuppressWarnings("PMD.ThreadPoolCreationRule")
39-
private static ScheduledExecutorService pool = Executors.newScheduledThreadPool(2,
40-
new NamedThreadFactory("sentinel-heartbeat-send-task", true));
40+
private ScheduledExecutorService pool = null;
4141

42-
private boolean validHeartbeatInterval(Long interval) {
43-
return interval != null && interval > 0;
42+
private void initSchedulerIfNeeded() {
43+
if (pool == null) {
44+
pool = new ScheduledThreadPoolExecutor(2,
45+
new NamedThreadFactory("sentinel-heartbeat-send-task", true),
46+
new DiscardOldestPolicy());
47+
}
4448
}
4549

4650
@Override
4751
public void init() {
48-
ServiceLoader<HeartbeatSender> loader = ServiceLoader.load(HeartbeatSender.class);
49-
Iterator<HeartbeatSender> iterator = loader.iterator();
50-
if (iterator.hasNext()) {
51-
final HeartbeatSender sender = iterator.next();
52-
if (iterator.hasNext()) {
53-
throw new IllegalStateException("Only single heartbeat sender can be scheduled");
54-
} else {
55-
long interval = retrieveInterval(sender);
56-
setIntervalIfNotExists(interval);
57-
scheduleHeartbeatTask(sender, interval);
58-
}
52+
HeartbeatSender sender = HeartbeatSenderProvider.getHeartbeatSender();
53+
if (sender == null) {
54+
RecordLog.warn("[HeartbeatSenderInitFunc] WARN: No HeartbeatSender loaded");
55+
return;
5956
}
57+
58+
initSchedulerIfNeeded();
59+
long interval = retrieveInterval(sender);
60+
setIntervalIfNotExists(interval);
61+
scheduleHeartbeatTask(sender, interval);
62+
}
63+
64+
private boolean isValidHeartbeatInterval(Long interval) {
65+
return interval != null && interval > 0;
6066
}
6167

6268
private void setIntervalIfNotExists(long interval) {
@@ -65,13 +71,14 @@ private void setIntervalIfNotExists(long interval) {
6571

6672
long retrieveInterval(/*@NonNull*/ HeartbeatSender sender) {
6773
Long intervalInConfig = TransportConfig.getHeartbeatIntervalMs();
68-
if (validHeartbeatInterval(intervalInConfig)) {
69-
RecordLog.info("[HeartbeatSenderInit] Using heartbeat interval in Sentinel config property: " + intervalInConfig);
74+
if (isValidHeartbeatInterval(intervalInConfig)) {
75+
RecordLog.info("[HeartbeatSenderInitFunc] Using heartbeat interval "
76+
+ "in Sentinel config property: " + intervalInConfig);
7077
return intervalInConfig;
7178
} else {
7279
long senderInterval = sender.intervalMs();
73-
RecordLog.info("[HeartbeatSenderInit] Heartbeat interval not configured in config property or invalid, "
74-
+ "using sender default: " + senderInterval);
80+
RecordLog.info("[HeartbeatSenderInit] Heartbeat interval not configured in "
81+
+ "config property or invalid, using sender default: " + senderInterval);
7582
return senderInterval;
7683
}
7784
}

sentinel-transport/sentinel-transport-netty-http/src/main/java/com/alibaba/csp/sentinel/transport/command/NettyHttpCommandCenter.java

+2
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import com.alibaba.csp.sentinel.command.CommandHandler;
2323
import com.alibaba.csp.sentinel.command.CommandHandlerProvider;
2424
import com.alibaba.csp.sentinel.concurrent.NamedThreadFactory;
25+
import com.alibaba.csp.sentinel.spi.SpiOrder;
2526
import com.alibaba.csp.sentinel.transport.command.netty.HttpServer;
2627
import com.alibaba.csp.sentinel.log.RecordLog;
2728
import com.alibaba.csp.sentinel.transport.CommandCenter;
@@ -31,6 +32,7 @@
3132
*
3233
* @author Eric Zhao
3334
*/
35+
@SpiOrder(SpiOrder.LOWEST_PRECEDENCE - 100)
3436
public class NettyHttpCommandCenter implements CommandCenter {
3537

3638
private final HttpServer server = new HttpServer();

sentinel-transport/sentinel-transport-netty-http/src/main/java/com/alibaba/csp/sentinel/transport/heartbeat/HttpHeartbeatSender.java

+2
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import java.util.List;
2020

2121
import com.alibaba.csp.sentinel.Constants;
22+
import com.alibaba.csp.sentinel.spi.SpiOrder;
2223
import com.alibaba.csp.sentinel.transport.config.TransportConfig;
2324
import com.alibaba.csp.sentinel.log.RecordLog;
2425
import com.alibaba.csp.sentinel.util.AppNameUtil;
@@ -39,6 +40,7 @@
3940
* @author Eric Zhao
4041
* @author leyou
4142
*/
43+
@SpiOrder(SpiOrder.LOWEST_PRECEDENCE - 100)
4244
public class HttpHeartbeatSender implements HeartbeatSender {
4345

4446
private final CloseableHttpClient client;

0 commit comments

Comments
 (0)