From 0cd7c3433311ebf848efddcb2449346c132d5133 Mon Sep 17 00:00:00 2001 From: jason Date: Fri, 28 Sep 2018 18:48:49 +0800 Subject: [PATCH] Add: * VersionUtil to get version from jar * NetUtil to get available port to bind conveniently Fix: * LogBase repackage and support variable arguments * SentinelConfig remove duplicated JVM properties overriding --- sentinel-core/pom.xml | 17 +++- .../com/alibaba/csp/sentinel/Constants.java | 3 +- .../csp/sentinel/config/SentinelConfig.java | 17 ++-- .../csp/sentinel/log/CommandCenterLog.java | 19 ++-- .../com/alibaba/csp/sentinel/log/LogBase.java | 23 +++++ .../alibaba/csp/sentinel/log/RecordLog.java | 18 ++-- .../csp/sentinel/util/VersionUtil.java | 21 +++++ .../csp/sentinel/util/VersionUtilTest.java | 15 +++ .../sentinel-transport-common/pom.xml | 5 + .../csp/sentinel/transport/util/NetUtil.java | 94 +++++++++++++++++++ .../sentinel/transport/util/NetUtilTest.java | 31 ++++++ .../transport/command/netty/HttpServer.java | 8 ++ .../command/SimpleHttpCommandCenter.java | 46 +++------ 13 files changed, 250 insertions(+), 67 deletions(-) create mode 100644 sentinel-core/src/main/java/com/alibaba/csp/sentinel/util/VersionUtil.java create mode 100644 sentinel-core/src/test/java/com/alibaba/csp/sentinel/util/VersionUtilTest.java create mode 100644 sentinel-transport/sentinel-transport-common/src/main/java/com/alibaba/csp/sentinel/transport/util/NetUtil.java create mode 100644 sentinel-transport/sentinel-transport-common/src/test/java/com/alibaba/csp/sentinel/transport/util/NetUtilTest.java diff --git a/sentinel-core/pom.xml b/sentinel-core/pom.xml index 1bdea1c1c6..14c192eef8 100755 --- a/sentinel-core/pom.xml +++ b/sentinel-core/pom.xml @@ -24,5 +24,20 @@ test - + + + + org.apache.maven.plugins + maven-jar-plugin + 3.0.2 + + + + ${project.version} + + + + + + \ No newline at end of file diff --git a/sentinel-core/src/main/java/com/alibaba/csp/sentinel/Constants.java b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/Constants.java index 8e727dba7c..1a1d5e9a78 100755 --- a/sentinel-core/src/main/java/com/alibaba/csp/sentinel/Constants.java +++ b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/Constants.java @@ -20,6 +20,7 @@ import com.alibaba.csp.sentinel.node.EntranceNode; import com.alibaba.csp.sentinel.slotchain.StringResourceWrapper; import com.alibaba.csp.sentinel.slots.system.SystemRule; +import com.alibaba.csp.sentinel.util.VersionUtil; /** * @author qinan.qn @@ -28,7 +29,7 @@ */ public final class Constants { - public static final String SENTINEL_VERSION = "0.2.1"; + public static final String SENTINEL_VERSION = VersionUtil.getVersion("0.2.1"); public final static int MAX_CONTEXT_NAME_SIZE = 2000; public final static int MAX_SLOT_CHAIN_SIZE = 6000; diff --git a/sentinel-core/src/main/java/com/alibaba/csp/sentinel/config/SentinelConfig.java b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/config/SentinelConfig.java index d5017f13df..c3f8a27239 100755 --- a/sentinel-core/src/main/java/com/alibaba/csp/sentinel/config/SentinelConfig.java +++ b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/config/SentinelConfig.java @@ -77,15 +77,6 @@ private static void loadProps() { for (Object key : fileProps.keySet()) { SentinelConfig.setConfig((String)key, (String)fileProps.get(key)); - try { - String systemValue = System.getProperty((String)key); - if (!StringUtil.isEmpty(systemValue)) { - SentinelConfig.setConfig((String)key, systemValue); - } - } catch (Exception e) { - RecordLog.info(e.getMessage(), e); - } - RecordLog.info(key + " value: " + SentinelConfig.getConfig((String)key)); } } } catch (Throwable ioe) { @@ -94,7 +85,13 @@ private static void loadProps() { // JVM parameter override file config. for (Map.Entry entry : System.getProperties().entrySet()) { - SentinelConfig.setConfig(entry.getKey().toString(), entry.getValue().toString()); + String configKey = entry.getKey().toString(); + String configValue = entry.getValue().toString(); + String configValueOld = getConfig(configKey); + SentinelConfig.setConfig(configKey, configValue); + if (configValueOld != null) { + RecordLog.info("JVM parameter overrides {0}: {1} -> {2}", configKey, configValueOld, configValue); + } } } diff --git a/sentinel-core/src/main/java/com/alibaba/csp/sentinel/log/CommandCenterLog.java b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/log/CommandCenterLog.java index f5f34243b5..563b1066dd 100755 --- a/sentinel-core/src/main/java/com/alibaba/csp/sentinel/log/CommandCenterLog.java +++ b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/log/CommandCenterLog.java @@ -40,18 +40,19 @@ public static void resetLogBaseDir(String baseDir) { logHandler = makeLogger(FILE_NAME, heliumRecordLog); } - public static void info(String msg) { - LoggerUtils.disableOtherHandlers(heliumRecordLog, logHandler); - heliumRecordLog.log(Level.INFO, msg); + public static void info(String detail, Object... params) { + log(heliumRecordLog, logHandler, Level.INFO, detail, params); } - public static void info(String msg, Throwable e) { - LoggerUtils.disableOtherHandlers(heliumRecordLog, logHandler); - heliumRecordLog.log(Level.INFO, msg, e); + public static void info(String detail, Throwable e) { + log(heliumRecordLog, logHandler, Level.INFO, detail, e); } - public static void warn(String msg, Throwable e) { - LoggerUtils.disableOtherHandlers(heliumRecordLog, logHandler); - heliumRecordLog.log(Level.WARNING, msg, e); + public static void warn(String detail, Object... params) { + log(heliumRecordLog, logHandler, Level.WARNING, detail, params); + } + + public static void warn(String detail, Throwable e) { + log(heliumRecordLog, logHandler, Level.WARNING, detail, e); } } diff --git a/sentinel-core/src/main/java/com/alibaba/csp/sentinel/log/LogBase.java b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/log/LogBase.java index 3d8e58ff7e..d646abb792 100755 --- a/sentinel-core/src/main/java/com/alibaba/csp/sentinel/log/LogBase.java +++ b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/log/LogBase.java @@ -24,7 +24,10 @@ import com.alibaba.csp.sentinel.util.PidUtil; /** + * Add support for placeholders in java.util.logging + * * @author leyou + * @author jason */ public class LogBase { public static final String LOG_CHARSET = "utf-8"; @@ -36,6 +39,26 @@ public class LogBase { String userHome = System.getProperty(USER_HOME); setLogBaseDir(userHome); } + + protected static void log(Logger logger, Handler handler, Level level, String detail, Object... params) { + if (detail == null) { + return; + } + LoggerUtils.disableOtherHandlers(logger, handler); + if (params.length == 0) { + logger.log(level, detail); + } else { + logger.log(level, detail, params); + } + } + + protected static void log(Logger logger, Handler handler, Level level, String detail, Throwable throwable) { + if (detail == null) { + return; + } + LoggerUtils.disableOtherHandlers(logger, handler); + logger.log(level, detail, throwable); + } /** * Get log file base directory path, the returned path is guaranteed end with {@link File#separator} diff --git a/sentinel-core/src/main/java/com/alibaba/csp/sentinel/log/RecordLog.java b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/log/RecordLog.java index 3c4db12f92..ca8fa84c45 100755 --- a/sentinel-core/src/main/java/com/alibaba/csp/sentinel/log/RecordLog.java +++ b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/log/RecordLog.java @@ -32,7 +32,7 @@ public class RecordLog extends LogBase { static { logHandler = makeLogger(FILE_NAME, heliumRecordLog); } - + /** * Change log dir, the dir will be created if not exits */ @@ -41,23 +41,19 @@ public static void resetLogBaseDir(String baseDir) { logHandler = makeLogger(FILE_NAME, heliumRecordLog); } - public static void info(String detail) { - LoggerUtils.disableOtherHandlers(heliumRecordLog, logHandler); - heliumRecordLog.log(Level.INFO, detail); + public static void info(String detail, Object... params) { + log(heliumRecordLog, logHandler, Level.INFO, detail, params); } public static void info(String detail, Throwable e) { - LoggerUtils.disableOtherHandlers(heliumRecordLog, logHandler); - heliumRecordLog.log(Level.INFO, detail, e); + log(heliumRecordLog, logHandler, Level.INFO, detail, e); } - public static void warn(String detail) { - LoggerUtils.disableOtherHandlers(heliumRecordLog, logHandler); - heliumRecordLog.log(Level.WARNING, detail); + public static void warn(String detail, Object... params) { + log(heliumRecordLog, logHandler, Level.WARNING, detail, params); } public static void warn(String detail, Throwable e) { - LoggerUtils.disableOtherHandlers(heliumRecordLog, logHandler); - heliumRecordLog.log(Level.WARNING, detail, e); + log(heliumRecordLog, logHandler, Level.WARNING, detail, e); } } diff --git a/sentinel-core/src/main/java/com/alibaba/csp/sentinel/util/VersionUtil.java b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/util/VersionUtil.java new file mode 100644 index 0000000000..6351461f66 --- /dev/null +++ b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/util/VersionUtil.java @@ -0,0 +1,21 @@ +package com.alibaba.csp.sentinel.util; + +import com.alibaba.csp.sentinel.log.RecordLog; + +/** + * Get Sentinel version from MANIFEST.MF + * + * @author jason @ Sep 28, 2018 + * + */ +public class VersionUtil { + public static String getVersion(String defaultVersion) { + try { + String version = VersionUtil.class.getPackage().getImplementationVersion(); + return version == null || version.length() == 0 ? defaultVersion : version; + } catch (Throwable e) { + RecordLog.warn("return default version, ignore exception", e); + return defaultVersion; + } + } +} diff --git a/sentinel-core/src/test/java/com/alibaba/csp/sentinel/util/VersionUtilTest.java b/sentinel-core/src/test/java/com/alibaba/csp/sentinel/util/VersionUtilTest.java new file mode 100644 index 0000000000..069667ff77 --- /dev/null +++ b/sentinel-core/src/test/java/com/alibaba/csp/sentinel/util/VersionUtilTest.java @@ -0,0 +1,15 @@ +package com.alibaba.csp.sentinel.util; + +import org.junit.Assert; +import org.junit.Test; + +public class VersionUtilTest { + @Test + public void versionTest() { + String version = VersionUtil.getVersion("1.0"); + /** + * manifest cannot be load before package + */ + Assert.assertEquals("1.0", version); + } +} diff --git a/sentinel-transport/sentinel-transport-common/pom.xml b/sentinel-transport/sentinel-transport-common/pom.xml index 227b6d4f50..61cafe718b 100755 --- a/sentinel-transport/sentinel-transport-common/pom.xml +++ b/sentinel-transport/sentinel-transport-common/pom.xml @@ -20,5 +20,10 @@ com.alibaba fastjson + + junit + junit + test + \ No newline at end of file diff --git a/sentinel-transport/sentinel-transport-common/src/main/java/com/alibaba/csp/sentinel/transport/util/NetUtil.java b/sentinel-transport/sentinel-transport-common/src/main/java/com/alibaba/csp/sentinel/transport/util/NetUtil.java new file mode 100644 index 0000000000..2ecdb900e3 --- /dev/null +++ b/sentinel-transport/sentinel-transport-common/src/main/java/com/alibaba/csp/sentinel/transport/util/NetUtil.java @@ -0,0 +1,94 @@ +package com.alibaba.csp.sentinel.transport.util; + +import java.io.IOException; +import java.net.ServerSocket; + +/** + * net utils for transporting + * + * @author jason @ Sep 28, 2018 + * + */ +public class NetUtil { + + /** + * Get a server socket from an avaliable port from a base port.
+ * Increasement on port number will happen when the port has already been + * used.
+ *

+ * To avoid infinite loop 200 attemps will be made in most.
+ * Default backlog is 100. + * + * @param port + * @return null for error + */ + public static ServerSocket getServerSocketFromBasePort(int port) { + return getServerSocketFromBasePort(port, 100, 200); + } + + /** + * Get a server socket from an avaliable port from a base port.
+ * Increasement on port number will happen when the port has already been + * used.
+ *

+ * To avoid infinite loop 200 attemps will be made in most. + * + * @param port + * @param backlog + * @return null for error + */ + public static ServerSocket getServerSocketFromBasePort(int port, int backlog) { + return getServerSocketFromBasePort(port, backlog, 200); + } + + /** + * Get a server socket from an avaliable port from a base port.
+ * Increasement on port number will happen when the port has already been + * used.
+ * + * @param port + * @param backlog + * @param tries + * total count of increasement + * @return + */ + public static ServerSocket getServerSocketFromBasePort(int port, int backlog, int tries) { + while (tries-- > 0) { + try { + return new ServerSocket(port++, backlog); + } catch (IOException e) { + } + } + return null; + } + + /** + * Get an available port to bind with maximum 200 tries + * + * @param port + * @return 0 for failure + */ + public static int getAvailablePortFromBase(int port) { + return getAvailablePortFromBase(port, 200); + } + + /** + * Get an available port to bind + * + * @param port + * @param maxTries + * @return 0 for failure + */ + public static int getAvailablePortFromBase(int port, int maxTries) { + ServerSocket serverSocket = getServerSocketFromBasePort(port, 50, maxTries); + if (serverSocket != null) { + int finalPort = serverSocket.getLocalPort(); + try { + serverSocket.close(); + } catch (IOException e) { + } + return finalPort; + } + return 0; + } +} diff --git a/sentinel-transport/sentinel-transport-common/src/test/java/com/alibaba/csp/sentinel/transport/util/NetUtilTest.java b/sentinel-transport/sentinel-transport-common/src/test/java/com/alibaba/csp/sentinel/transport/util/NetUtilTest.java new file mode 100644 index 0000000000..2e34ca1849 --- /dev/null +++ b/sentinel-transport/sentinel-transport-common/src/test/java/com/alibaba/csp/sentinel/transport/util/NetUtilTest.java @@ -0,0 +1,31 @@ +package com.alibaba.csp.sentinel.transport.util; + +import java.io.IOException; +import java.net.ServerSocket; + +import org.junit.Assert; +import org.junit.Test; + +public class NetUtilTest { + @Test + public void availablePortTest() { + // get a port first + int port = NetUtil.getAvailablePortFromBase(3000, 5000); + Assert.assertTrue(port > 0); + // try to create a socket based on it (should be just use it) + ServerSocket serverSocket = NetUtil.getServerSocketFromBasePort(port); + Assert.assertNotNull(serverSocket); + Assert.assertEquals(port, serverSocket.getLocalPort()); + // get a port based on it again while the socket working, + // a new greater port will be returned + int portNew = NetUtil.getAvailablePortFromBase(port); + Assert.assertTrue(portNew > port); + // close the socket and fetch again, same port will be returned + try { + serverSocket.close(); + } catch (IOException e) { + } + portNew = NetUtil.getAvailablePortFromBase(port); + Assert.assertEquals(portNew, port); + } +} diff --git a/sentinel-transport/sentinel-transport-netty-http/src/main/java/com/alibaba/csp/sentinel/transport/command/netty/HttpServer.java b/sentinel-transport/sentinel-transport-netty-http/src/main/java/com/alibaba/csp/sentinel/transport/command/netty/HttpServer.java index 3ad0f65bac..8bd7687de3 100755 --- a/sentinel-transport/sentinel-transport-netty-http/src/main/java/com/alibaba/csp/sentinel/transport/command/netty/HttpServer.java +++ b/sentinel-transport/sentinel-transport-netty-http/src/main/java/com/alibaba/csp/sentinel/transport/command/netty/HttpServer.java @@ -20,6 +20,7 @@ import java.util.concurrent.ConcurrentHashMap; import com.alibaba.csp.sentinel.transport.config.TransportConfig; +import com.alibaba.csp.sentinel.transport.util.NetUtil; import com.alibaba.csp.sentinel.command.CommandHandler; import com.alibaba.csp.sentinel.log.CommandCenterLog; import com.alibaba.csp.sentinel.util.StringUtil; @@ -33,6 +34,7 @@ /** * @author Eric Zhao */ +@SuppressWarnings("rawtypes") public final class HttpServer { private static final int DEFAULT_PORT = 8719; @@ -57,9 +59,15 @@ public void start() throws Exception { } else { port = Integer.parseInt(TransportConfig.getPort()); } + // find a really available one + port = NetUtil.getAvailablePortFromBase(port); } catch (Exception e) { throw new IllegalArgumentException("Illegal port: " + TransportConfig.getPort()); } + if (port == 0) { + throw new RuntimeException("Could not determine the transport server port"); + } + TransportConfig.setRuntimePort(port); channel = b.bind(port).sync().channel(); channel.closeFuture().sync(); } finally { diff --git a/sentinel-transport/sentinel-transport-simple-http/src/main/java/com/alibaba/csp/sentinel/transport/command/SimpleHttpCommandCenter.java b/sentinel-transport/sentinel-transport-simple-http/src/main/java/com/alibaba/csp/sentinel/transport/command/SimpleHttpCommandCenter.java index f073ccaf75..ec5e3fde0c 100755 --- a/sentinel-transport/sentinel-transport-simple-http/src/main/java/com/alibaba/csp/sentinel/transport/command/SimpleHttpCommandCenter.java +++ b/sentinel-transport/sentinel-transport-simple-http/src/main/java/com/alibaba/csp/sentinel/transport/command/SimpleHttpCommandCenter.java @@ -38,6 +38,7 @@ import com.alibaba.csp.sentinel.transport.CommandCenter; import com.alibaba.csp.sentinel.transport.command.http.HttpEventTask; import com.alibaba.csp.sentinel.transport.config.TransportConfig; +import com.alibaba.csp.sentinel.transport.util.NetUtil; import com.alibaba.csp.sentinel.util.StringUtil; /*** @@ -45,6 +46,7 @@ * * @author youji.zj */ +@SuppressWarnings("rawtypes") public class SimpleHttpCommandCenter implements CommandCenter { private static final int PORT_UNINITIALIZED = -1; @@ -94,50 +96,24 @@ public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { @Override public void run() { - int repeat = 0; - - int tmpPort = port; boolean success = false; - while (true) { - ServerSocket serverSocket = null; - try { - serverSocket = new ServerSocket(tmpPort); - } catch (IOException ex) { - CommandCenterLog.info( - String.format("IO error occurs, port: %d, repeat times: %d", tmpPort, repeat), ex); + ServerSocket serverSocket = NetUtil.getServerSocketFromBasePort(port); - tmpPort = adjustPort(repeat); - try { - TimeUnit.SECONDS.sleep(5); - } catch (InterruptedException e1) { - break; - } - repeat++; - } - - if (serverSocket != null) { - CommandCenterLog.info("[CommandCenter] Begin listening at port " + serverSocket.getLocalPort()); - socketReference = serverSocket; - executor.submit(new ServerThread(serverSocket)); - success = true; - break; - } + if (serverSocket != null) { + CommandCenterLog.info("[CommandCenter] Begin listening at port " + serverSocket.getLocalPort()); + socketReference = serverSocket; + executor.submit(new ServerThread(serverSocket)); + success = true; } if (!success) { - tmpPort = PORT_UNINITIALIZED; + port = PORT_UNINITIALIZED; } - TransportConfig.setRuntimePort(tmpPort); + + TransportConfig.setRuntimePort(port); executor.shutdown(); } - /** - * Adjust the port to settle down. - */ - private int adjustPort(int repeat) { - int mod = repeat / 5; - return port + mod; - } }; new Thread(serverInitTask).start();