HBASE-22963 Netty ByteBuf leak in rpc client implementation (#577)
Signed-off-by: Michael Stack <stack@apache.org>
This commit is contained in:
parent
d8e5c87cf8
commit
693f201f3d
|
@ -463,6 +463,7 @@ public abstract class AbstractRpcClient<T extends RpcConnection> implements RpcC
|
|||
+ connection.remoteId);
|
||||
connections.removeValue(remoteId, connection);
|
||||
connection.shutdown();
|
||||
connection.cleanupConnection();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,6 +48,7 @@ import org.apache.hadoop.hbase.testclassification.LargeTests;
|
|||
import org.apache.hadoop.hbase.util.Bytes;
|
||||
import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
|
||||
import org.apache.hadoop.hbase.util.ManualEnvironmentEdge;
|
||||
import org.junit.After;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Assert;
|
||||
import org.junit.BeforeClass;
|
||||
|
@ -59,6 +60,9 @@ import org.junit.rules.TestName;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.apache.hbase.thirdparty.io.netty.util.ResourceLeakDetector;
|
||||
import org.apache.hbase.thirdparty.io.netty.util.ResourceLeakDetector.Level;
|
||||
|
||||
/**
|
||||
* This class is for testing {@link Connection}.
|
||||
*/
|
||||
|
@ -81,6 +85,7 @@ public class TestConnection {
|
|||
|
||||
@BeforeClass
|
||||
public static void setUpBeforeClass() throws Exception {
|
||||
ResourceLeakDetector.setLevel(Level.PARANOID);
|
||||
TEST_UTIL.getConfiguration().setBoolean(HConstants.STATUS_PUBLISHED, true);
|
||||
// Up the handlers; this test needs more than usual.
|
||||
TEST_UTIL.getConfiguration().setInt(HConstants.REGION_SERVER_HIGH_PRIORITY_HANDLER_COUNT, 10);
|
||||
|
@ -95,6 +100,11 @@ public class TestConnection {
|
|||
TEST_UTIL.shutdownMiniCluster();
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws IOException {
|
||||
TEST_UTIL.getAdmin().balancerSwitch(true, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Naive test to check that Connection#getAdmin returns a properly constructed HBaseAdmin object
|
||||
* @throws IOException Unable to construct admin
|
||||
|
@ -125,7 +135,7 @@ public class TestConnection {
|
|||
TableName tableName = TableName.valueOf("HCM-testConnectionClose" + allowsInterrupt);
|
||||
TEST_UTIL.createTable(tableName, FAM_NAM).close();
|
||||
|
||||
boolean previousBalance = TEST_UTIL.getAdmin().balancerSwitch(false, true);
|
||||
TEST_UTIL.getAdmin().balancerSwitch(false, true);
|
||||
|
||||
Configuration c2 = new Configuration(TEST_UTIL.getConfiguration());
|
||||
// We want to work on a separate connection.
|
||||
|
@ -190,9 +200,9 @@ public class TestConnection {
|
|||
RpcClient rpcClient = ((AsyncConnectionImpl) connection.toAsyncConnection()).rpcClient;
|
||||
|
||||
LOG.info("Going to cancel connections. connection=" + connection.toString() + ", sn=" + sn);
|
||||
for (int i = 0; i < 5000; i++) {
|
||||
for (int i = 0; i < 500; i++) {
|
||||
rpcClient.cancelConnections(sn);
|
||||
Thread.sleep(5);
|
||||
Thread.sleep(50);
|
||||
}
|
||||
|
||||
step.compareAndSet(1, 2);
|
||||
|
@ -207,7 +217,6 @@ public class TestConnection {
|
|||
table.close();
|
||||
connection.close();
|
||||
Assert.assertTrue("Unexpected exception is " + failed.get(), failed.get() == null);
|
||||
TEST_UTIL.getAdmin().balancerSwitch(previousBalance, true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -382,4 +391,22 @@ public class TestConnection {
|
|||
conn.getTable(tableName).coprocessorService(MultiRowMutationService.class,
|
||||
HConstants.EMPTY_START_ROW, HConstants.EMPTY_END_ROW, callable);
|
||||
}
|
||||
|
||||
// There is no assertion, but you need to confirm that there is no resource leak output from netty
|
||||
@Test
|
||||
public void testCancelConnectionMemoryLeak() throws IOException, InterruptedException {
|
||||
TableName tableName = TableName.valueOf(name.getMethodName());
|
||||
TEST_UTIL.createTable(tableName, FAM_NAM).close();
|
||||
TEST_UTIL.getAdmin().balancerSwitch(false, true);
|
||||
try (Connection connection = ConnectionFactory.createConnection(TEST_UTIL.getConfiguration());
|
||||
Table table = connection.getTable(tableName)) {
|
||||
table.get(new Get(Bytes.toBytes("1")));
|
||||
ServerName sn = TEST_UTIL.getRSForFirstRegionInTable(tableName).getServerName();
|
||||
RpcClient rpcClient = ((AsyncConnectionImpl) connection.toAsyncConnection()).rpcClient;
|
||||
rpcClient.cancelConnections(sn);
|
||||
Thread.sleep(1000);
|
||||
System.gc();
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
2
pom.xml
2
pom.xml
|
@ -1564,10 +1564,12 @@
|
|||
<hbase-surefire.argLine>-enableassertions -Dhbase.build.id=${build.id} -Xmx${surefire.Xmx}
|
||||
-Djava.security.egd=file:/dev/./urandom -Djava.net.preferIPv4Stack=true
|
||||
-Djava.awt.headless=true -Djdk.net.URLClassPath.disableClassPathURLCheck=true
|
||||
-Dorg.apache.hbase.thirdparty.io.netty.leakDetection.level=paranoid
|
||||
</hbase-surefire.argLine>
|
||||
<hbase-surefire.cygwin-argLine>-enableassertions -Xmx${surefire.cygwinXmx}
|
||||
-Djava.security.egd=file:/dev/./urandom -Djava.net.preferIPv4Stack=true
|
||||
"-Djava.library.path=${hadoop.library.path};${java.library.path}"
|
||||
-Dorg.apache.hbase.thirdparty.io.netty.leakDetection.level=paranoid
|
||||
</hbase-surefire.cygwin-argLine>
|
||||
<!-- Surefire argLine defaults to Linux, cygwin argLine is used in the os.windows profile -->
|
||||
<argLine>${hbase-surefire.argLine}</argLine>
|
||||
|
|
Loading…
Reference in New Issue