com.codeloom.ketty.ConfigurableServer Maven / Gradle / Ivy
package com.codeloom.ketty;
import java.io.File;
import java.net.*;
import java.util.Enumeration;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.joran.JoranConfigurator;
import ch.qos.logback.core.joran.spi.JoranException;
import com.codeloom.resource.ResourceFactory;
import com.codeloom.settings.CommandLine;
import com.codeloom.settings.PropertiesConstants;
import com.codeloom.settings.Settings;
import com.codeloom.util.BaseException;
import com.codeloom.util.Factory;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.util.resource.URLResourceFactory;
import org.eclipse.jetty.xml.XmlConfiguration;
import org.slf4j.ILoggerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ConfigurableServer implements KettyServer {
protected static final Logger LOG = LoggerFactory.getLogger(ConfigurableServer.class);
protected static final String LOGBACK_DEFAULT = "${ketty.home}/conf/logback.app.xml";
protected Server jettyServer = null;
protected void resetLogger(){
ILoggerFactory factory = LoggerFactory.getILoggerFactory();
LOG.info("Current logger factory is {}",factory);
if (factory instanceof LoggerContext) {
// 采用了logback实现
String conf = PropertiesConstants.getString(Settings.get(),
"logback.conf", LOGBACK_DEFAULT);
try {
LOG.info("Reset logback with file:{}",conf);
LoggerContext lc = (LoggerContext) factory;
JoranConfigurator configurator = new JoranConfigurator();
configurator.setContext(lc);
lc.reset();
configurator.doConfigure(conf);
} catch (JoranException e) {
LOG.error("Failed to reset logback.",e);
}
}
}
@Override
public void start(String[] args) throws Exception {
Settings settings = Settings.get();
// 确定ketty.home环境变量
String kettyHome = PropertiesConstants.getString(settings,"home","${ketty.home}");
if (StringUtils.isEmpty(kettyHome)){
kettyHome = System.getenv("KETTY_HOME");
if (StringUtils.isEmpty(kettyHome)){
throw new BaseException("Can not find ketty home.Check parameter:ketty.home or home");
}
}
PropertiesConstants.setString(settings,"ketty.home",kettyHome);
// 从CommandLine拷贝环境变量
settings.copyFrom(new CommandLine(args));
// 通过一些列的配置文件来初始化
String configFile = PropertiesConstants.getString(settings,"ketty.config",
"file:///${ketty.home}/conf/ketty.xml");
if (StringUtils.isNotEmpty(configFile)){
settings.addSettings(configFile);
}
String contextPath = PropertiesConstants.getString(settings,"context", "${server.context}");
if (StringUtils.isEmpty(contextPath)){
contextPath = kettyHome + File.separatorChar + "webapps" + File.separatorChar + "ROOT";
}
String port = PropertiesConstants.getString(settings,"port", "9000");
if (!isPortAvailable(port)){
throw new BaseException("Port is not available:" + port);
}
String app = PropertiesConstants.getString(settings,"app", "${server.app}");
if (StringUtils.isEmpty(app)){
throw new BaseException("Can not find app.Check parameter:app or server.app");
}
String contextRoot = PropertiesConstants.getString(settings,"contextRoot", "${server.contextRoot}");
if (StringUtils.isEmpty(contextRoot)){
contextRoot = PropertiesConstants.getString(settings,"vroot." + app,"/");
}
long mem = PropertiesConstants.getLong(settings, "mem", 0);
if (mem <= 0){
mem = Runtime.getRuntime().maxMemory() / 1000 / 1000;
}
long cores = PropertiesConstants.getLong(settings, "vcores", 0);
if (cores <= 0){
cores = Runtime.getRuntime().availableProcessors();
}
//保证temp和logs目录存在
String temp = PropertiesConstants.getString(settings,"ketty.temp.home","${ketty.home}/temp");
String logs = PropertiesConstants.getString(settings,"ketty.logs.home", "${ketty.home}/logs");
makeSureDirectoryExist(temp);
makeSureDirectoryExist(logs);
String jettyConfig = PropertiesConstants.getString(settings,"ketty.start", "file:///${ketty.home}/conf/start.xml");
String niName = PropertiesConstants.getString(settings, "ketty.ip.nic", "eth0");
try {
String ip = getHostIp(niName);
System.setProperty("server.ip", ip);
System.setProperty("server.port", port);
System.setProperty("server.mem", String.valueOf(mem));
System.setProperty("server.app", app);
System.setProperty("server.cores", String.valueOf(cores));
System.setProperty("server.context",contextPath);
System.setProperty("server.root", contextRoot);
System.setProperty("ketty.home", kettyHome);
String hostIp = System.getenv("KETTY_HOST");
if (StringUtils.isNotEmpty(hostIp) && !hostIp.equals(ip)){
//可能运行在容器中
System.setProperty("host.ip",hostIp);
System.setProperty("host.port",ip);
System.setProperty("host.app",app);
}else {
System.setProperty("host.ip",ip);
System.setProperty("host.port",port);
System.setProperty("host.app",app);
}
ResourceFactory rf = Settings.getResourceFactory();
URL url = rf.createURL(jettyConfig, null);
if (url == null){
throw new BaseException("Failed to load the start script:"+jettyConfig);
}
URLResourceFactory f = new URLResourceFactory();
LOG.info("Use xml configuration to start server");
LOG.info("URL = {}",jettyConfig);
XmlConfiguration xmlConfig = new XmlConfiguration(f.newResource(url));
jettyServer = (Server)xmlConfig.configure();
jettyServer.start();
}catch(Exception ex){
LOG.error("Failed to start jetty server",ex);
}
}
private void makeSureDirectoryExist(String path) {
if (StringUtils.isNotEmpty(path)){
File file = new File(path);
if (!file.exists()){
LOG.info("Dir {} does not exist. Creating.",path);
file.mkdirs();
}
}
}
public void join() throws Exception {
if (jettyServer != null){
resetLogger();
jettyServer.join();
}
}
public void stop() throws Exception {
if (jettyServer != null){
jettyServer.stop();
}
}
public static boolean isPortAvailable(String port){
try {
int p = Integer.parseInt(port);
ServerSocket socket = new ServerSocket(p);
socket.close();
return true;
}catch (Exception ex){
return false;
}
}
public static int getAvailablePort(int fromPort,int toPort){
ServerSocket socket = null;
for (int port = fromPort ; port < toPort ; port ++){
try {
socket = new ServerSocket(port);
socket.close();
LOG.info("Port is available,port = {}",port);
return port;
}catch (Exception ex){
LOG.info("Port is bound,try another.port = {}",port);
}
}
return 0;
}
public static String getHostIp(String name){
// get ip from env : KETTY_IP
String ip = System.getenv("KETTY_IP");
if (StringUtils.isNotEmpty(ip)){
return ip;
}
try {
InetAddress addr = InetAddress.getLocalHost();
return addr.getHostAddress();
}catch (Exception ex){
LOG.error("Can not get ip from Local Host");
}
if (StringUtils.isNotEmpty(name)){
ip = getIpByInterface(name);
if (StringUtils.isNotEmpty(ip)){
return ip;
}
}
LOG.info("Try to get ip from network interface.");
Enumeration interfaces = null;
try {
interfaces = NetworkInterface.getNetworkInterfaces();
}catch (Exception ex){
return "127.0.0.1";
}
while (interfaces.hasMoreElements()) {
NetworkInterface ni = interfaces.nextElement();
Enumeration addrs = ni.getInetAddresses();
while (addrs.hasMoreElements()){
InetAddress inetAddr = addrs.nextElement();
if (!inetAddr.isLoopbackAddress()){
return inetAddr.getHostAddress();
}
}
}
return "127.0.0.1";
}
public static String getIpByInterface(String name){
NetworkInterface ni;
try {
ni = NetworkInterface.getByName(name);
Enumeration addrs = ni.getInetAddresses();
while (addrs.hasMoreElements()){
InetAddress inetAddr = addrs.nextElement();
if (!inetAddr.isLoopbackAddress()
&& !inetAddr.isAnyLocalAddress()
&& !inetAddr.isLinkLocalAddress()
&& !inetAddr.isMulticastAddress()) {
return inetAddr.getHostAddress();
}
}
} catch (SocketException e) {
LOG.error("Can not get ip by interface name.");
}
return null;
}
public static void main(String [] args){
KettyServer server = new ConfigurableServer();
try {
server.start(args);
server.join();
}catch (Exception ex){
LOG.error("Failed to start ketty server.",ex);
}
}
}
© 2015 - 2026 Weber Informatics LLC | Privacy Policy