diff --git a/sentinel-transport/sentinel-transport-common/src/main/java/com/alibaba/csp/sentinel/transport/config/TransportConfig.java b/sentinel-transport/sentinel-transport-common/src/main/java/com/alibaba/csp/sentinel/transport/config/TransportConfig.java index c27625cd..cb4130c6 100755 --- a/sentinel-transport/sentinel-transport-common/src/main/java/com/alibaba/csp/sentinel/transport/config/TransportConfig.java +++ b/sentinel-transport/sentinel-transport-common/src/main/java/com/alibaba/csp/sentinel/transport/config/TransportConfig.java @@ -15,10 +15,14 @@ */ package com.alibaba.csp.sentinel.transport.config; +import java.util.ArrayList; +import java.util.List; + import com.alibaba.csp.sentinel.config.SentinelConfig; import com.alibaba.csp.sentinel.log.RecordLog; import com.alibaba.csp.sentinel.util.HostNameUtil; import com.alibaba.csp.sentinel.util.StringUtil; +import com.alibaba.csp.sentinel.util.function.Tuple2; /** * @author leyou @@ -51,12 +55,69 @@ public class TransportConfig { } /** - * Get ip:port of Sentinel Dashboard. + * Get a list of (ip/domain, port) indicating Sentinel Dashboard's address.
+ * NOTE: only support HTTP protocol * - * @return console server ip:port, maybe null if not configured + * @return list of (ip/domain, port) pair.
+ * May not be null.
+ * An empty list returned when not configured. */ - public static String getConsoleServer() { - return SentinelConfig.getConfig(CONSOLE_SERVER); + public static List> getConsoleServerList() { + String config = SentinelConfig.getConfig(CONSOLE_SERVER); + List> list = new ArrayList>(); + if (StringUtil.isBlank(config)) { + RecordLog.warn("Dashboard server address is not configured"); + return list; + } + + int pos = -1; + int cur = 0; + while (true) { + pos = config.indexOf(',', cur); + if (cur < config.length() - 1 && pos < 0) { + // for single segment, pos move to the end + pos = config.length(); + } + if (pos < 0) { + break; + } + if (pos <= cur) { + cur ++; + continue; + } + // parsing + String ipPortStr = config.substring(cur, pos); + cur = pos + 1; + if (StringUtil.isBlank(ipPortStr)) { + continue; + } + ipPortStr = ipPortStr.trim(); + if (ipPortStr.startsWith("http://")) { + ipPortStr = ipPortStr.substring(7); + } + int index = ipPortStr.indexOf(":"); + int port = 80; + if (index == 0) { + // skip + continue; + } + String host = ipPortStr; + if (index >= 0) { + try { + port = Integer.parseInt(ipPortStr.substring(index + 1)); + if (port <= 1 || port >= 65535) { + throw new RuntimeException("Port number [" + port + "] over range"); + } + } catch (Exception e) { + RecordLog.warn("Parse port of dashboard server failed: " + ipPortStr, e); + // skip + continue; + } + host = ipPortStr.substring(0, index); + } + list.add(Tuple2.of(host, port)); + } + return list; } public static int getRuntimePort() { diff --git a/sentinel-transport/sentinel-transport-common/src/test/java/com/alibaba/csp/sentinel/transport/config/TransportConfigTest.java b/sentinel-transport/sentinel-transport-common/src/test/java/com/alibaba/csp/sentinel/transport/config/TransportConfigTest.java index a67d4285..94ef251f 100644 --- a/sentinel-transport/sentinel-transport-common/src/test/java/com/alibaba/csp/sentinel/transport/config/TransportConfigTest.java +++ b/sentinel-transport/sentinel-transport-common/src/test/java/com/alibaba/csp/sentinel/transport/config/TransportConfigTest.java @@ -17,6 +17,7 @@ package com.alibaba.csp.sentinel.transport.config; import com.alibaba.csp.sentinel.config.SentinelConfig; import com.alibaba.csp.sentinel.util.StringUtil; +import com.alibaba.csp.sentinel.util.function.Tuple2; import org.junit.After; import org.junit.Before; @@ -24,6 +25,8 @@ import org.junit.Test; import static org.junit.Assert.*; +import java.util.List; + public class TransportConfigTest { @Before @@ -82,4 +85,84 @@ public class TransportConfigTest { SentinelConfig.removeConfig(TransportConfig.HEARTBEAT_API_PATH); assertEquals(TransportConfig.HEARTBEAT_DEFAULT_PATH, TransportConfig.getHeartbeatApiPath()); } -} \ No newline at end of file + + @Test + public void testGetConsoleServerList() { + // empty + SentinelConfig.setConfig(TransportConfig.CONSOLE_SERVER, ""); + List> list = TransportConfig.getConsoleServerList(); + assertNotNull(list); + assertEquals(0, list.size()); + + // single ip + SentinelConfig.setConfig(TransportConfig.CONSOLE_SERVER, "112.13.223.3"); + list = TransportConfig.getConsoleServerList(); + assertNotNull(list); + assertEquals(1, list.size()); + assertEquals("112.13.223.3", list.get(0).r1); + assertEquals(new Integer(80), list.get(0).r2); + + // single domain + SentinelConfig.setConfig(TransportConfig.CONSOLE_SERVER, "www.dashboard.org"); + list = TransportConfig.getConsoleServerList(); + assertNotNull(list); + assertEquals(1, list.size()); + assertEquals("www.dashboard.org", list.get(0).r1); + assertEquals(new Integer(80), list.get(0).r2); + + // single ip including port + SentinelConfig.setConfig(TransportConfig.CONSOLE_SERVER, "www.dashboard.org:81"); + list = TransportConfig.getConsoleServerList(); + assertNotNull(list); + assertEquals(1, list.size()); + assertEquals("www.dashboard.org", list.get(0).r1); + assertEquals(new Integer(81), list.get(0).r2); + + // mixed + SentinelConfig.setConfig(TransportConfig.CONSOLE_SERVER, "www.dashboard.org:81,112.13.223.3,112.13.223.4:8080,www.dashboard.org"); + list = TransportConfig.getConsoleServerList(); + assertNotNull(list); + assertEquals(4, list.size()); + assertEquals("www.dashboard.org", list.get(0).r1); + assertEquals(new Integer(81), list.get(0).r2); + assertEquals("112.13.223.3", list.get(1).r1); + assertEquals(new Integer(80), list.get(1).r2); + assertEquals("112.13.223.4", list.get(2).r1); + assertEquals(new Integer(8080), list.get(2).r2); + assertEquals("www.dashboard.org", list.get(3).r1); + assertEquals(new Integer(80), list.get(3).r2); + + // malformed + SentinelConfig.setConfig(TransportConfig.CONSOLE_SERVER, "www.dashboard.org:0"); + list = TransportConfig.getConsoleServerList(); + assertNotNull(list); + assertEquals(0, list.size()); + + SentinelConfig.setConfig(TransportConfig.CONSOLE_SERVER, "www.dashboard.org:-1"); + list = TransportConfig.getConsoleServerList(); + assertNotNull(list); + assertEquals(0, list.size()); + + SentinelConfig.setConfig(TransportConfig.CONSOLE_SERVER, ":80"); + list = TransportConfig.getConsoleServerList(); + assertNotNull(list); + assertEquals(0, list.size()); + + SentinelConfig.setConfig(TransportConfig.CONSOLE_SERVER, "www.dashboard.org:"); + list = TransportConfig.getConsoleServerList(); + assertNotNull(list); + assertEquals(0, list.size()); + + SentinelConfig.setConfig(TransportConfig.CONSOLE_SERVER, "www.dashboard.org:80000"); + list = TransportConfig.getConsoleServerList(); + assertNotNull(list); + assertEquals(0, list.size()); + + SentinelConfig.setConfig(TransportConfig.CONSOLE_SERVER, "www.dashboard.org:80000,www.dashboard.org:81,:80"); + list = TransportConfig.getConsoleServerList(); + assertNotNull(list); + assertEquals(1, list.size()); + assertEquals("www.dashboard.org", list.get(0).r1); + assertEquals(new Integer(81), list.get(0).r2); + } +} diff --git a/sentinel-transport/sentinel-transport-netty-http/src/main/java/com/alibaba/csp/sentinel/transport/heartbeat/HttpHeartbeatSender.java b/sentinel-transport/sentinel-transport-netty-http/src/main/java/com/alibaba/csp/sentinel/transport/heartbeat/HttpHeartbeatSender.java index be5c7fa2..dcdb6c8e 100755 --- a/sentinel-transport/sentinel-transport-netty-http/src/main/java/com/alibaba/csp/sentinel/transport/heartbeat/HttpHeartbeatSender.java +++ b/sentinel-transport/sentinel-transport-netty-http/src/main/java/com/alibaba/csp/sentinel/transport/heartbeat/HttpHeartbeatSender.java @@ -15,7 +15,6 @@ */ package com.alibaba.csp.sentinel.transport.heartbeat; -import java.util.ArrayList; import java.util.List; import com.alibaba.csp.sentinel.Constants; @@ -58,7 +57,7 @@ public class HttpHeartbeatSender implements HeartbeatSender { public HttpHeartbeatSender() { this.client = HttpClients.createDefault(); - List> dashboardList = parseDashboardList(); + List> dashboardList = TransportConfig.getConsoleServerList(); if (dashboardList == null || dashboardList.isEmpty()) { RecordLog.info("[NettyHttpHeartbeatSender] No dashboard available"); } else { @@ -68,40 +67,6 @@ public class HttpHeartbeatSender implements HeartbeatSender { } } - protected static List> parseDashboardList() { - List> list = new ArrayList>(); - try { - String ipsStr = TransportConfig.getConsoleServer(); - if (StringUtil.isBlank(ipsStr)) { - RecordLog.warn("[NettyHttpHeartbeatSender] Dashboard server address is not configured"); - return list; - } - - for (String ipPortStr : ipsStr.split(",")) { - if (ipPortStr.trim().length() == 0) { - continue; - } - ipPortStr = ipPortStr.trim(); - if (ipPortStr.startsWith("http://")) { - ipPortStr = ipPortStr.substring(7); - } - if (ipPortStr.startsWith(":")) { - continue; - } - String[] ipPort = ipPortStr.trim().split(":"); - int port = 80; - if (ipPort.length > 1) { - port = Integer.parseInt(ipPort[1].trim()); - } - list.add(Tuple2.of(ipPort[0].trim(), port)); - } - } catch (Exception ex) { - RecordLog.warn("[NettyHttpHeartbeatSender] Parse dashboard list failed, current address list: " + list, ex); - ex.printStackTrace(); - } - return list; - } - @Override public boolean sendHeartbeat() throws Exception { if (StringUtil.isEmpty(consoleHost)) { diff --git a/sentinel-transport/sentinel-transport-netty-http/src/test/java/com/alibaba/csp/sentinel/transport/heartbeat/HttpHeartbeatSenderTest.java b/sentinel-transport/sentinel-transport-netty-http/src/test/java/com/alibaba/csp/sentinel/transport/heartbeat/HttpHeartbeatSenderTest.java deleted file mode 100644 index 1d270d9a..00000000 --- a/sentinel-transport/sentinel-transport-netty-http/src/test/java/com/alibaba/csp/sentinel/transport/heartbeat/HttpHeartbeatSenderTest.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.alibaba.csp.sentinel.transport.heartbeat; - -import static org.junit.Assert.assertEquals; - -import java.util.List; - -import org.junit.Test; - -import com.alibaba.csp.sentinel.config.SentinelConfig; -import com.alibaba.csp.sentinel.transport.config.TransportConfig; -import com.alibaba.csp.sentinel.util.function.Tuple2; - -public class HttpHeartbeatSenderTest { - - private void setAddr(String serverList) { - SentinelConfig.setConfig(TransportConfig.CONSOLE_SERVER, serverList); - } - - @Test - public void testAddr() { - setAddr(""); - assertEquals(0, HttpHeartbeatSender.parseDashboardList().size()); - - setAddr("a.com"); - List> list = HttpHeartbeatSender.parseDashboardList(); - assertEquals(1, list.size()); - assertEquals("a.com", list.get(0).r1); - assertEquals(Integer.valueOf(80), list.get(0).r2); - - setAddr("a.com:88"); - list = HttpHeartbeatSender.parseDashboardList(); - assertEquals(1, list.size()); - assertEquals("a.com", list.get(0).r1); - assertEquals(Integer.valueOf(88), list.get(0).r2); - - setAddr("a.com:88,,,,"); - list = HttpHeartbeatSender.parseDashboardList(); - assertEquals(1, list.size()); - assertEquals("a.com", list.get(0).r1); - assertEquals(Integer.valueOf(88), list.get(0).r2); - - setAddr("a.com:88,b.com"); - list = HttpHeartbeatSender.parseDashboardList(); - assertEquals(2, list.size()); - assertEquals("a.com", list.get(0).r1); - assertEquals(Integer.valueOf(88), list.get(0).r2); - assertEquals("b.com", list.get(1).r1); - assertEquals(Integer.valueOf(80), list.get(1).r2); - - setAddr("a.com:88,b.com:99999"); - list = HttpHeartbeatSender.parseDashboardList(); - assertEquals(2, list.size()); - assertEquals("a.com", list.get(0).r1); - assertEquals(Integer.valueOf(88), list.get(0).r2); - assertEquals("b.com", list.get(1).r1); - assertEquals(Integer.valueOf(99999), list.get(1).r2); - } -} diff --git a/sentinel-transport/sentinel-transport-simple-http/src/main/java/com/alibaba/csp/sentinel/transport/heartbeat/SimpleHttpHeartbeatSender.java b/sentinel-transport/sentinel-transport-simple-http/src/main/java/com/alibaba/csp/sentinel/transport/heartbeat/SimpleHttpHeartbeatSender.java index 605beff0..bab9ffa2 100755 --- a/sentinel-transport/sentinel-transport-simple-http/src/main/java/com/alibaba/csp/sentinel/transport/heartbeat/SimpleHttpHeartbeatSender.java +++ b/sentinel-transport/sentinel-transport-simple-http/src/main/java/com/alibaba/csp/sentinel/transport/heartbeat/SimpleHttpHeartbeatSender.java @@ -26,6 +26,7 @@ import com.alibaba.csp.sentinel.transport.heartbeat.client.SimpleHttpClient; import com.alibaba.csp.sentinel.transport.heartbeat.client.SimpleHttpRequest; import com.alibaba.csp.sentinel.transport.heartbeat.client.SimpleHttpResponse; import com.alibaba.csp.sentinel.util.StringUtil; +import com.alibaba.csp.sentinel.util.function.Tuple2; /** * The heartbeat sender provides basic API for sending heartbeat request to provided target. @@ -43,13 +44,13 @@ public class SimpleHttpHeartbeatSender implements HeartbeatSender { private final HeartbeatMessage heartBeat = new HeartbeatMessage(); private final SimpleHttpClient httpClient = new SimpleHttpClient(); - private final List addressList; + private final List> addressList; private int currentAddressIdx = 0; public SimpleHttpHeartbeatSender() { // Retrieve the list of default addresses. - List newAddrs = getDefaultConsoleIps(); + List> newAddrs = TransportConfig.getConsoleServerList(); RecordLog.info("[SimpleHttpHeartbeatSender] Default console address list retrieved: " + newAddrs); this.addressList = newAddrs; } @@ -60,11 +61,12 @@ public class SimpleHttpHeartbeatSender implements HeartbeatSender { RecordLog.info("[SimpleHttpHeartbeatSender] Runtime port not initialized, won't send heartbeat"); return false; } - InetSocketAddress addr = getAvailableAddress(); - if (addr == null) { + Tuple2 addrInfo = getAvailableAddress(); + if (addrInfo == null) { return false; } + InetSocketAddress addr = new InetSocketAddress(addrInfo.r1, addrInfo.r2); SimpleHttpRequest request = new SimpleHttpRequest(addr, TransportConfig.getHeartbeatApiPath()); request.setParams(heartBeat.generateCurrentMessage()); try { @@ -83,7 +85,7 @@ public class SimpleHttpHeartbeatSender implements HeartbeatSender { return DEFAULT_INTERVAL; } - private InetSocketAddress getAvailableAddress() { + private Tuple2 getAvailableAddress() { if (addressList == null || addressList.isEmpty()) { return null; } @@ -94,33 +96,4 @@ public class SimpleHttpHeartbeatSender implements HeartbeatSender { return addressList.get(index); } - private List getDefaultConsoleIps() { - List newAddrs = new ArrayList(); - try { - String ipsStr = TransportConfig.getConsoleServer(); - if (StringUtil.isEmpty(ipsStr)) { - RecordLog.warn("[SimpleHttpHeartbeatSender] Dashboard server address not configured"); - return newAddrs; - } - - for (String ipPortStr : ipsStr.split(",")) { - if (ipPortStr.trim().length() == 0) { - continue; - } - if (ipPortStr.startsWith("http://")) { - ipPortStr = ipPortStr.trim().substring(7); - } - String[] ipPort = ipPortStr.trim().split(":"); - int port = 80; - if (ipPort.length > 1) { - port = Integer.parseInt(ipPort[1].trim()); - } - newAddrs.add(new InetSocketAddress(ipPort[0].trim(), port)); - } - } catch (Exception ex) { - RecordLog.warn("[SimpleHeartbeatSender] Parse dashboard list failed, current address list: " + newAddrs, ex); - ex.printStackTrace(); - } - return newAddrs; - } }