From 630642b65decbfdf575131eae8785050a0ae78bb Mon Sep 17 00:00:00 2001 From: jasonjoo2010 Date: Tue, 16 Oct 2018 11:23:53 +0800 Subject: [PATCH] Enhancements in transport-netty-http and properties related (#161) * sentinel-transport-netty-http will also retry when port specified has been used * LogBase support variable arguments * Remove duplicated JVM properties overriding in SentinelConfig * Add VersionUtil to get version from jar --- pom.xml | 10 +++ sentinel-core/pom.xml | 16 +++- .../com/alibaba/csp/sentinel/Constants.java | 3 +- .../csp/sentinel/config/SentinelConfig.java | 17 ++-- .../csp/sentinel/log/CommandCenterLog.java | 20 ++--- .../com/alibaba/csp/sentinel/log/LogBase.java | 20 +++++ .../alibaba/csp/sentinel/log/RecordLog.java | 18 ++--- .../csp/sentinel/util/VersionUtil.java | 36 +++++++++ .../csp/sentinel/util/VersionUtilTest.java | 15 ++++ .../sentinel-transport-common/pom.xml | 5 ++ .../transport/command/netty/HttpServer.java | 35 +++++++- .../command/SimpleHttpCommandCenter.java | 79 ++++++++++--------- 12 files changed, 204 insertions(+), 70 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 diff --git a/pom.xml b/pom.xml index 19d558bc81..bc7fb82b9a 100755 --- a/pom.xml +++ b/pom.xml @@ -58,6 +58,7 @@ 2.8.2 1.6 0.8.1 + 3.1.0 @@ -182,6 +183,15 @@ + + + + org.apache.maven.plugins + maven-jar-plugin + ${maven.jar.version} + + + diff --git a/sentinel-core/pom.xml b/sentinel-core/pom.xml index 1bdea1c1c6..eba0078231 100755 --- a/sentinel-core/pom.xml +++ b/sentinel-core/pom.xml @@ -24,5 +24,19 @@ test - + + + + org.apache.maven.plugins + maven-jar-plugin + + + + ${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 e80c59ef48..29dee61ce7 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 @@ -32,18 +32,20 @@ public class CommandCenterLog extends LogBase { 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 detail, Throwable e) { + log(heliumRecordLog, logHandler, Level.INFO, detail, e); } - public static void info(String msg, Throwable e) { - LoggerUtils.disableOtherHandlers(heliumRecordLog, logHandler); - heliumRecordLog.log(Level.INFO, msg, e); + public static void warn(String detail, Object... params) { + log(heliumRecordLog, logHandler, Level.WARNING, detail, params); } - public static void warn(String msg, Throwable e) { - LoggerUtils.disableOtherHandlers(heliumRecordLog, logHandler); - heliumRecordLog.log(Level.WARNING, msg, e); + 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 78f2bae125..4274a807ef 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 @@ -61,6 +61,26 @@ private static String addSeparator(String logDir) { } return logDir; } + + 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 1832759c5f..5ba3e97991 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,24 +32,20 @@ public class RecordLog extends LogBase { static { 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..80a6eb274c --- /dev/null +++ b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/util/VersionUtil.java @@ -0,0 +1,36 @@ +/* + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.csp.sentinel.util; + +import com.alibaba.csp.sentinel.log.RecordLog; + +/** + * Get Sentinel version from MANIFEST.MF + * + * @author jason + * @since 0.2.1 + */ +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-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..95a77090b2 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 @@ -18,14 +18,17 @@ import java.util.Map; import java.util.Map.Entry; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.TimeUnit; -import com.alibaba.csp.sentinel.transport.config.TransportConfig; import com.alibaba.csp.sentinel.command.CommandHandler; import com.alibaba.csp.sentinel.log.CommandCenterLog; +import com.alibaba.csp.sentinel.log.RecordLog; +import com.alibaba.csp.sentinel.transport.config.TransportConfig; import com.alibaba.csp.sentinel.util.StringUtil; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.Channel; +import io.netty.channel.ChannelFuture; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.nio.NioServerSocketChannel; @@ -33,6 +36,7 @@ /** * @author Eric Zhao */ +@SuppressWarnings("rawtypes") public final class HttpServer { private static final int DEFAULT_PORT = 8719; @@ -60,13 +64,40 @@ public void start() throws Exception { } catch (Exception e) { throw new IllegalArgumentException("Illegal port: " + TransportConfig.getPort()); } - channel = b.bind(port).sync().channel(); + + int retryCount = 0; + ChannelFuture channelFuture = null; + // loop for an successful binding + while (true) { + int newPort = getNewPort(port, retryCount); + try { + channelFuture = b.bind(newPort).sync(); + TransportConfig.setRuntimePort(newPort); + break; + } catch (Exception e) { + TimeUnit.MILLISECONDS.sleep(30); + RecordLog.warn("netty server bind error, port={0}, retry={1}", newPort, retryCount); + retryCount ++; + } + } + channel = channelFuture.channel(); channel.closeFuture().sync(); } finally { workerGroup.shutdownGracefully(); bossGroup.shutdownGracefully(); } } + + /** + * increase port number every 3 tries + * + * @param basePort + * @param retryCount + * @return + */ + private int getNewPort(int basePort, int retryCount) { + return basePort + retryCount / 3; + } public void close() { channel.close(); 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..779bee1ca4 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 @@ -52,6 +52,7 @@ public class SimpleHttpCommandCenter implements CommandCenter { private static final int DEFAULT_SERVER_SO_TIMEOUT = 3000; private static final int DEFAULT_PORT = 8719; + @SuppressWarnings("rawtypes") private static final Map handlerMap = new HashMap(); private ExecutorService executor = Executors.newSingleThreadExecutor( @@ -61,6 +62,7 @@ public class SimpleHttpCommandCenter implements CommandCenter { private ServerSocket socketReference; @Override + @SuppressWarnings("rawtypes") public void beforeStart() throws Exception { // Register handlers Map handlers = CommandHandlerProvider.getInstance().namedHandlers(); @@ -94,54 +96,56 @@ 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); - - 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; - } + ServerSocket serverSocket = getServerSocketFromBasePort(port); + + if (serverSocket != null) { + CommandCenterLog.info("[CommandCenter] Begin listening at port " + serverSocket.getLocalPort()); + socketReference = serverSocket; + executor.submit(new ServerThread(serverSocket)); + success = true; + port = serverSocket.getLocalPort(); } 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(); } + + /** + * 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 basePort + * @return + */ + private static ServerSocket getServerSocketFromBasePort(int basePort) { + int tryCount = 0; + while (true) { + try { + ServerSocket server = new ServerSocket(basePort + tryCount / 3, 100); + server.setReuseAddress(true); + return server; + } catch (IOException e) { + tryCount ++; + try { + TimeUnit.MILLISECONDS.sleep(30); + } catch (InterruptedException e1) { + break; + } + } + } + return null; + } @Override public void stop() throws Exception { @@ -204,10 +208,12 @@ public void run() { } } + @SuppressWarnings("rawtypes") public static CommandHandler getHandler(String commandName) { return handlerMap.get(commandName); } + @SuppressWarnings("rawtypes") public static void registerCommands(Map handlerMap) { if (handlerMap != null) { for (Entry e : handlerMap.entrySet()) { @@ -216,6 +222,7 @@ public static void registerCommands(Map handlerMap) { } } + @SuppressWarnings("rawtypes") public static void registerCommand(String commandName, CommandHandler handler) { if (StringUtil.isEmpty(commandName)) { return;