Make cluster request timeout to be configurable

This commit is contained in:
Kelven Yang 2011-07-14 18:11:32 -07:00
parent d11ac32f08
commit 61676ff3ea
5 changed files with 64 additions and 41 deletions

View File

@ -32,6 +32,8 @@ import javax.naming.ConfigurationException;
import org.apache.log4j.Logger;
import com.cloud.cluster.dao.ManagementServerHostDao;
import com.cloud.configuration.Config;
import com.cloud.configuration.dao.ConfigurationDao;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.PropertiesUtil;
import com.cloud.utils.component.ComponentLocator;
@ -40,15 +42,21 @@ import com.cloud.utils.component.ComponentLocator;
public class ClusterServiceServletAdapter implements ClusterServiceAdapter {
private static final Logger s_logger = Logger.getLogger(ClusterServiceServletAdapter.class);
private static final int DEFAULT_SERVICE_PORT = 9090;
private static final int DEFAULT_SERVICE_PORT = 9090;
private static final int DEFAULT_REQUEST_TIMEOUT = 300; // 300 seconds
private ClusterManager manager;
private ClusterManager _manager;
private ManagementServerHostDao _mshostDao;
private ConfigurationDao _configDao;
private ManagementServerHostDao _mshostDao;
private ClusterServiceServletContainer _servletContainer;
private String _name;
private int _clusterServicePort = DEFAULT_SERVICE_PORT;
private int _clusterServicePort = DEFAULT_SERVICE_PORT;
private int _clusterRequestTimeoutSeconds = DEFAULT_REQUEST_TIMEOUT;
@Override
public ClusterService getPeerService(String strPeer) throws RemoteException {
@ -63,7 +71,7 @@ public class ClusterServiceServletAdapter implements ClusterServiceAdapter {
if(serviceUrl == null)
return null;
return new ClusterServiceServletImpl(serviceUrl);
return new ClusterServiceServletImpl(serviceUrl, _clusterRequestTimeoutSeconds);
}
@Override
@ -111,7 +119,7 @@ public class ClusterServiceServletAdapter implements ClusterServiceAdapter {
@Override
public boolean start() {
_servletContainer = new ClusterServiceServletContainer();
_servletContainer.start(new ClusterServiceServletHttpHandler(manager), _clusterServicePort);
_servletContainer.start(new ClusterServiceServletHttpHandler(_manager), _clusterServicePort);
return true;
}
@ -128,13 +136,24 @@ public class ClusterServiceServletAdapter implements ClusterServiceAdapter {
ComponentLocator locator = ComponentLocator.getCurrentLocator();
manager = locator.getManager(ClusterManager.class);
if(manager == null)
_manager = locator.getManager(ClusterManager.class);
if(_manager == null)
throw new ConfigurationException("Unable to get " + ClusterManager.class.getName());
_mshostDao = locator.getDao(ManagementServerHostDao.class);
if(_mshostDao == null)
throw new ConfigurationException("Unable to get " + ManagementServerHostDao.class.getName());
if(_mshostDao == null)
throw new ConfigurationException("Unable to get " + ManagementServerHostDao.class.getName());
_configDao = locator.getDao(ConfigurationDao.class);
if(_configDao == null)
throw new ConfigurationException("Unable to get " + ConfigurationDao.class.getName());
String value = _configDao.getValue(Config.ClusterMessageTimeOutSeconds.key());
_clusterRequestTimeoutSeconds = NumbersUtil.parseInt(value, DEFAULT_REQUEST_TIMEOUT);
s_logger.info("Configure cluster request time out. timeout: " + _clusterRequestTimeoutSeconds + " seconds");
File dbPropsFile = PropertiesUtil.findConfigFile("db.properties");
Properties dbProps = new Properties();
@ -145,7 +164,7 @@ public class ClusterServiceServletAdapter implements ClusterServiceAdapter {
} catch (IOException e) {
throw new ConfigurationException("Unable to load db.properties content");
}
_clusterServicePort = NumbersUtil.parseInt(dbProps.getProperty("cluster.servlet.port"), DEFAULT_SERVICE_PORT);
if(s_logger.isInfoEnabled())
s_logger.info("Cluster servlet port : " + _clusterServicePort);

View File

@ -34,30 +34,33 @@ import com.google.gson.Gson;
public class ClusterServiceServletImpl implements ClusterService {
private static final long serialVersionUID = 4574025200012566153L;
private static final Logger s_logger = Logger.getLogger(ClusterServiceServletImpl.class);
private static int HTTP_DATA_TIMEOUT = 60000;
private String serviceUrl;
private String _serviceUrl;
private final Gson gson;
private final Gson _gson;
private int _requestTimeoutSeconds;
public ClusterServiceServletImpl() {
gson = GsonHelper.getGson();
_gson = GsonHelper.getGson();
}
public ClusterServiceServletImpl(String serviceUrl) {
this.serviceUrl = serviceUrl;
public ClusterServiceServletImpl(String serviceUrl, int requestTimeoutSeconds) {
s_logger.info("Setup cluster service servlet. service url: " + serviceUrl + ", request timeout: " + requestTimeoutSeconds + " seconds");
this._serviceUrl = serviceUrl;
this._requestTimeoutSeconds = requestTimeoutSeconds;
gson = GsonHelper.getGson();
_gson = GsonHelper.getGson();
}
@Override
public String execute(String callingPeer, long agentId, String gsonPackage, boolean stopOnError) throws RemoteException {
if(s_logger.isDebugEnabled()) {
s_logger.debug("Post (sync-call) " + gsonPackage + " to " + serviceUrl + " for agent " + agentId + " from " + callingPeer);
s_logger.debug("Post (sync-call) " + gsonPackage + " to " + _serviceUrl + " for agent " + agentId + " from " + callingPeer);
}
HttpClient client = getHttpClient();
PostMethod method = new PostMethod(serviceUrl);
PostMethod method = new PostMethod(_serviceUrl);
method.addParameter("method", Integer.toString(RemoteMethodConstants.METHOD_EXECUTE));
method.addParameter("agentId", Long.toString(agentId));
@ -71,11 +74,11 @@ public class ClusterServiceServletImpl implements ClusterService {
public long executeAsync(String callingPeer, long agentId, String gsonPackage, boolean stopOnError) throws RemoteException {
if(s_logger.isDebugEnabled()) {
s_logger.debug("Post (Async-call) " + gsonPackage + " to " + serviceUrl + " for agent " + agentId + " from " + callingPeer);
s_logger.debug("Post (Async-call) " + gsonPackage + " to " + _serviceUrl + " for agent " + agentId + " from " + callingPeer);
}
HttpClient client = getHttpClient();
PostMethod method = new PostMethod(serviceUrl);
PostMethod method = new PostMethod(_serviceUrl);
method.addParameter("method", Integer.toString(RemoteMethodConstants.METHOD_EXECUTE_ASYNC));
method.addParameter("agentId", Long.toString(agentId));
@ -85,15 +88,15 @@ public class ClusterServiceServletImpl implements ClusterService {
String result = executePostMethod(client, method);
if(result == null) {
s_logger.error("Empty return from remote async-execution on " + serviceUrl);
throw new RemoteException("Invalid result returned from async-execution on peer : " + serviceUrl);
s_logger.error("Empty return from remote async-execution on " + _serviceUrl);
throw new RemoteException("Invalid result returned from async-execution on peer : " + _serviceUrl);
}
try {
return gson.fromJson(result, Long.class);
return _gson.fromJson(result, Long.class);
} catch(Throwable e) {
s_logger.error("Unable to parse executeAsync return : " + result);
throw new RemoteException("Invalid result returned from async-execution on peer : " + serviceUrl);
throw new RemoteException("Invalid result returned from async-execution on peer : " + _serviceUrl);
}
}
@ -105,7 +108,7 @@ public class ClusterServiceServletImpl implements ClusterService {
+ ", seq: " + seq + ", gsonPackage: " + gsonPackage);
}
HttpClient client = getHttpClient();
PostMethod method = new PostMethod(serviceUrl);
PostMethod method = new PostMethod(_serviceUrl);
method.addParameter("method", Integer.toString(RemoteMethodConstants.METHOD_ASYNC_RESULT));
method.addParameter("agentId", Long.toString(agentId));
@ -130,11 +133,11 @@ public class ClusterServiceServletImpl implements ClusterService {
@Override
public boolean ping(String callingPeer) throws RemoteException {
if(s_logger.isDebugEnabled()) {
s_logger.debug("Ping at " + serviceUrl);
s_logger.debug("Ping at " + _serviceUrl);
}
HttpClient client = getHttpClient();
PostMethod method = new PostMethod(serviceUrl);
PostMethod method = new PostMethod(_serviceUrl);
method.addParameter("method", Integer.toString(RemoteMethodConstants.METHOD_PING));
method.addParameter("callingPeer", callingPeer);
@ -154,20 +157,20 @@ public class ClusterServiceServletImpl implements ClusterService {
if(response == HttpStatus.SC_OK) {
result = method.getResponseBodyAsString();
if(s_logger.isDebugEnabled()) {
s_logger.debug("POST " + serviceUrl + " response :" + result + ", responding time: "
s_logger.debug("POST " + _serviceUrl + " response :" + result + ", responding time: "
+ (System.currentTimeMillis() - startTick) + " ms");
}
} else {
s_logger.error("Invalid response code : " + response + ", from : "
+ serviceUrl + ", method : " + method.getParameter("method")
+ _serviceUrl + ", method : " + method.getParameter("method")
+ " responding time: " + (System.currentTimeMillis() - startTick));
}
} catch (HttpException e) {
s_logger.error("HttpException from : " + serviceUrl + ", method : " + method.getParameter("method"));
s_logger.error("HttpException from : " + _serviceUrl + ", method : " + method.getParameter("method"));
} catch (IOException e) {
s_logger.error("IOException from : " + serviceUrl + ", method : " + method.getParameter("method"));
s_logger.error("IOException from : " + _serviceUrl + ", method : " + method.getParameter("method"));
} catch(Throwable e) {
s_logger.error("Exception from : " + serviceUrl + ", method : " + method.getParameter("method") + ", exception :", e);
s_logger.error("Exception from : " + _serviceUrl + ", method : " + method.getParameter("method") + ", exception :", e);
}
return result;
@ -176,7 +179,7 @@ public class ClusterServiceServletImpl implements ClusterService {
private HttpClient getHttpClient() {
HttpClient client = new HttpClient();
HttpClientParams clientParams = new HttpClientParams();
clientParams.setSoTimeout(HTTP_DATA_TIMEOUT);
clientParams.setSoTimeout(this._requestTimeoutSeconds * 1000);
client.setParams(clientParams);
return client;
@ -184,7 +187,7 @@ public class ClusterServiceServletImpl implements ClusterService {
// for test purpose only
public static void main(String[] args) {
ClusterServiceServletImpl service = new ClusterServiceServletImpl("http://localhost:9090/clusterservice");
ClusterServiceServletImpl service = new ClusterServiceServletImpl("http://localhost:9090/clusterservice", 300);
try {
String result = service.execute("test", 1, "{ p1:v1, p2:v2 }", true);
System.out.println(result);

View File

@ -236,8 +236,9 @@ public enum Config {
AgentLbEnable("Advanced", ClusterManager.class, Boolean.class, "agent.lb.enabled", "true", "If agent load balancing enabled in cluster setup", null),
SubDomainNetworkAccess("Advanced", NetworkManager.class, Boolean.class, "allow.subdomain.network.access", "true", "Allow subdomains to use networks dedicated to their parent domain(s)", null),
EncodeApiResponse("Advanced", ManagementServer.class, Boolean.class, "encode.api.response", "false", "Do UTF-8 encoding for the api response, false by default", null);
EncodeApiResponse("Advanced", ManagementServer.class, Boolean.class, "encode.api.response", "false", "Do UTF-8 encoding for the api response, false by default", null),
ClusterMessageTimeOutSeconds("Advanced", ManagementServer.class, Integer.class, "cluster.message.timeout.seconds", "300", "Time (in seconds) to wait before a inter-management server message post times out.", null);
private final String _category;
private final Class<?> _componentClass;

View File

@ -1,8 +1,3 @@
INSERT INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'default.page.size', '500', 'Default page size for API list* commands');
DELETE FROM `cloud`.`op_host_capacity` WHERE `capacity_type` in (2,6);
INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'vmware.management.portgroup', 'Management Network', 'Specify the management network name(for ESXi hosts)');
INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'vmware.additional.vnc.portrange.start', '59000', 'Start port number of additional VNC port range');
INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'vmware.additional.vnc.portrange.size', '1000', 'Start port number of additional VNC port range');
INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Console Proxy', 'DEFAULT', 'AgentManager', 'consoleproxy.management.state', 'Auto', 'console proxy service management state');
INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Console Proxy', 'DEFAULT', 'AgentManager', 'consoleproxy.management.state.last', 'Auto', 'last console proxy service management state');

View File

@ -139,4 +139,9 @@ CREATE INDEX `i_op_lock__mac_ip_thread` on `op_lock` (`mac`, `ip`, `thread`);
UPDATE `cloud`.`mshost` set removed=NULL where removed IS NOT NULL;
INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'vmware.management.portgroup', 'Management Network', 'Specify the management network name(for ESXi hosts)');
INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'vmware.additional.vnc.portrange.start', '59000', 'Start port number of additional VNC port range');
INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'vmware.additional.vnc.portrange.size', '1000', 'Start port number of additional VNC port range');
INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Console Proxy', 'DEFAULT', 'AgentManager', 'consoleproxy.management.state', 'Auto', 'console proxy service management state');
INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Console Proxy', 'DEFAULT', 'AgentManager', 'consoleproxy.management.state.last', 'Auto', 'last console proxy service management state');
INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'cluster.message.timeout.seconds', '300', 'Time (in seconds) to wait before a inter-management server message post times out.');