Commit c4be98576a91211532ddb6710849a17f17661374
1 parent
5206a0e4
Improve zookeeper client reconnect logic. UI: Flot widget - Fixed incorrect indi…
…vidual tooltip content.
Showing
3 changed files
with
37 additions
and
14 deletions
@@ -52,6 +52,8 @@ import javax.annotation.PostConstruct; | @@ -52,6 +52,8 @@ import javax.annotation.PostConstruct; | ||
52 | import javax.annotation.PreDestroy; | 52 | import javax.annotation.PreDestroy; |
53 | import java.util.List; | 53 | import java.util.List; |
54 | import java.util.NoSuchElementException; | 54 | import java.util.NoSuchElementException; |
55 | +import java.util.concurrent.ExecutorService; | ||
56 | +import java.util.concurrent.Executors; | ||
55 | import java.util.stream.Collectors; | 57 | import java.util.stream.Collectors; |
56 | 58 | ||
57 | import static org.apache.curator.framework.recipes.cache.PathChildrenCacheEvent.Type.CHILD_REMOVED; | 59 | import static org.apache.curator.framework.recipes.cache.PathChildrenCacheEvent.Type.CHILD_REMOVED; |
@@ -96,11 +98,13 @@ public class ZkDiscoveryService implements DiscoveryService, PathChildrenCacheLi | @@ -96,11 +98,13 @@ public class ZkDiscoveryService implements DiscoveryService, PathChildrenCacheLi | ||
96 | @Lazy | 98 | @Lazy |
97 | private ClusterRoutingService routingService; | 99 | private ClusterRoutingService routingService; |
98 | 100 | ||
101 | + private ExecutorService reconnectExecutorService; | ||
102 | + | ||
99 | private CuratorFramework client; | 103 | private CuratorFramework client; |
100 | private PathChildrenCache cache; | 104 | private PathChildrenCache cache; |
101 | private String nodePath; | 105 | private String nodePath; |
102 | 106 | ||
103 | - private volatile boolean stopped = false; | 107 | + private volatile boolean stopped = true; |
104 | 108 | ||
105 | @PostConstruct | 109 | @PostConstruct |
106 | public void init() { | 110 | public void init() { |
@@ -110,9 +114,15 @@ public class ZkDiscoveryService implements DiscoveryService, PathChildrenCacheLi | @@ -110,9 +114,15 @@ public class ZkDiscoveryService implements DiscoveryService, PathChildrenCacheLi | ||
110 | Assert.notNull(zkConnectionTimeout, MiscUtils.missingProperty("zk.connection_timeout_ms")); | 114 | Assert.notNull(zkConnectionTimeout, MiscUtils.missingProperty("zk.connection_timeout_ms")); |
111 | Assert.notNull(zkSessionTimeout, MiscUtils.missingProperty("zk.session_timeout_ms")); | 115 | Assert.notNull(zkSessionTimeout, MiscUtils.missingProperty("zk.session_timeout_ms")); |
112 | 116 | ||
117 | + reconnectExecutorService = Executors.newSingleThreadExecutor(); | ||
118 | + | ||
113 | log.info("Initializing discovery service using ZK connect string: {}", zkUrl); | 119 | log.info("Initializing discovery service using ZK connect string: {}", zkUrl); |
114 | 120 | ||
115 | zkNodesDir = zkDir + "/nodes"; | 121 | zkNodesDir = zkDir + "/nodes"; |
122 | + initZkClient(); | ||
123 | + } | ||
124 | + | ||
125 | + private void initZkClient() { | ||
116 | try { | 126 | try { |
117 | client = CuratorFrameworkFactory.newClient(zkUrl, zkSessionTimeout, zkConnectionTimeout, new RetryForever(zkRetryInterval)); | 127 | client = CuratorFrameworkFactory.newClient(zkUrl, zkSessionTimeout, zkConnectionTimeout, new RetryForever(zkRetryInterval)); |
118 | client.start(); | 128 | client.start(); |
@@ -120,6 +130,8 @@ public class ZkDiscoveryService implements DiscoveryService, PathChildrenCacheLi | @@ -120,6 +130,8 @@ public class ZkDiscoveryService implements DiscoveryService, PathChildrenCacheLi | ||
120 | cache = new PathChildrenCache(client, zkNodesDir, true); | 130 | cache = new PathChildrenCache(client, zkNodesDir, true); |
121 | cache.getListenable().addListener(this); | 131 | cache.getListenable().addListener(this); |
122 | cache.start(); | 132 | cache.start(); |
133 | + stopped = false; | ||
134 | + log.info("ZK client connected"); | ||
123 | } catch (Exception e) { | 135 | } catch (Exception e) { |
124 | log.error("Failed to connect to ZK: {}", e.getMessage(), e); | 136 | log.error("Failed to connect to ZK: {}", e.getMessage(), e); |
125 | CloseableUtils.closeQuietly(cache); | 137 | CloseableUtils.closeQuietly(cache); |
@@ -128,12 +140,20 @@ public class ZkDiscoveryService implements DiscoveryService, PathChildrenCacheLi | @@ -128,12 +140,20 @@ public class ZkDiscoveryService implements DiscoveryService, PathChildrenCacheLi | ||
128 | } | 140 | } |
129 | } | 141 | } |
130 | 142 | ||
131 | - @PreDestroy | ||
132 | - public void destroy() { | 143 | + private void destroyZkClient() { |
133 | stopped = true; | 144 | stopped = true; |
134 | - unpublishCurrentServer(); | 145 | + try { |
146 | + unpublishCurrentServer(); | ||
147 | + } catch (Exception e) {} | ||
135 | CloseableUtils.closeQuietly(cache); | 148 | CloseableUtils.closeQuietly(cache); |
136 | CloseableUtils.closeQuietly(client); | 149 | CloseableUtils.closeQuietly(client); |
150 | + log.info("ZK client disconnected"); | ||
151 | + } | ||
152 | + | ||
153 | + @PreDestroy | ||
154 | + public void destroy() { | ||
155 | + destroyZkClient(); | ||
156 | + reconnectExecutorService.shutdownNow(); | ||
137 | log.info("Stopped discovery service"); | 157 | log.info("Stopped discovery service"); |
138 | } | 158 | } |
139 | 159 | ||
@@ -180,20 +200,21 @@ public class ZkDiscoveryService implements DiscoveryService, PathChildrenCacheLi | @@ -180,20 +200,21 @@ public class ZkDiscoveryService implements DiscoveryService, PathChildrenCacheLi | ||
180 | return (client, newState) -> { | 200 | return (client, newState) -> { |
181 | log.info("[{}:{}] ZK state changed: {}", self.getHost(), self.getPort(), newState); | 201 | log.info("[{}:{}] ZK state changed: {}", self.getHost(), self.getPort(), newState); |
182 | if (newState == ConnectionState.LOST) { | 202 | if (newState == ConnectionState.LOST) { |
183 | - reconnect(); | 203 | + reconnectExecutorService.submit(this::reconnect); |
184 | } | 204 | } |
185 | }; | 205 | }; |
186 | } | 206 | } |
187 | 207 | ||
188 | - private boolean reconnectInProgress = false; | 208 | + private volatile boolean reconnectInProgress = false; |
189 | 209 | ||
190 | private synchronized void reconnect() { | 210 | private synchronized void reconnect() { |
191 | if (!reconnectInProgress) { | 211 | if (!reconnectInProgress) { |
192 | reconnectInProgress = true; | 212 | reconnectInProgress = true; |
193 | try { | 213 | try { |
194 | - client.blockUntilConnected(); | 214 | + destroyZkClient(); |
215 | + initZkClient(); | ||
195 | publishCurrentServer(); | 216 | publishCurrentServer(); |
196 | - } catch (InterruptedException e) { | 217 | + } catch (Exception e) { |
197 | log.error("Failed to reconnect to ZK: {}", e.getMessage(), e); | 218 | log.error("Failed to reconnect to ZK: {}", e.getMessage(), e); |
198 | } finally { | 219 | } finally { |
199 | reconnectInProgress = false; | 220 | reconnectInProgress = false; |
@@ -50,7 +50,7 @@ | @@ -50,7 +50,7 @@ | ||
50 | <commons-validator.version>1.5.0</commons-validator.version> | 50 | <commons-validator.version>1.5.0</commons-validator.version> |
51 | <commons-io.version>2.5</commons-io.version> | 51 | <commons-io.version>2.5</commons-io.version> |
52 | <commons-csv.version>1.4</commons-csv.version> | 52 | <commons-csv.version>1.4</commons-csv.version> |
53 | - <jackson.version>2.9.7</jackson.version> | 53 | + <jackson.version>2.9.8</jackson.version> |
54 | <json-schema-validator.version>2.2.6</json-schema-validator.version> | 54 | <json-schema-validator.version>2.2.6</json-schema-validator.version> |
55 | <scala.version>2.11</scala.version> | 55 | <scala.version>2.11</scala.version> |
56 | <akka.version>2.4.2</akka.version> | 56 | <akka.version>2.4.2</akka.version> |
@@ -59,7 +59,7 @@ | @@ -59,7 +59,7 @@ | ||
59 | <velocity.version>1.7</velocity.version> | 59 | <velocity.version>1.7</velocity.version> |
60 | <velocity-tools.version>2.0</velocity-tools.version> | 60 | <velocity-tools.version>2.0</velocity-tools.version> |
61 | <mail.version>1.4.3</mail.version> | 61 | <mail.version>1.4.3</mail.version> |
62 | - <curator.version>4.0.1</curator.version> | 62 | + <curator.version>4.2.0</curator.version> |
63 | <protobuf.version>3.6.1</protobuf.version> | 63 | <protobuf.version>3.6.1</protobuf.version> |
64 | <grpc.version>1.16.1</grpc.version> | 64 | <grpc.version>1.16.1</grpc.version> |
65 | <lombok.version>1.16.18</lombok.version> | 65 | <lombok.version>1.16.18</lombok.version> |
@@ -137,9 +137,11 @@ export default class TbFlot { | @@ -137,9 +137,11 @@ export default class TbFlot { | ||
137 | }); | 137 | }); |
138 | content += dateDiv.prop('outerHTML'); | 138 | content += dateDiv.prop('outerHTML'); |
139 | if (tbFlot.ctx.tooltipIndividual) { | 139 | if (tbFlot.ctx.tooltipIndividual) { |
140 | - var seriesHoverInfo = hoverInfo.seriesHover[seriesIndex]; | ||
141 | - if (seriesHoverInfo) { | ||
142 | - content += seriesInfoDivFromInfo(seriesHoverInfo, seriesIndex); | 140 | + var found = hoverInfo.seriesHover.filter((seriesHover) => { |
141 | + return seriesHover.index === seriesIndex; | ||
142 | + }); | ||
143 | + if (found && found.length) { | ||
144 | + content += seriesInfoDivFromInfo(found[0], seriesIndex); | ||
143 | } | 145 | } |
144 | } else { | 146 | } else { |
145 | var seriesDiv = $('<div></div>'); | 147 | var seriesDiv = $('<div></div>'); |
@@ -161,7 +163,7 @@ export default class TbFlot { | @@ -161,7 +163,7 @@ export default class TbFlot { | ||
161 | if (i == hoverInfo.seriesHover.length) { | 163 | if (i == hoverInfo.seriesHover.length) { |
162 | break; | 164 | break; |
163 | } | 165 | } |
164 | - seriesHoverInfo = hoverInfo.seriesHover[i]; | 166 | + var seriesHoverInfo = hoverInfo.seriesHover[i]; |
165 | columnContent += seriesInfoDivFromInfo(seriesHoverInfo, seriesIndex); | 167 | columnContent += seriesInfoDivFromInfo(seriesHoverInfo, seriesIndex); |
166 | } | 168 | } |
167 | columnDiv.html(columnContent); | 169 | columnDiv.html(columnContent); |