Signed-off-by: Eric Zhao <sczyh16@gmail.com>master
@@ -25,7 +25,7 @@ import com.alibaba.csp.sentinel.util.SpiLoader; | |||
* @author cdfive | |||
* @since 1.5.0 | |||
*/ | |||
public class CommandCenterProvider { | |||
public final class CommandCenterProvider { | |||
private static CommandCenter commandCenter = null; | |||
@@ -34,10 +34,10 @@ public class CommandCenterProvider { | |||
} | |||
private static void resolveInstance() { | |||
CommandCenter resolveCommandCenter = SpiLoader.loadFirstInstance(CommandCenter.class); | |||
CommandCenter resolveCommandCenter = SpiLoader.loadHighestPriorityInstance(CommandCenter.class); | |||
if (resolveCommandCenter == null) { | |||
RecordLog.warn("[CommandCenterProvider] No existing CommandCenter, resolve failed"); | |||
RecordLog.warn("[CommandCenterProvider] WARN: No existing CommandCenter found"); | |||
} else { | |||
commandCenter = resolveCommandCenter; | |||
RecordLog.info("[CommandCenterProvider] CommandCenter resolved: " + resolveCommandCenter.getClass() | |||
@@ -0,0 +1,55 @@ | |||
/* | |||
* Copyright 1999-2019 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 | |||
* | |||
* https://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.heartbeat; | |||
import com.alibaba.csp.sentinel.log.RecordLog; | |||
import com.alibaba.csp.sentinel.transport.HeartbeatSender; | |||
import com.alibaba.csp.sentinel.util.SpiLoader; | |||
/** | |||
* @author Eric Zhao | |||
* @since 1.6.0 | |||
*/ | |||
public final class HeartbeatSenderProvider { | |||
private static HeartbeatSender heartbeatSender = null; | |||
static { | |||
resolveInstance(); | |||
} | |||
private static void resolveInstance() { | |||
HeartbeatSender resolved = SpiLoader.loadHighestPriorityInstance(HeartbeatSender.class); | |||
if (resolved == null) { | |||
RecordLog.warn("[HeartbeatSenderProvider] WARN: No existing HeartbeatSender found"); | |||
} else { | |||
heartbeatSender = resolved; | |||
RecordLog.info("[HeartbeatSenderProvider] HeartbeatSender activated: " + resolved.getClass() | |||
.getCanonicalName()); | |||
} | |||
} | |||
/** | |||
* Get resolved {@link HeartbeatSender} instance. | |||
* | |||
* @return resolved {@code HeartbeatSender} instance | |||
*/ | |||
public static HeartbeatSender getHeartbeatSender() { | |||
return heartbeatSender; | |||
} | |||
private HeartbeatSenderProvider() {} | |||
} |
@@ -15,15 +15,16 @@ | |||
*/ | |||
package com.alibaba.csp.sentinel.transport.init; | |||
import java.util.Iterator; | |||
import java.util.ServiceLoader; | |||
import java.util.concurrent.Executors; | |||
import java.util.concurrent.ScheduledExecutorService; | |||
import java.util.concurrent.ScheduledThreadPoolExecutor; | |||
import java.util.concurrent.ThreadPoolExecutor.DiscardOldestPolicy; | |||
import java.util.concurrent.TimeUnit; | |||
import com.alibaba.csp.sentinel.concurrent.NamedThreadFactory; | |||
import com.alibaba.csp.sentinel.config.SentinelConfig; | |||
import com.alibaba.csp.sentinel.heartbeat.HeartbeatSenderProvider; | |||
import com.alibaba.csp.sentinel.init.InitFunc; | |||
import com.alibaba.csp.sentinel.init.InitOrder; | |||
import com.alibaba.csp.sentinel.log.RecordLog; | |||
import com.alibaba.csp.sentinel.transport.HeartbeatSender; | |||
import com.alibaba.csp.sentinel.transport.config.TransportConfig; | |||
@@ -33,30 +34,35 @@ import com.alibaba.csp.sentinel.transport.config.TransportConfig; | |||
* | |||
* @author Eric Zhao | |||
*/ | |||
@InitOrder(-1) | |||
public class HeartbeatSenderInitFunc implements InitFunc { | |||
@SuppressWarnings("PMD.ThreadPoolCreationRule") | |||
private static ScheduledExecutorService pool = Executors.newScheduledThreadPool(2, | |||
new NamedThreadFactory("sentinel-heartbeat-send-task", true)); | |||
private ScheduledExecutorService pool = null; | |||
private boolean validHeartbeatInterval(Long interval) { | |||
return interval != null && interval > 0; | |||
private void initSchedulerIfNeeded() { | |||
if (pool == null) { | |||
pool = new ScheduledThreadPoolExecutor(2, | |||
new NamedThreadFactory("sentinel-heartbeat-send-task", true), | |||
new DiscardOldestPolicy()); | |||
} | |||
} | |||
@Override | |||
public void init() { | |||
ServiceLoader<HeartbeatSender> loader = ServiceLoader.load(HeartbeatSender.class); | |||
Iterator<HeartbeatSender> iterator = loader.iterator(); | |||
if (iterator.hasNext()) { | |||
final HeartbeatSender sender = iterator.next(); | |||
if (iterator.hasNext()) { | |||
throw new IllegalStateException("Only single heartbeat sender can be scheduled"); | |||
} else { | |||
long interval = retrieveInterval(sender); | |||
setIntervalIfNotExists(interval); | |||
scheduleHeartbeatTask(sender, interval); | |||
} | |||
HeartbeatSender sender = HeartbeatSenderProvider.getHeartbeatSender(); | |||
if (sender == null) { | |||
RecordLog.warn("[HeartbeatSenderInitFunc] WARN: No HeartbeatSender loaded"); | |||
return; | |||
} | |||
initSchedulerIfNeeded(); | |||
long interval = retrieveInterval(sender); | |||
setIntervalIfNotExists(interval); | |||
scheduleHeartbeatTask(sender, interval); | |||
} | |||
private boolean isValidHeartbeatInterval(Long interval) { | |||
return interval != null && interval > 0; | |||
} | |||
private void setIntervalIfNotExists(long interval) { | |||
@@ -65,13 +71,14 @@ public class HeartbeatSenderInitFunc implements InitFunc { | |||
long retrieveInterval(/*@NonNull*/ HeartbeatSender sender) { | |||
Long intervalInConfig = TransportConfig.getHeartbeatIntervalMs(); | |||
if (validHeartbeatInterval(intervalInConfig)) { | |||
RecordLog.info("[HeartbeatSenderInit] Using heartbeat interval in Sentinel config property: " + intervalInConfig); | |||
if (isValidHeartbeatInterval(intervalInConfig)) { | |||
RecordLog.info("[HeartbeatSenderInitFunc] Using heartbeat interval " | |||
+ "in Sentinel config property: " + intervalInConfig); | |||
return intervalInConfig; | |||
} else { | |||
long senderInterval = sender.intervalMs(); | |||
RecordLog.info("[HeartbeatSenderInit] Heartbeat interval not configured in config property or invalid, " | |||
+ "using sender default: " + senderInterval); | |||
RecordLog.info("[HeartbeatSenderInit] Heartbeat interval not configured in " | |||
+ "config property or invalid, using sender default: " + senderInterval); | |||
return senderInterval; | |||
} | |||
} | |||
@@ -22,6 +22,7 @@ import java.util.concurrent.Executors; | |||
import com.alibaba.csp.sentinel.command.CommandHandler; | |||
import com.alibaba.csp.sentinel.command.CommandHandlerProvider; | |||
import com.alibaba.csp.sentinel.concurrent.NamedThreadFactory; | |||
import com.alibaba.csp.sentinel.spi.SpiOrder; | |||
import com.alibaba.csp.sentinel.transport.command.netty.HttpServer; | |||
import com.alibaba.csp.sentinel.log.RecordLog; | |||
import com.alibaba.csp.sentinel.transport.CommandCenter; | |||
@@ -31,6 +32,7 @@ import com.alibaba.csp.sentinel.transport.CommandCenter; | |||
* | |||
* @author Eric Zhao | |||
*/ | |||
@SpiOrder(SpiOrder.LOWEST_PRECEDENCE - 100) | |||
public class NettyHttpCommandCenter implements CommandCenter { | |||
private final HttpServer server = new HttpServer(); | |||
@@ -19,6 +19,7 @@ import java.util.ArrayList; | |||
import java.util.List; | |||
import com.alibaba.csp.sentinel.Constants; | |||
import com.alibaba.csp.sentinel.spi.SpiOrder; | |||
import com.alibaba.csp.sentinel.transport.config.TransportConfig; | |||
import com.alibaba.csp.sentinel.log.RecordLog; | |||
import com.alibaba.csp.sentinel.util.AppNameUtil; | |||
@@ -39,6 +40,7 @@ import org.apache.http.impl.client.HttpClients; | |||
* @author Eric Zhao | |||
* @author leyou | |||
*/ | |||
@SpiOrder(SpiOrder.LOWEST_PRECEDENCE - 100) | |||
public class HttpHeartbeatSender implements HeartbeatSender { | |||
private final CloseableHttpClient client; | |||