-
Notifications
You must be signed in to change notification settings - Fork 7.3k
[ZOOKEEPER-3473] Improving successful TLS handshake throughput with concurrent control #1027
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -19,11 +19,49 @@ | |
| package org.apache.zookeeper.server; | ||
|
|
||
| import java.net.InetSocketAddress; | ||
| import java.util.concurrent.CountDownLatch; | ||
| import java.util.concurrent.LinkedBlockingQueue; | ||
| import java.util.concurrent.TimeUnit; | ||
| import java.util.concurrent.atomic.AtomicInteger; | ||
| import org.apache.zookeeper.PortAssignment; | ||
| import org.apache.zookeeper.WatchedEvent; | ||
| import org.apache.zookeeper.Watcher; | ||
| import org.apache.zookeeper.ZooKeeper; | ||
| import org.apache.zookeeper.common.ClientX509Util; | ||
| import org.apache.zookeeper.server.metric.SimpleCounter; | ||
| import org.apache.zookeeper.test.ClientBase; | ||
| import org.apache.zookeeper.test.SSLAuthTest; | ||
| import org.hamcrest.Matchers; | ||
| import org.junit.Assert; | ||
| import org.junit.Test; | ||
| import org.slf4j.Logger; | ||
| import org.slf4j.LoggerFactory; | ||
|
|
||
| public class NettyServerCnxnFactoryTest { | ||
|
|
||
| public class NettyServerCnxnFactoryTest extends ClientBase { | ||
|
|
||
| private static final Logger LOG = LoggerFactory | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do you use logging in tests?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To print the useful information which is useful for debugging unexpected test behavior. Do you suggest to use System.out ?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I usually don't output anything in (unit)tests, but feel free to leave it there if it's comfortable. |
||
| .getLogger(NettyServerCnxnFactoryTest.class); | ||
|
|
||
| final LinkedBlockingQueue<ZooKeeper> zks = new LinkedBlockingQueue<ZooKeeper>(); | ||
|
|
||
| @Override | ||
| public void setUp() throws Exception { | ||
| System.setProperty(ServerCnxnFactory.ZOOKEEPER_SERVER_CNXN_FACTORY, | ||
lvfangmin marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| "org.apache.zookeeper.server.NettyServerCnxnFactory"); | ||
| super.setUp(); | ||
| } | ||
|
|
||
| @Override | ||
| public void tearDown() throws Exception { | ||
| System.clearProperty(ServerCnxnFactory.ZOOKEEPER_SERVER_CNXN_FACTORY); | ||
|
|
||
| // clean up | ||
| for (ZooKeeper zk : zks) { | ||
| zk.close(); | ||
| } | ||
| super.tearDown(); | ||
| } | ||
|
|
||
| @Test | ||
| public void testRebind() throws Exception { | ||
|
|
@@ -58,4 +96,63 @@ public void testRebindIPv4IPv6() throws Exception { | |
| Assert.assertTrue(factory.getParentChannel().isActive()); | ||
| } | ||
|
|
||
| @Test | ||
| public void testOutstandingHandshakeLimit() throws Exception { | ||
|
|
||
| SimpleCounter tlsHandshakeExceeded = (SimpleCounter) ServerMetrics.getMetrics().TLS_HANDSHAKE_EXCEEDED; | ||
| tlsHandshakeExceeded.reset(); | ||
| Assert.assertEquals(tlsHandshakeExceeded.get(), 0); | ||
|
|
||
| ClientX509Util x509Util = SSLAuthTest.setUpSecure(); | ||
| NettyServerCnxnFactory factory = (NettyServerCnxnFactory) serverFactory; | ||
| factory.setSecure(true); | ||
| factory.setOutstandingHandshakeLimit(10); | ||
|
|
||
| int threadNum = 3; | ||
| int cnxnPerThread = 10; | ||
| Thread[] cnxnWorker = new Thread[threadNum]; | ||
|
|
||
| AtomicInteger cnxnCreated = new AtomicInteger(0); | ||
| CountDownLatch latch = new CountDownLatch(1); | ||
|
|
||
| for (int i = 0; i < cnxnWorker.length; i++) { | ||
| cnxnWorker[i] = new Thread() { | ||
| @Override | ||
| public void run() { | ||
| for (int i = 0; i < cnxnPerThread; i++) { | ||
| try { | ||
| zks.add(new ZooKeeper(hostPort, 3000, new Watcher() { | ||
| @Override | ||
| public void process(WatchedEvent event) { | ||
| int created = cnxnCreated.addAndGet(1); | ||
| if (created == threadNum * cnxnPerThread) { | ||
| latch.countDown(); | ||
| } | ||
| } | ||
| })); | ||
| } catch (Exception e) { | ||
| LOG.info("Error while creating zk client", e); | ||
| } | ||
| } | ||
| } | ||
| }; | ||
| cnxnWorker[i].start(); | ||
| } | ||
|
|
||
| Assert.assertThat(latch.await(3, TimeUnit.SECONDS), Matchers.is(true)); | ||
| LOG.info("created {} connections", threadNum * cnxnPerThread); | ||
|
|
||
| // Assert throttling not 0 | ||
| long handshakeThrottledNum = tlsHandshakeExceeded.get(); | ||
| LOG.info("TLS_HANDSHAKE_EXCEEDED: {}", handshakeThrottledNum); | ||
| Assert.assertThat("The number of handshake throttled should be " | ||
| + "greater than 0", handshakeThrottledNum, Matchers.greaterThan(0L)); | ||
|
|
||
| // Assert there is no outstanding handshake anymore | ||
| int outstandingHandshakeNum = factory.getOutstandingHandshakeNum(); | ||
| LOG.info("outstanding handshake is {}", outstandingHandshakeNum); | ||
| Assert.assertThat("The outstanding handshake number should be 0 " | ||
| + "after all cnxns established", outstandingHandshakeNum, Matchers.is(0)); | ||
|
|
||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds like something that should be turned on all the time with some meaningful default value. What do you think about setting it to 250 by default and let this property to override it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This feature hasn't been fully rollout internally, I would suggest to enable this by default, when we verified on our internal environment for a while, so if there is bug we can find it and fix it before its affecting the community.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a master-only patch which doesn't even have an alpha-release, so I believe we could be a little bit more flexible about that, but I'm also happy with leaving it off.