Skip to content

Commit

Permalink
ZOOKEEPER-3037 - Add unit test and various improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
nkalmar committed Apr 10, 2019
1 parent f309757 commit 6c07f45
Show file tree
Hide file tree
Showing 3 changed files with 148 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -224,14 +224,16 @@ public ZooKeeperServer(FileTxnSnapLog txnLogFactory, int tickTime,

/**
* Adds JvmPauseMonitor and calls
* {@link #ZooKeeperServer(FileTxnSnapLog, int, int, int, ZKDatabase)}
* {@link #ZooKeeperServer(FileTxnSnapLog, int, int, int, int, ZKDatabase)}
*
*/
public ZooKeeperServer(JvmPauseMonitor jvmPauseMonitor, FileTxnSnapLog txnLogFactory, int tickTime,
int minSessionTimeout, int maxSessionTimeout, ZKDatabase zkDb) {
this(txnLogFactory, tickTime, minSessionTimeout, maxSessionTimeout, zkDb);
int minSessionTimeout, int maxSessionTimeout, int clientPortListenBacklog, ZKDatabase zkDb) {
this(txnLogFactory, tickTime, minSessionTimeout, maxSessionTimeout, clientPortListenBacklog, zkDb);
this.jvmPauseMonitor = jvmPauseMonitor;
LOG.info("Added JvmPauseMonitor to server");
if(jvmPauseMonitor != null) {
LOG.info("Added JvmPauseMonitor to server");
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,17 +46,17 @@ public class JvmPauseMonitor {
public static final String JVM_PAUSE_MONITOR_FEATURE_SWITCH_KEY = "jvm.pause.monitor";

/** The target sleep time */
private long sleepTimeMs = SLEEP_TIME_MS_DEFAULT;
protected long sleepTimeMs;
public static final String SLEEP_TIME_MS_KEY = "jvm.pause.sleep.time.ms";
public static final long SLEEP_TIME_MS_DEFAULT = 500;

/** log WARN if we detect a pause longer than this threshold */
private long warnThresholdMs = WARN_THRESHOLD_DEFAULT;
protected long warnThresholdMs;
public static final String WARN_THRESHOLD_KEY = "jvm.pause.warn-threshold.ms";
public static final long WARN_THRESHOLD_DEFAULT = 10000;

/** log INFO if we detect a pause longer than this threshold */
private long infoThresholdMs = INFO_THRESHOLD_DEFAULT;
protected long infoThresholdMs;
public static final String INFO_THRESHOLD_KEY = "jvm.pause.info-threshold.ms";
public static final long INFO_THRESHOLD_DEFAULT = 1000;

Expand Down Expand Up @@ -128,10 +128,11 @@ private String formatMessage(long extraSleepTime,
}
}

String ret = "Detected pause in JVM or host machine (eg GC): " +
"pause of approximately " + extraSleepTime + "ms\n";
String ret = "Detected pause in JVM or host machine (eg GC): pause of approximately " + extraSleepTime
+ "ms, total pause: info level: " + numGcInfoThresholdExceeded
+ ", warn level: " + numGcWarnThresholdExceeded + "\n";
if (gcDiffs.isEmpty()) {
ret += "No GCs detected";
ret += ("No GCs detected");
} else {
ret += String.join("\n", gcDiffs);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.zookeeper.server.util;

import org.apache.zookeeper.server.ServerConfig;
import org.apache.zookeeper.server.quorum.QuorumPeerConfig;
import org.junit.Assert;
import org.junit.Test;

import java.io.File;
import java.io.IOException;
import java.util.Properties;

public class JvmPauseMonitorTest {

@Test
public void testJvmPauseMonitorInit() {
final Long sleepTime = 444L;
final Long warnTH = 5555L;
final Long infoTH = 555L;

ServerConfig serverConfig = new ServerConfig();
QuorumPeerConfig quorumPeerConfig = new QuorumPeerConfig();

Assert.assertEquals(false, serverConfig.isJvmPauseMonitorToRun());
Assert.assertEquals(false, quorumPeerConfig.isJvmPauseMonitorToRun());

Properties zkProp = new Properties();
zkProp.setProperty("dataDir", new File("myDataDir").getAbsolutePath());
zkProp.setProperty("jvm.pause.monitor", "true");
zkProp.setProperty("jvm.pause.sleep.time.ms", sleepTime.toString());
zkProp.setProperty("jvm.pause.warn-threshold.ms", warnTH.toString());
zkProp.setProperty("jvm.pause.info-threshold.ms", infoTH.toString());
try {
quorumPeerConfig.parseProperties(zkProp);
} catch (IOException | QuorumPeerConfig.ConfigException e) {
Assert.fail("Exception while reading config for JvmPauseMonitor");
}
serverConfig.readFrom(quorumPeerConfig);

Assert.assertEquals(true, serverConfig.isJvmPauseMonitorToRun());
Assert.assertEquals(true, quorumPeerConfig.isJvmPauseMonitorToRun());

JvmPauseMonitor pauseMonitor = new JvmPauseMonitor(serverConfig);
Assert.assertFalse(pauseMonitor.isStarted());
pauseMonitor.serviceStart();
Assert.assertTrue(pauseMonitor.isStarted());

Assert.assertEquals(sleepTime, Long.valueOf(pauseMonitor.sleepTimeMs));
Assert.assertEquals(warnTH, Long.valueOf(pauseMonitor.warnThresholdMs));
Assert.assertEquals(infoTH, Long.valueOf(pauseMonitor.infoThresholdMs));
}

@Test
public void testJvmPauseMonitorExceedInfoThreshold() throws InterruptedException {
final Long sleepTime = 100L;
final Long infoTH = -1L;

ServerConfig serverConfig = new ServerConfig();
QuorumPeerConfig quorumPeerConfig = new QuorumPeerConfig();

Properties zkProp = new Properties();
zkProp.setProperty("dataDir", new File("myDataDir").getAbsolutePath());
zkProp.setProperty("jvm.pause.monitor", "true");
zkProp.setProperty("jvm.pause.sleep.time.ms", sleepTime.toString());
zkProp.setProperty("jvm.pause.info-threshold.ms", infoTH.toString());
try {
quorumPeerConfig.parseProperties(zkProp);
} catch (IOException | QuorumPeerConfig.ConfigException e) {
Assert.fail("Exception while reading config for JvmPauseMonitor");
}
serverConfig.readFrom(quorumPeerConfig);

JvmPauseMonitor pauseMonitor = new JvmPauseMonitor(serverConfig);
pauseMonitor.serviceStart();

Assert.assertEquals(sleepTime, Long.valueOf(pauseMonitor.sleepTimeMs));
Assert.assertEquals(infoTH, Long.valueOf(pauseMonitor.infoThresholdMs));

Thread.sleep(1000);

Assert.assertNotEquals(0L, pauseMonitor.getNumGcInfoThresholdExceeded());
Assert.assertEquals(0L, pauseMonitor.getNumGcWarnThresholdExceeded());
Assert.assertNotEquals(0L, pauseMonitor.getTotalGcExtraSleepTime());
}

@Test
public void testJvmPauseMonitorExceedWarnThreshold() throws InterruptedException {
final Long sleepTime = 100L;
final Long warnTH = -1L;

ServerConfig serverConfig = new ServerConfig();
QuorumPeerConfig quorumPeerConfig = new QuorumPeerConfig();

Properties zkProp = new Properties();
zkProp.setProperty("dataDir", new File("myDataDir").getAbsolutePath());
zkProp.setProperty("jvm.pause.monitor", "true");
zkProp.setProperty("jvm.pause.sleep.time.ms", sleepTime.toString());
zkProp.setProperty("jvm.pause.warn-threshold.ms", warnTH.toString());
try {
quorumPeerConfig.parseProperties(zkProp);
} catch (IOException | QuorumPeerConfig.ConfigException e) {
Assert.fail("Exception while reading config for JvmPauseMonitor");
}
serverConfig.readFrom(quorumPeerConfig);

JvmPauseMonitor pauseMonitor = new JvmPauseMonitor(serverConfig);
pauseMonitor.serviceStart();

Assert.assertEquals(sleepTime, Long.valueOf(pauseMonitor.sleepTimeMs));
Assert.assertEquals(warnTH, Long.valueOf(pauseMonitor.warnThresholdMs));

Thread.sleep(1000);

Assert.assertEquals(0L, pauseMonitor.getNumGcInfoThresholdExceeded());
Assert.assertNotEquals(0L, pauseMonitor.getNumGcWarnThresholdExceeded());
Assert.assertNotEquals(0L, pauseMonitor.getTotalGcExtraSleepTime());
}
}

0 comments on commit 6c07f45

Please sign in to comment.