org.gridgain.grid.kernal.GridKernal Maven / Gradle / Ivy
/*
Copyright (C) GridGain Systems. All Rights Reserved.
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 org.gridgain.grid.kernal;
import org.gridgain.grid.*;
import org.gridgain.grid.cache.*;
import org.gridgain.grid.cache.affinity.*;
import org.gridgain.grid.dataload.*;
import org.gridgain.grid.dr.*;
import org.gridgain.grid.ggfs.*;
import org.gridgain.grid.kernal.managers.*;
import org.gridgain.grid.kernal.managers.authentication.*;
import org.gridgain.grid.kernal.managers.checkpoint.*;
import org.gridgain.grid.kernal.managers.collision.*;
import org.gridgain.grid.kernal.managers.communication.*;
import org.gridgain.grid.kernal.managers.deployment.*;
import org.gridgain.grid.kernal.managers.discovery.*;
import org.gridgain.grid.kernal.managers.eventstorage.*;
import org.gridgain.grid.kernal.managers.failover.*;
import org.gridgain.grid.kernal.managers.indexing.*;
import org.gridgain.grid.kernal.managers.loadbalancer.*;
import org.gridgain.grid.kernal.managers.securesession.*;
import org.gridgain.grid.kernal.managers.swapspace.*;
import org.gridgain.grid.kernal.processors.*;
import org.gridgain.grid.kernal.processors.affinity.*;
import org.gridgain.grid.kernal.processors.cache.*;
import org.gridgain.grid.kernal.processors.clock.*;
import org.gridgain.grid.kernal.processors.closure.*;
import org.gridgain.grid.kernal.processors.continuous.*;
import org.gridgain.grid.kernal.processors.dataload.*;
import org.gridgain.grid.kernal.processors.dr.*;
import org.gridgain.grid.kernal.processors.email.*;
import org.gridgain.grid.kernal.processors.ggfs.*;
import org.gridgain.grid.kernal.processors.job.*;
import org.gridgain.grid.kernal.processors.jobmetrics.*;
import org.gridgain.grid.kernal.processors.license.*;
import org.gridgain.grid.kernal.processors.offheap.*;
import org.gridgain.grid.kernal.processors.port.*;
import org.gridgain.grid.kernal.processors.resource.*;
import org.gridgain.grid.kernal.processors.rest.*;
import org.gridgain.grid.kernal.processors.schedule.*;
import org.gridgain.grid.kernal.processors.segmentation.*;
import org.gridgain.grid.kernal.processors.session.*;
import org.gridgain.grid.kernal.processors.streamer.*;
import org.gridgain.grid.kernal.processors.task.*;
import org.gridgain.grid.kernal.processors.timeout.*;
import org.gridgain.grid.kernal.processors.version.*;
import org.gridgain.grid.lang.*;
import org.gridgain.grid.logger.*;
import org.gridgain.grid.logger.log4j.*;
import org.gridgain.grid.marshaller.optimized.*;
import org.gridgain.grid.product.*;
import org.gridgain.grid.scheduler.*;
import org.gridgain.grid.spi.*;
import org.gridgain.grid.streamer.*;
import org.gridgain.grid.util.*;
import org.gridgain.grid.util.future.*;
import org.gridgain.grid.util.lang.*;
import org.gridgain.grid.util.nodestart.*;
import org.gridgain.grid.util.typedef.*;
import org.gridgain.grid.util.typedef.internal.*;
import org.jetbrains.annotations.*;
import org.springframework.context.*;
import javax.management.*;
import java.io.*;
import java.lang.management.*;
import java.lang.reflect.*;
import java.net.*;
import java.text.*;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.*;
import static org.gridgain.grid.GridLifecycleEventType.*;
import static org.gridgain.grid.GridSystemProperties.*;
import static org.gridgain.grid.kernal.GridKernalState.*;
import static org.gridgain.grid.kernal.GridNodeAttributes.*;
import static org.gridgain.grid.kernal.GridProductImpl.*;
import static org.gridgain.grid.kernal.processors.dr.GridDrUtils.*;
import static org.gridgain.grid.product.GridProductEdition.*;
import static org.gridgain.grid.util.nodestart.GridNodeStartUtils.*;
/**
* GridGain kernal.
*
* See http://en.wikipedia.org/wiki/Kernal for information on the
* misspelling.
*/
public class GridKernal extends GridProjectionAdapter implements GridEx, GridKernalMBean {
/** Enterprise release flag. */
private static final boolean ent;
/**
*
*/
static {
boolean ent0;
try {
ent0 = Class.forName("org.gridgain.grid.kernal.breadcrumb") != null;
}
catch (ClassNotFoundException ignored) {
ent0 = false;
}
ent = ent0;
}
/** Ant-augmented compatible versions. */
private static final String COMPATIBLE_VERS = /*@java.compatible.vers*/"";
/** System line separator. */
private static final String NL = U.nl();
/** Periodic version check delay. */
private static final long PERIODIC_VER_CHECK_DELAY = 1000 * 60 * 60; // Every hour.
/** Periodic version check delay. */
private static final long PERIODIC_VER_CHECK_CONN_TIMEOUT = 10 * 1000; // 10 seconds.
/** Periodic version check delay. */
private static final long PERIODIC_LIC_CHECK_DELAY = 1000 * 60; // Every minute.
/** Periodic starvation check interval. */
private static final long PERIODIC_STARVATION_CHECK_FREQ = 1000 * 30;
/** Shutdown delay in msec. when license violation detected. */
private static final int SHUTDOWN_DELAY = 60 * 1000;
/** */
private GridConfiguration cfg;
/** */
@SuppressWarnings({"FieldAccessedSynchronizedAndUnsynchronized"})
private GridLoggerProxy log;
/** */
private String gridName;
/** */
private ObjectName kernalMBean;
/** */
private ObjectName locNodeMBean;
/** */
private ObjectName pubExecSvcMBean;
/** */
private ObjectName sysExecSvcMBean;
/** */
private ObjectName mgmtExecSvcMBean;
/** */
private ObjectName p2PExecSvcMBean;
/** Kernal start timestamp. */
private long startTime = U.currentTimeMillis();
/** Spring context, potentially {@code null}. */
private ApplicationContext springCtx;
/** */
private Timer updateNtfTimer;
/** */
private Timer starveTimer;
/** */
private Timer licTimer;
/** */
private Timer metricsLogTimer;
/** Indicate error on grid stop. */
private boolean errOnStop;
/** Node local store. */
private GridNodeLocalMap nodeLoc;
/** */
private GridScheduler scheduler;
/** Kernal gateway. */
private final AtomicReference gw = new AtomicReference<>();
/** Data Grid edition usage registered flag. */
private volatile boolean dbUsageRegistered;
/** */
private final Collection compatibleVers;
/** Stop guard. */
private final AtomicBoolean stopGuard = new AtomicBoolean();
/**
* No-arg constructor is required by externalization.
*/
public GridKernal() {
this(null);
}
/**
* @param springCtx Optional Spring application context.
*/
public GridKernal(@Nullable ApplicationContext springCtx) {
super(null, null, (GridPredicate)null);
this.springCtx = springCtx;
String[] compatibleVers = COMPATIBLE_VERS.split(",");
for (int i = 0; i < compatibleVers.length; i++)
compatibleVers[i] = compatibleVers[i].trim();
this.compatibleVers = Collections.unmodifiableList(Arrays.asList(compatibleVers));
}
/** {@inheritDoc} */
@Override public String name() {
return gridName;
}
/** {@inheritDoc} */
@Override public String getCopyright() {
return ctx.product().copyright();
}
/** {@inheritDoc} */
@Override public String getLicenseFilePath() {
assert cfg != null;
return cfg.getLicenseUrl();
}
/** {@inheritDoc} */
@Override public long getStartTimestamp() {
return startTime;
}
/** {@inheritDoc} */
@Override public String getStartTimestampFormatted() {
return DateFormat.getDateTimeInstance().format(new Date(startTime));
}
/** {@inheritDoc} */
@Override public long getUpTime() {
return U.currentTimeMillis() - startTime;
}
/** {@inheritDoc} */
@Override public String getUpTimeFormatted() {
return X.timeSpan2HMSM(U.currentTimeMillis() - startTime);
}
/** {@inheritDoc} */
@Override public String getFullVersion() {
return VER + '-' + ctx.build();
}
/** {@inheritDoc} */
@Override public String getCheckpointSpiFormatted() {
assert cfg != null;
return Arrays.toString(cfg.getCheckpointSpi());
}
/** {@inheritDoc} */
@Override public String getSwapSpaceSpiFormatted() {
assert cfg != null;
return cfg.getSwapSpaceSpi().toString();
}
/** {@inheritDoc} */
@Override public String getCommunicationSpiFormatted() {
assert cfg != null;
return cfg.getCommunicationSpi().toString();
}
/** {@inheritDoc} */
@Override public String getDeploymentSpiFormatted() {
assert cfg != null;
return cfg.getDeploymentSpi().toString();
}
/** {@inheritDoc} */
@Override public String getDiscoverySpiFormatted() {
assert cfg != null;
return cfg.getDiscoverySpi().toString();
}
/** {@inheritDoc} */
@Override public String getEventStorageSpiFormatted() {
assert cfg != null;
return cfg.getEventStorageSpi().toString();
}
/** {@inheritDoc} */
@Override public String getCollisionSpiFormatted() {
assert cfg != null;
return cfg.getCollisionSpi().toString();
}
/** {@inheritDoc} */
@Override public String getFailoverSpiFormatted() {
assert cfg != null;
return Arrays.toString(cfg.getFailoverSpi());
}
/** {@inheritDoc} */
@Override public String getLoadBalancingSpiFormatted() {
assert cfg != null;
return Arrays.toString(cfg.getLoadBalancingSpi());
}
/** {@inheritDoc} */
@Override public String getAuthenticationSpiFormatted() {
assert cfg != null;
return cfg.getAuthenticationSpi().toString();
}
/** {@inheritDoc} */
@Override public String getSecureSessionSpiFormatted() {
assert cfg != null;
return cfg.getSecureSessionSpi().toString();
}
/** {@inheritDoc} */
@Override public String getOsInformation() {
return U.osString();
}
/** {@inheritDoc} */
@Override public String getJdkInformation() {
return U.jdkString();
}
/** {@inheritDoc} */
@Override public String getOsUser() {
return System.getProperty("user.name");
}
/** {@inheritDoc} */
@Override public String getVmName() {
return ManagementFactory.getRuntimeMXBean().getName();
}
/** {@inheritDoc} */
@Override public String getInstanceName() {
return gridName;
}
/** {@inheritDoc} */
@Override public String getExecutorServiceFormatted() {
assert cfg != null;
return cfg.getExecutorService().toString();
}
/** {@inheritDoc} */
@Override public String getGridGainHome() {
assert cfg != null;
return cfg.getGridGainHome();
}
/** {@inheritDoc} */
@Override public String getGridLoggerFormatted() {
assert cfg != null;
return cfg.getGridLogger().toString();
}
/** {@inheritDoc} */
@Override public String getMBeanServerFormatted() {
assert cfg != null;
return cfg.getMBeanServer().toString();
}
/** {@inheritDoc} */
@Override public UUID getLocalNodeId() {
assert cfg != null;
return cfg.getNodeId();
}
/** {@inheritDoc} */
@SuppressWarnings("unchecked")
@Override public Collection getUserAttributesFormatted() {
assert cfg != null;
// That's why Java sucks...
return F.transform(cfg.getUserAttributes().entrySet(), new C1, String>() {
@Override public String apply(Map.Entry e) {
return e.getKey() + ", " + e.getValue().toString();
}
});
}
/** {@inheritDoc} */
@Override public boolean isPeerClassLoadingEnabled() {
assert cfg != null;
return cfg.isPeerClassLoadingEnabled();
}
/** {@inheritDoc} */
@Override public Collection getLifecycleBeansFormatted() {
GridLifecycleBean[] beans = cfg.getLifecycleBeans();
return F.isEmpty(beans) ? Collections.emptyList() : F.transform(beans, F.string());
}
/**
* @param spiCls SPI class.
* @return Spi version.
* @throws GridException Thrown if {@link GridSpiInfo} annotation cannot be found.
*/
private Serializable getSpiVersion(Class extends GridSpi> spiCls) throws GridException {
assert spiCls != null;
GridSpiInfo ann = U.getAnnotation(spiCls, GridSpiInfo.class);
if (ann == null)
throw new GridException("SPI implementation does not have annotation: " + GridSpiInfo.class);
return ann.version();
}
/**
* @param attrs Current attributes.
* @param name New attribute name.
* @param val New attribute value.
* @throws GridException If duplicated SPI name found.
*/
private void add(Map attrs, String name, @Nullable Serializable val) throws GridException {
assert attrs != null;
assert name != null;
if (attrs.put(name, val) != null) {
if (name.endsWith(ATTR_SPI_CLASS))
// User defined duplicated names for the different SPIs.
throw new GridException("Failed to set SPI attribute. Duplicated SPI name found: " +
name.substring(0, name.length() - ATTR_SPI_CLASS.length()));
// Otherwise it's a mistake of setting up duplicated attribute.
assert false : "Duplicate attribute: " + name;
}
}
/**
* Notifies life-cycle beans of grid event.
*
* @param evt Grid event.
* @throws GridException If user threw exception during start.
*/
@SuppressWarnings({"CatchGenericClass"})
private void notifyLifecycleBeans(GridLifecycleEventType evt) throws GridException {
if (!cfg.isDaemon() && cfg.getLifecycleBeans() != null)
for (GridLifecycleBean bean : cfg.getLifecycleBeans())
if (bean != null)
bean.onLifecycleEvent(evt);
}
/**
* Notifies life-cycle beans of grid event.
*
* @param evt Grid event.
*/
@SuppressWarnings({"CatchGenericClass"})
private void notifyLifecycleBeansEx(GridLifecycleEventType evt) {
try {
notifyLifecycleBeans(evt);
}
// Catch generic throwable to secure against user assertions.
catch (Throwable e) {
U.error(log, "Failed to notify lifecycle bean (safely ignored) [evt=" + evt +
", gridName=" + gridName + ']', e);
}
}
/**
* @param cfg Grid configuration to use.
* @param errHnd Error handler to use for notification about startup problems.
* @throws GridException Thrown in case of any errors.
*/
@SuppressWarnings("CatchGenericClass")
public void start(final GridConfiguration cfg, GridAbsClosure errHnd) throws GridException {
gw.compareAndSet(null, new GridKernalGatewayImpl(cfg.getGridName()));
GridKernalGateway gw = this.gw.get();
gw.writeLock();
try {
switch (gw.getState()) {
case STARTED: {
U.warn(log, "Grid has already been started (ignored).");
return;
}
case STARTING: {
U.warn(log, "Grid is already in process of being started (ignored).");
return;
}
case STOPPING: {
throw new GridException("Grid is in process of being stopped");
}
case STOPPED: {
break;
}
}
gw.setState(STARTING);
}
finally {
gw.writeUnlock();
}
assert cfg != null;
// Make sure we got proper configuration.
validateCommon(cfg);
gridName = cfg.getGridName();
this.cfg = cfg;
log = (GridLoggerProxy)cfg.getGridLogger().getLogger(getClass().getName() +
(gridName != null ? '%' + gridName : ""));
RuntimeMXBean rtBean = ManagementFactory.getRuntimeMXBean();
String build = new SimpleDateFormat("yyyyMMdd").format(new Date(BUILD));
// Ack various information.
ackAsciiLogo(build);
ackConfigUrl();
ackDaemon();
ackOsInfo();
ackLanguageRuntime();
ackRemoteManagement();
ackVmArguments(rtBean);
ackClassPaths(rtBean);
ackSystemProperties();
ackEnvironmentVariables();
ackSmtpConfiguration();
ackCacheConfiguration();
ackP2pConfiguration();
// Run background network diagnostics.
GridDiagnostic.runBackgroundCheck(gridName, cfg.getExecutorService(), log);
boolean notifyEnabled = !"false".equalsIgnoreCase(X.getSystemOrEnv(GG_UPDATE_NOTIFIER));
final GridUpdateNotifier verChecker;
if (notifyEnabled) {
verChecker = new GridUpdateNotifier(gridName, false);
verChecker.checkForNewVersion(cfg.getExecutorService(), log);
}
else
verChecker = null;
// Ack 3-rd party licenses location.
if (log.isInfoEnabled() && cfg.getGridGainHome() != null)
log.info("3-rd party licenses can be found at: " + cfg.getGridGainHome() + File.separatorChar + "libs" +
File.separatorChar + "licenses");
// Check that user attributes are not conflicting
// with internally reserved names.
for (String name : cfg.getUserAttributes().keySet())
if (name.startsWith(ATTR_PREFIX))
throw new GridException("User attribute has illegal name: '" + name + "'. Note that all names " +
"starting with '" + ATTR_PREFIX + "' are reserved for internal use.");
// Ack local node user attributes.
logNodeUserAttributes();
// Ack configuration.
ackSpis();
Map attrs = createNodeAttributes(cfg, build);
// Spin out SPIs & managers.
try {
GridKernalContextImpl ctx = new GridKernalContextImpl(this, cfg, gw, ent);
nodeLoc = new GridNodeLocalMapImpl(ctx);
// Set context into rich adapter.
setKernalContext(ctx);
// Start and configure resource processor first as it contains resources used
// by all other managers and processors.
GridResourceProcessor rsrcProc = new GridResourceProcessor(ctx);
rsrcProc.setSpringContext(springCtx);
// Set node version.
ctx.version(VER);
ctx.build(build);
ctx.product(new GridProductImpl(ctx, verChecker));
scheduler = new GridSchedulerImpl(ctx);
startProcessor(ctx, rsrcProc, attrs);
// Inject resources into lifecycle beans.
if (!cfg.isDaemon() && cfg.getLifecycleBeans() != null)
for (GridLifecycleBean bean : cfg.getLifecycleBeans())
if (bean != null)
rsrcProc.inject(bean);
// Lifecycle notification.
notifyLifecycleBeans(BEFORE_GRID_START);
// Starts lifecycle aware components.
U.startLifecycleAware(lifecycleAwares(cfg));
GridVersionProcessor verProc = createComponent(GridVersionProcessor.class, ctx);
// Start version converter processor before all other
// components so they can register converters.
startProcessor(ctx, verProc, attrs);
// Off-heap processor has no dependencies.
startProcessor(ctx, new GridOffHeapProcessor(ctx), attrs);
// Closure processor should be started before all others
// (except for resource processor), as many components can depend on it.
startProcessor(ctx, new GridClosureProcessor(ctx), attrs);
// Start some other processors (order & place is important).
startProcessor(ctx, new GridEmailProcessor(ctx), attrs);
startProcessor(ctx, new GridPortProcessor(ctx), attrs);
startProcessor(ctx, new GridJobMetricsProcessor(ctx), attrs);
// Timeout processor needs to be started before managers,
// as managers may depend on it.
startProcessor(ctx, new GridTimeoutProcessor(ctx), attrs);
// Start SPI managers.
// NOTE: that order matters as there are dependencies between managers.
startManager(ctx, createComponent(GridAuthenticationManager.class, ctx), attrs);
startManager(ctx, createComponent(GridSecureSessionManager.class, ctx), attrs);
startManager(ctx, new GridIoManager(ctx), attrs);
startManager(ctx, new GridCheckpointManager(ctx), attrs);
startManager(ctx, new GridEventStorageManager(ctx), attrs);
startManager(ctx, new GridDeploymentManager(ctx), attrs);
startManager(ctx, new GridLoadBalancerManager(ctx), attrs);
startManager(ctx, new GridFailoverManager(ctx), attrs);
startManager(ctx, new GridCollisionManager(ctx), attrs);
startManager(ctx, new GridSwapSpaceManager(ctx), attrs);
startManager(ctx, new GridIndexingManager(ctx), attrs);
ackSecurity(ctx);
// Start processors before discovery manager, so they will
// be able to start receiving messages once discovery completes.
startProcessor(ctx, new GridClockSyncProcessor(ctx), attrs);
startProcessor(ctx, createComponent(GridLicenseProcessor.class, ctx), attrs);
startProcessor(ctx, new GridAffinityProcessor(ctx), attrs);
startProcessor(ctx, createComponent(GridSegmentationProcessor.class, ctx), attrs);
startProcessor(ctx, new GridCacheProcessor(ctx), attrs);
startProcessor(ctx, new GridTaskSessionProcessor(ctx), attrs);
startProcessor(ctx, new GridJobProcessor(ctx), attrs);
startProcessor(ctx, new GridTaskProcessor(ctx), attrs);
startProcessor(ctx, new GridScheduleProcessor(ctx), attrs);
startProcessor(ctx, new GridRestProcessor(ctx), attrs);
startProcessor(ctx, new GridDataLoaderProcessor(ctx), attrs);
startProcessor(ctx, new GridStreamProcessor(ctx), attrs);
startProcessor(ctx, new GridGgfsProcessor(ctx), attrs);
startProcessor(ctx, new GridContinuousProcessor(ctx), attrs);
startProcessor(ctx, createComponent(GridDrProcessor.class, ctx), attrs);
// Put version converters to attributes after
// all components are started.
verProc.addConvertersToAttributes(attrs);
gw.writeLock();
try {
gw.setState(STARTED);
// Start discovery manager last to make sure that grid is fully initialized.
startManager(ctx, new GridDiscoveryManager(ctx), attrs);
}
finally {
gw.writeUnlock();
}
// Check whether physical RAM is not exceeded.
checkPhysicalRam();
// Suggest configuration optimizations.
suggestOptimizations(ctx, cfg);
// Notify discovery manager the first to make sure that topology is discovered.
ctx.discovery().onKernalStart();
// Notify IO manager the second so further components can send and receive messages.
ctx.io().onKernalStart();
// Callbacks.
for (GridComponent comp : ctx) {
// Skip discovery manager.
if (comp instanceof GridDiscoveryManager)
continue;
// Skip IO manager.
if (comp instanceof GridIoManager)
continue;
comp.onKernalStart();
}
// Ack the license.
ctx.license().ackLicense();
// Register MBeans.
registerKernalMBean();
registerLocalNodeMBean();
registerExecutorMBeans();
// Lifecycle bean notifications.
notifyLifecycleBeans(AFTER_GRID_START);
}
catch (Throwable e) {
if (X.hasCause(e, InterruptedException.class, GridInterruptedException.class))
U.warn(log, "Grid startup routine has been interrupted (will rollback).");
else
U.error(log, "Got exception while starting (will rollback startup routine).", e);
errHnd.apply();
stop(true);
if (e instanceof GridException)
throw (GridException)e;
else
throw new GridException(e);
}
// Mark start timestamp.
startTime = U.currentTimeMillis();
// Ack latest version information.
if (verChecker != null)
verChecker.reportStatus(log);
if (notifyEnabled) {
verChecker.reportOnlyNew(true);
verChecker.licenseProcessor(ctx.license());
updateNtfTimer = new Timer("gridgain-update-notifier-timer");
// Setup periodic version check.
updateNtfTimer.scheduleAtFixedRate(new GridTimerTask() {
@Override public void safeRun() throws InterruptedException {
verChecker.topologySize(nodes().size());
verChecker.checkForNewVersion(cfg.getExecutorService(), log);
// Just wait for 10 secs.
Thread.sleep(PERIODIC_VER_CHECK_CONN_TIMEOUT);
// Report status if one is available.
// No-op if status is NOT available.
verChecker.reportStatus(log);
}
}, PERIODIC_VER_CHECK_DELAY, PERIODIC_VER_CHECK_DELAY);
}
String intervalStr = X.getSystemOrEnv(GG_STARVATION_CHECK_INTERVAL);
// Start starvation checker if enabled.
boolean starveCheck = !isDaemon() && !"0".equals(intervalStr);
if (starveCheck) {
final long interval = F.isEmpty(intervalStr) ? PERIODIC_STARVATION_CHECK_FREQ : Long.parseLong(intervalStr);
starveTimer = new Timer("gridgain-starvation-checker");
starveTimer.scheduleAtFixedRate(new GridTimerTask() {
/** Last completed task count. */
private long lastCompletedCnt;
@Override protected void safeRun() {
ExecutorService e = cfg.getExecutorService();
if (!(e instanceof ThreadPoolExecutor))
return;
ThreadPoolExecutor exec = (ThreadPoolExecutor)e;
long completedCnt = exec.getCompletedTaskCount();
// If all threads are active and no task has completed since last time and there is
// at least one waiting request, then it is possible starvation.
if (exec.getPoolSize() == exec.getActiveCount() && completedCnt == lastCompletedCnt &&
!exec.getQueue().isEmpty())
LT.warn(log, null, "Possible thread pool starvation detected (no task completed in last " +
interval + "ms, is executorService pool size large enough?)");
lastCompletedCnt = completedCnt;
}
}, interval, interval);
}
if (!isDaemon()) {
licTimer = new Timer("gridgain-license-checker");
// Setup periodic license check.
licTimer.scheduleAtFixedRate(new GridTimerTask() {
@Override public void safeRun() throws InterruptedException {
try {
ctx.license().checkLicense();
}
// This exception only happens when license processor was unable
// to resolve license violation on its own and this grid instance
// now needs to be shutdown.
//
// Note that in most production configurations the license will
// have certain grace period and license processor will attempt
// to reload the license during the grace period.
//
// This exception thrown here means that grace period, if any,
// has expired and license violation is still unresolved.
catch (GridProductLicenseException ignored) {
U.error(log, "License violation is unresolved. GridGain node will shutdown in " +
(SHUTDOWN_DELAY / 1000) + " sec.");
U.error(log, " ^-- Contact your support for immediate assistance (!)");
// Allow interruption to break from here since
// node is stopping anyways.
Thread.sleep(SHUTDOWN_DELAY);
G.stop(gridName, true);
}
// Safety net.
catch (Throwable e) {
U.error(log, "Unable to check the license due to system error.", e);
U.error(log, "Grid instance will be stopped...");
// Stop the grid if we get unknown license-related error.
// Should never happen. Practically an assertion...
G.stop(gridName, true);
}
}
}, PERIODIC_LIC_CHECK_DELAY, PERIODIC_LIC_CHECK_DELAY);
}
long metricsLogFreq = cfg.getMetricsLogFrequency();
if (metricsLogFreq > 0) {
metricsLogTimer = new Timer("gridgain-metrics-logger");
metricsLogTimer.scheduleAtFixedRate(new GridTimerTask() {
/** */
private final DecimalFormat dblFmt = new DecimalFormat("#.##");
@Override protected void safeRun() {
if (log.isInfoEnabled()) {
GridNodeMetrics m = localNode().metrics();
double cpuLoadPct = m.getCurrentCpuLoad() * 100;
double avgCpuLoadPct = m.getAverageCpuLoad() * 100;
long heapUsed = m.getHeapMemoryUsed();
long heapMax = m.getHeapMemoryMaximum();
double heapUsedPct = heapUsed * 100.0 / heapMax;
SB sb = new SB();
sb.a("Metrics [").
a("curCpuLoad=").a(dblFmt.format(cpuLoadPct)).a("%").
a(", avgCpuLoad=").a(dblFmt.format(avgCpuLoadPct)).a("%").
a(", heapUsed=").a(dblFmt.format(heapUsedPct)).a("%").
a("]");
log.info(sb.toString());
}
}
}, metricsLogFreq, metricsLogFreq);
}
ctx.performance().logSuggestions(log, gridName);
ackBenchmarks();
ackVisor();
ackStart(rtBean);
if (!isDaemon())
ctx.discovery().ackTopology();
// Send node start email notification, if enabled.
if (isSmtpEnabled() && isAdminEmailsSet() && cfg.isLifeCycleEmailNotification()) {
SB sb = new SB();
for (GridPortRecord rec : ctx.ports().records())
sb.a(rec.protocol()).a(":").a(rec.port()).a(" ");
String nid = localNode().id().toString().toUpperCase();
String nid8 = U.id8(localNode().id()).toUpperCase();
GridProductLicense lic = ctx.license().license();
String body =
"GridGain node started with the following parameters:" + NL +
NL +
"----" + NL +
"GridGain ver. " + VER + '#' + ctx.build() + "-sha1:" + REV_HASH + NL +
"Grid name: " + gridName + NL +
"Node ID: " + nid + NL +
"Node order: " + localNode().order() + NL +
"Node addresses: " + U.addressesAsString(localNode()) + NL +
"Local ports: " + sb + NL +
"OS name: " + U.osString() + NL +
"OS user: " + System.getProperty("user.name") + NL +
"CPU(s): " + localNode().metrics().getTotalCpus() + NL +
"Heap: " + U.heapSize(localNode(), 2) + "GB" + NL +
"JVM name: " + U.jvmName() + NL +
"JVM vendor: " + U.jvmVendor() + NL +
"JVM version: " + U.jvmVersion() + NL +
"VM name: " + rtBean.getName() + NL +
"License ID: " + lic.id().toString().toUpperCase() + NL +
"Licensed to: " + lic.userOrganization() + NL +
"----" + NL +
NL +
"NOTE:" + NL +
"This message is sent automatically to all configured admin emails." + NL +
"To change this behavior use 'lifeCycleEmailNotify' grid configuration property." +
NL + NL +
"| www.gridgain.com" + NL +
"| [email protected]" + NL;
sendAdminEmailAsync("GridGain node started: " + nid8, body, false);
}
}
/**
* Validates common configuration parameters.
*
* @param cfg Configuration.
*/
private void validateCommon(GridConfiguration cfg) {
A.notNull(cfg.getNodeId(), "cfg.getNodeId()");
A.notNull(cfg.getMBeanServer(), "cfg.getMBeanServer()");
A.notNull(cfg.getGridLogger(), "cfg.getGridLogger()");
A.notNull(cfg.getMarshaller(), "cfg.getMarshaller()");
A.notNull(cfg.getExecutorService(), "cfg.getExecutorService()");
A.notNull(cfg.getUserAttributes(), "cfg.getUserAttributes()");
// All SPIs should be non-null.
A.notNull(cfg.getSwapSpaceSpi(), "cfg.getSwapSpaceSpi()");
A.notNull(cfg.getCheckpointSpi(), "cfg.getCheckpointSpi()");
A.notNull(cfg.getCommunicationSpi(), "cfg.getCommunicationSpi()");
A.notNull(cfg.getDeploymentSpi(), "cfg.getDeploymentSpi()");
A.notNull(cfg.getDiscoverySpi(), "cfg.getDiscoverySpi()");
A.notNull(cfg.getEventStorageSpi(), "cfg.getEventStorageSpi()");
A.notNull(cfg.getAuthenticationSpi(), "cfg.getAuthenticationSpi()");
A.notNull(cfg.getSecureSessionSpi(), "cfg.getSecureSessionSpi()");
A.notNull(cfg.getCollisionSpi(), "cfg.getCollisionSpi()");
A.notNull(cfg.getFailoverSpi(), "cfg.getFailoverSpi()");
A.notNull(cfg.getLoadBalancingSpi(), "cfg.getLoadBalancingSpi()");
A.notNull(cfg.getIndexingSpi(), "cfg.getIndexingSpi()");
A.ensure(cfg.getNetworkTimeout() > 0, "cfg.getNetworkTimeout() > 0");
A.ensure(cfg.getNetworkSendRetryDelay() > 0, "cfg.getNetworkSendRetryDelay() > 0");
A.ensure(cfg.getNetworkSendRetryCount() > 0, "cfg.getNetworkSendRetryCount() > 0");
A.ensure(cfg.getDataCenterId() >= 0, "cfg.getDataCenterId() >= 0");
A.ensure(cfg.getDataCenterId() < MAX_DATA_CENTERS, "cfg.getDataCenterId() <= 31");
boolean hasHubCfg = cfg.getDrSenderHubConfiguration() != null ||
cfg.getDrReceiverHubConfiguration() != null;
if (!hasHubCfg)
for (GridCacheConfiguration cacheCfg : cfg.getCacheConfiguration()) {
if (cacheCfg.getDrSenderConfiguration() != null || cacheCfg.getDrReceiverConfiguration() != null) {
hasHubCfg = true;
break;
}
}
if (hasHubCfg)
A.ensure(cfg.getDataCenterId() != 0, "cfg.getDataCenterId() must have non-zero value if grid has " +
"send or receiver hub configuration.");
}
/**
* Checks whether physical RAM is not exceeded.
*/
private void checkPhysicalRam() {
long ram = ctx.discovery().localNode().attribute(ATTR_PHY_RAM);
if (ram != -1) {
String macs = ctx.discovery().localNode().attribute(ATTR_MACS);
long totalHeap = 0;
for (GridNode node : ctx.discovery().nodes()) {
if (macs.equals(node.attribute(ATTR_MACS))) {
long heap = node.metrics().getHeapMemoryMaximum();
if (heap != -1)
totalHeap += heap;
}
}
if (totalHeap > ram) {
U.quietAndWarn(log, "Attempting to start more nodes than physical RAM " +
"available on current host (this can cause significant slowdown)");
}
}
}
/**
* @param ctx Context.
* @param cfg Configuration to check for possible performance issues.
*/
private void suggestOptimizations(GridKernalContext ctx, GridConfiguration cfg) {
GridPerformanceSuggestions perf = ctx.performance();
if (ctx.collision().enabled())
perf.add("Disable collision resolution (remove 'collisionSpi' from configuration)");
if (ctx.checkpoint().enabled())
perf.add("Disable checkpoints (remove 'checkpointSpi' from configuration)");
if (cfg.isPeerClassLoadingEnabled())
perf.add("Disable peer class loading (set 'peerClassLoadingEnabled' to false)");
if (cfg.isMarshalLocalJobs())
perf.add("Disable local jobs marshalling (set 'marshalLocalJobs' to false)");
if (cfg.getIncludeEventTypes() != null && cfg.getIncludeEventTypes().length != 0)
perf.add("Disable grid events (remove 'includeEventTypes' from configuration)");
if (GridOptimizedMarshaller.available() && !(cfg.getMarshaller() instanceof GridOptimizedMarshaller))
perf.add("Enable optimized marshaller (set 'marshaller' to " +
GridOptimizedMarshaller.class.getSimpleName() + ')');
}
/**
* Creates attributes map and fills it in.
*
* @param cfg Grid configuration.
* @param build Build string.
* @return Map of all node attributes.
* @throws GridException thrown if was unable to set up attribute.
*/
@SuppressWarnings({"SuspiciousMethodCalls", "unchecked", "TypeMayBeWeakened"})
private Map createNodeAttributes(GridConfiguration cfg, String build) throws GridException {
Map attrs = new HashMap<>();
final String[] incProps = cfg.getIncludeProperties();
try {
// Stick all environment settings into node attributes.
attrs.putAll(F.view(System.getenv(), new P1() {
@Override public boolean apply(String name) {
return incProps == null || U.containsStringArray(incProps, name, true) ||
U.isVisorNodeStartProperty(name) || U.isVisorRequiredProperty(name);
}
}));
if (log.isDebugEnabled())
log.debug("Added environment properties to node attributes.");
}
catch (SecurityException e) {
throw new GridException("Failed to add environment properties to node attributes due to " +
"security violation: " + e.getMessage());
}
try {
// Stick all system properties into node's attributes overwriting any
// identical names from environment properties.
for (Map.Entry
© 2015 - 2025 Weber Informatics LLC | Privacy Policy