You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@slider.apache.org by bi...@apache.org on 2016/05/17 15:29:13 UTC
incubator-slider git commit: SLIDER-1121 fix slider AM port
allocation race condition
Repository: incubator-slider
Updated Branches:
refs/heads/develop 4b7d5c832 -> 55dd69dd3
SLIDER-1121 fix slider AM port allocation race condition
Project: http://git-wip-us.apache.org/repos/asf/incubator-slider/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-slider/commit/55dd69dd
Tree: http://git-wip-us.apache.org/repos/asf/incubator-slider/tree/55dd69dd
Diff: http://git-wip-us.apache.org/repos/asf/incubator-slider/diff/55dd69dd
Branch: refs/heads/develop
Commit: 55dd69dd36e743e645a67a53429c185dc4612307
Parents: 4b7d5c8
Author: Billie Rinaldi <bi...@gmail.com>
Authored: Tue May 17 06:57:29 2016 -0700
Committer: Billie Rinaldi <bi...@gmail.com>
Committed: Tue May 17 06:57:29 2016 -0700
----------------------------------------------------------------------
.../org/apache/slider/common/SliderKeys.java | 5 --
.../apache/slider/common/tools/PortScanner.java | 16 +----
.../apache/slider/common/tools/SliderUtils.java | 16 +++++
.../server/appmaster/SliderAppMaster.java | 63 ++++++++------------
.../appmaster/web/rest/agent/AgentWebApp.java | 35 ++++++++++-
5 files changed, 79 insertions(+), 56 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/55dd69dd/slider-core/src/main/java/org/apache/slider/common/SliderKeys.java
----------------------------------------------------------------------
diff --git a/slider-core/src/main/java/org/apache/slider/common/SliderKeys.java b/slider-core/src/main/java/org/apache/slider/common/SliderKeys.java
index 1d2d5f8..05c7048 100644
--- a/slider-core/src/main/java/org/apache/slider/common/SliderKeys.java
+++ b/slider-core/src/main/java/org/apache/slider/common/SliderKeys.java
@@ -266,11 +266,6 @@ public interface SliderKeys extends SliderXmlConfKeys {
* {@value}
*/
String KEY_ALLOWED_PORT_RANGE = "site.global.slider.allowed.ports";
-
- /**
- * Allowed port range
- */
- String KEY_AM_ALLOWED_PORT_RANGE = "slider.am.allowed.port.range";
/**
* env var for custom JVM options.
http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/55dd69dd/slider-core/src/main/java/org/apache/slider/common/tools/PortScanner.java
----------------------------------------------------------------------
diff --git a/slider-core/src/main/java/org/apache/slider/common/tools/PortScanner.java b/slider-core/src/main/java/org/apache/slider/common/tools/PortScanner.java
index b5b21ce..5b80f9f 100644
--- a/slider-core/src/main/java/org/apache/slider/common/tools/PortScanner.java
+++ b/slider-core/src/main/java/org/apache/slider/common/tools/PortScanner.java
@@ -19,6 +19,7 @@ package org.apache.slider.common.tools;
import org.apache.slider.common.SliderExitCodes;
import org.apache.slider.core.exceptions.SliderException;
+import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
@@ -39,8 +40,6 @@ public class PortScanner {
public PortScanner() {
}
- int nextPort = 1024;
-
public void setPortRange(String input) {
// first split based on commas
Set<Integer> inputPorts= new TreeSet<Integer>();
@@ -68,23 +67,14 @@ public class PortScanner {
return remainingPortsToCheck;
}
- public int getAvailablePort() throws SliderException {
+ public int getAvailablePort() throws SliderException, IOException {
if (remainingPortsToCheck != null) {
return getAvailablePortViaPortArray();
} else {
- return getAvailablePortViaCounter();
+ return SliderUtils.getOpenPort();
}
}
- private int getAvailablePortViaCounter() throws SliderException {
- int port;
- do {
- port = nextPort;
- nextPort++;
- } while (!SliderUtils.isPortAvailable(port));
- return port;
- }
-
private int getAvailablePortViaPortArray() throws SliderException {
boolean found = false;
int availablePort = -1;
http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/55dd69dd/slider-core/src/main/java/org/apache/slider/common/tools/SliderUtils.java
----------------------------------------------------------------------
diff --git a/slider-core/src/main/java/org/apache/slider/common/tools/SliderUtils.java b/slider-core/src/main/java/org/apache/slider/common/tools/SliderUtils.java
index eae80f5..746e468 100644
--- a/slider-core/src/main/java/org/apache/slider/common/tools/SliderUtils.java
+++ b/slider-core/src/main/java/org/apache/slider/common/tools/SliderUtils.java
@@ -1114,6 +1114,22 @@ public final class SliderUtils {
}
/**
+ * Get a random open port
+ * @return true if the port was available for listening on
+ */
+ public static int getOpenPort() throws IOException {
+ ServerSocket socket = null;
+ try {
+ socket = new ServerSocket(0);
+ return socket.getLocalPort();
+ } finally {
+ if (socket != null) {
+ socket.close();
+ }
+ }
+ }
+
+ /**
* See if a port is available for listening on by trying to listen
* on it and seeing if that works or fails.
* @param port port to listen to
http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/55dd69dd/slider-core/src/main/java/org/apache/slider/server/appmaster/SliderAppMaster.java
----------------------------------------------------------------------
diff --git a/slider-core/src/main/java/org/apache/slider/server/appmaster/SliderAppMaster.java b/slider-core/src/main/java/org/apache/slider/server/appmaster/SliderAppMaster.java
index 8d30da7..0776a6c 100644
--- a/slider-core/src/main/java/org/apache/slider/server/appmaster/SliderAppMaster.java
+++ b/slider-core/src/main/java/org/apache/slider/server/appmaster/SliderAppMaster.java
@@ -404,11 +404,6 @@ public class SliderAppMaster extends AbstractSliderLaunchedService
private SecurityConfiguration securityConfiguration;
/**
- * The port for the web application
- */
- private int webAppPort;
-
- /**
* Is security enabled?
* Set early on in the {@link #createAndRunCluster(String)} operation.
*/
@@ -776,11 +771,23 @@ public class SliderAppMaster extends AbstractSliderLaunchedService
uploadServerCertForLocalization(clustername, fs);
}
- webAppPort = getPortToRequest();
- if (webAppPort == 0) {
- // failure to find a port
- throw new BadConfigException("Failed to fix a web application port");
- }
+ // Web service endpoints: initialize
+ WebAppApiImpl webAppApi =
+ new WebAppApiImpl(
+ stateForProviders,
+ providerService,
+ certificateManager,
+ registryOperations,
+ metricsAndMonitoring,
+ actionQueues,
+ this,
+ contentCache);
+ initAMFilterOptions(serviceConf);
+
+ // start the agent web app
+ startAgentWebApp(appInformation, serviceConf, webAppApi);
+ int webAppPort = deployWebApplication(webAppApi);
+
String scheme = WebAppUtils.HTTP_PREFIX;
appMasterTrackingUrl = scheme + appMasterHostname + ":" + webAppPort;
@@ -926,7 +933,7 @@ public class SliderAppMaster extends AbstractSliderLaunchedService
Path tmpDirPath = new Path(amTmpDir);
Path launcherTmpDirPath = new Path(tmpDirPath, rolesTmpSubdir);
fs.getFileSystem().mkdirs(launcherTmpDirPath);
-
+
//launcher service
launchService = new RoleLaunchService(actionQueues,
providerService,
@@ -972,25 +979,6 @@ public class SliderAppMaster extends AbstractSliderLaunchedService
scheduleEscalation(instanceDefinition.getInternal());
try {
-
- // Web service endpoints: initialize
-
- WebAppApiImpl webAppApi =
- new WebAppApiImpl(
- stateForProviders,
- providerService,
- certificateManager,
- registryOperations,
- metricsAndMonitoring,
- actionQueues,
- this,
- contentCache);
- initAMFilterOptions(serviceConf);
-
- // start the agent web app
- startAgentWebApp(appInformation, serviceConf, webAppApi);
- deployWebApplication(webAppPort, webAppApi);
-
// schedule YARN Registry registration
queue(new ActionRegisterServiceInstance(clustername, appid));
@@ -1051,7 +1039,7 @@ public class SliderAppMaster extends AbstractSliderLaunchedService
}
/**
- * List the node reports: uses {@link #yarnClient} as the login user
+ * List the node reports: uses {@link SliderYarnClientImpl} as the login user
* @param yarnClient client to the RM
* @return the node reports
* @throws IOException
@@ -1083,17 +1071,18 @@ public class SliderAppMaster extends AbstractSliderLaunchedService
* Creates and starts the web application, and adds a
* <code>WebAppService</code> service under the AM, to ensure
* a managed web application shutdown.
- * @param port port to deploy the web application on
* @param webAppApi web app API instance
+ * @return port the web application is deployed on
* @throws IOException general problems starting the webapp (network, etc)
* @throws WebAppException other issues
*/
- private void deployWebApplication(int port, WebAppApiImpl webAppApi)
- throws IOException {
+ private int deployWebApplication(WebAppApiImpl webAppApi)
+ throws IOException, SliderException {
try {
webApp = new SliderAMWebApp(webAppApi);
HttpConfig.Policy policy = HttpConfig.Policy.HTTP_ONLY;
+ int port = getPortToRequest();
log.info("Launching web application at port {} with policy {}", port, policy);
WebApps.$for(SliderAMWebApp.BASE_PATH,
@@ -1101,7 +1090,7 @@ public class SliderAppMaster extends AbstractSliderLaunchedService
webAppApi,
RestPaths.WS_CONTEXT)
.withHttpPolicy(getConfig(), policy)
- .at(port)
+ .at("0.0.0.0", port, true)
.inDevMode()
.start(webApp);
@@ -1109,6 +1098,7 @@ public class SliderAppMaster extends AbstractSliderLaunchedService
new WebAppService<>("slider", webApp);
deployChildService(webAppService);
+ return webApp.port();
} catch (WebAppException e) {
if (e.getCause() instanceof IOException) {
throw (IOException)e.getCause();
@@ -1167,8 +1157,7 @@ public class SliderAppMaster extends AbstractSliderLaunchedService
* @return the port to request.
* @throws SliderException
*/
- private int getPortToRequest()
- throws SliderException {
+ private int getPortToRequest() throws SliderException, IOException {
return portScanner.getAvailablePort();
}
http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/55dd69dd/slider-core/src/main/java/org/apache/slider/server/appmaster/web/rest/agent/AgentWebApp.java
----------------------------------------------------------------------
diff --git a/slider-core/src/main/java/org/apache/slider/server/appmaster/web/rest/agent/AgentWebApp.java b/slider-core/src/main/java/org/apache/slider/server/appmaster/web/rest/agent/AgentWebApp.java
index 200fbc2..3a3b0c0 100644
--- a/slider-core/src/main/java/org/apache/slider/server/appmaster/web/rest/agent/AgentWebApp.java
+++ b/slider-core/src/main/java/org/apache/slider/server/appmaster/web/rest/agent/AgentWebApp.java
@@ -25,7 +25,6 @@ import com.sun.jersey.spi.inject.SingletonTypeInjectableProvider;
import org.apache.slider.core.conf.MapOperations;
import org.apache.slider.providers.agent.AgentKeys;
import org.apache.slider.server.appmaster.web.WebAppApi;
-import org.apache.slider.server.appmaster.web.rest.RestPaths;
import org.apache.slider.server.services.security.SecurityUtils;
import org.mortbay.jetty.Connector;
import org.mortbay.jetty.Server;
@@ -40,6 +39,7 @@ import javax.ws.rs.ext.Provider;
import java.io.Closeable;
import java.io.File;
import java.io.IOException;
+import java.net.BindException;
import java.util.Set;
/**
@@ -91,6 +91,7 @@ public class AgentWebApp implements Closeable {
new QueuedThreadPool(
configsMap.getOptionInt("agent.threadpool.size.max", 25)));
agentServer.setStopAtShutdown(true);
+ agentServer.setGracefulShutdown(1000);
SslSelectChannelConnector ssl1WayConnector = createSSLConnector(false, port);
SslSelectChannelConnector ssl2WayConnector =
@@ -115,6 +116,7 @@ public class AgentWebApp implements Closeable {
agentRoot.addServlet(agent, "/*");
try {
+ openListeners();
agentServer.start();
} catch (IOException e) {
LOG.error("Unable to start agent server", e);
@@ -131,6 +133,37 @@ public class AgentWebApp implements Closeable {
}
+ private void openListeners() throws Exception {
+ // from HttpServer2.openListeners()
+ for (Connector listener : agentServer.getConnectors()) {
+ if (listener.getLocalPort() != -1) {
+ // This listener is either started externally or has been bound
+ continue;
+ }
+ int port = listener.getPort();
+ while (true) {
+ // jetty has a bug where you can't reopen a listener that previously
+ // failed to open w/o issuing a close first, even if the port is changed
+ try {
+ listener.close();
+ listener.open();
+ LOG.info("Jetty bound to port " + listener.getLocalPort());
+ break;
+ } catch (BindException ex) {
+ if (port == 0) {
+ BindException be = new BindException("Port in use: "
+ + listener.getHost() + ":" + listener.getPort());
+ be.initCause(ex);
+ throw be;
+ }
+ }
+ // try the next port number
+ listener.setPort(++port);
+ Thread.sleep(100);
+ }
+ }
+ }
+
private SslSelectChannelConnector createSSLConnector(boolean needClientAuth, int port) {
SslSelectChannelConnector sslConnector = new
SslSelectChannelConnector();