Signed-off-by: Eric Zhao <sczyh16@gmail.com>master
@@ -25,7 +25,7 @@ import com.alibaba.csp.sentinel.util.SpiLoader; | |||||
* @author cdfive | * @author cdfive | ||||
* @since 1.5.0 | * @since 1.5.0 | ||||
*/ | */ | ||||
public class CommandCenterProvider { | |||||
public final class CommandCenterProvider { | |||||
private static CommandCenter commandCenter = null; | private static CommandCenter commandCenter = null; | ||||
@@ -34,10 +34,10 @@ public class CommandCenterProvider { | |||||
} | } | ||||
private static void resolveInstance() { | private static void resolveInstance() { | ||||
CommandCenter resolveCommandCenter = SpiLoader.loadFirstInstance(CommandCenter.class); | |||||
CommandCenter resolveCommandCenter = SpiLoader.loadHighestPriorityInstance(CommandCenter.class); | |||||
if (resolveCommandCenter == null) { | if (resolveCommandCenter == null) { | ||||
RecordLog.warn("[CommandCenterProvider] No existing CommandCenter, resolve failed"); | |||||
RecordLog.warn("[CommandCenterProvider] WARN: No existing CommandCenter found"); | |||||
} else { | } else { | ||||
commandCenter = resolveCommandCenter; | commandCenter = resolveCommandCenter; | ||||
RecordLog.info("[CommandCenterProvider] CommandCenter resolved: " + resolveCommandCenter.getClass() | 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; | 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.ScheduledExecutorService; | ||||
import java.util.concurrent.ScheduledThreadPoolExecutor; | |||||
import java.util.concurrent.ThreadPoolExecutor.DiscardOldestPolicy; | |||||
import java.util.concurrent.TimeUnit; | import java.util.concurrent.TimeUnit; | ||||
import com.alibaba.csp.sentinel.concurrent.NamedThreadFactory; | import com.alibaba.csp.sentinel.concurrent.NamedThreadFactory; | ||||
import com.alibaba.csp.sentinel.config.SentinelConfig; | 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.InitFunc; | ||||
import com.alibaba.csp.sentinel.init.InitOrder; | |||||
import com.alibaba.csp.sentinel.log.RecordLog; | import com.alibaba.csp.sentinel.log.RecordLog; | ||||
import com.alibaba.csp.sentinel.transport.HeartbeatSender; | import com.alibaba.csp.sentinel.transport.HeartbeatSender; | ||||
import com.alibaba.csp.sentinel.transport.config.TransportConfig; | import com.alibaba.csp.sentinel.transport.config.TransportConfig; | ||||
@@ -33,30 +34,35 @@ import com.alibaba.csp.sentinel.transport.config.TransportConfig; | |||||
* | * | ||||
* @author Eric Zhao | * @author Eric Zhao | ||||
*/ | */ | ||||
@InitOrder(-1) | |||||
public class HeartbeatSenderInitFunc implements InitFunc { | 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 | @Override | ||||
public void init() { | 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) { | private void setIntervalIfNotExists(long interval) { | ||||
@@ -65,13 +71,14 @@ public class HeartbeatSenderInitFunc implements InitFunc { | |||||
long retrieveInterval(/*@NonNull*/ HeartbeatSender sender) { | long retrieveInterval(/*@NonNull*/ HeartbeatSender sender) { | ||||
Long intervalInConfig = TransportConfig.getHeartbeatIntervalMs(); | 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; | return intervalInConfig; | ||||
} else { | } else { | ||||
long senderInterval = sender.intervalMs(); | 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; | return senderInterval; | ||||
} | } | ||||
} | } | ||||
@@ -22,6 +22,7 @@ import java.util.concurrent.Executors; | |||||
import com.alibaba.csp.sentinel.command.CommandHandler; | import com.alibaba.csp.sentinel.command.CommandHandler; | ||||
import com.alibaba.csp.sentinel.command.CommandHandlerProvider; | import com.alibaba.csp.sentinel.command.CommandHandlerProvider; | ||||
import com.alibaba.csp.sentinel.concurrent.NamedThreadFactory; | 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.transport.command.netty.HttpServer; | ||||
import com.alibaba.csp.sentinel.log.RecordLog; | import com.alibaba.csp.sentinel.log.RecordLog; | ||||
import com.alibaba.csp.sentinel.transport.CommandCenter; | import com.alibaba.csp.sentinel.transport.CommandCenter; | ||||
@@ -31,6 +32,7 @@ import com.alibaba.csp.sentinel.transport.CommandCenter; | |||||
* | * | ||||
* @author Eric Zhao | * @author Eric Zhao | ||||
*/ | */ | ||||
@SpiOrder(SpiOrder.LOWEST_PRECEDENCE - 100) | |||||
public class NettyHttpCommandCenter implements CommandCenter { | public class NettyHttpCommandCenter implements CommandCenter { | ||||
private final HttpServer server = new HttpServer(); | private final HttpServer server = new HttpServer(); | ||||
@@ -19,6 +19,7 @@ import java.util.ArrayList; | |||||
import java.util.List; | import java.util.List; | ||||
import com.alibaba.csp.sentinel.Constants; | 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.transport.config.TransportConfig; | ||||
import com.alibaba.csp.sentinel.log.RecordLog; | import com.alibaba.csp.sentinel.log.RecordLog; | ||||
import com.alibaba.csp.sentinel.util.AppNameUtil; | import com.alibaba.csp.sentinel.util.AppNameUtil; | ||||
@@ -39,6 +40,7 @@ import org.apache.http.impl.client.HttpClients; | |||||
* @author Eric Zhao | * @author Eric Zhao | ||||
* @author leyou | * @author leyou | ||||
*/ | */ | ||||
@SpiOrder(SpiOrder.LOWEST_PRECEDENCE - 100) | |||||
public class HttpHeartbeatSender implements HeartbeatSender { | public class HttpHeartbeatSender implements HeartbeatSender { | ||||
private final CloseableHttpClient client; | private final CloseableHttpClient client; | ||||