Skip to content

Commit

Permalink
Refresh health indicator for config server if present
Browse files Browse the repository at this point in the history
Listen for heartbeats from discovery so that state changes can trigger
a new status (and the client doesn't rely on the old address of the
server if it has now changed).

Fixes gh-232
  • Loading branch information
Dave Syer committed Feb 25, 2015
1 parent dafb5ec commit 0b8f855
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 24 deletions.
Expand Up @@ -22,15 +22,16 @@
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.discovery.event.HeartbeatEvent;
import org.springframework.cloud.client.discovery.event.HeartbeatMonitor;
import org.springframework.cloud.config.client.ConfigClientProperties;
import org.springframework.cloud.config.client.ConfigServicePropertySourceLocator;
import org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration;
import org.springframework.context.ApplicationListener;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.Environment;
import org.springframework.context.event.SmartApplicationListener;

import com.netflix.appinfo.InstanceInfo;
import com.netflix.discovery.DiscoveryClient;
Expand All @@ -48,7 +49,9 @@
@Import(EurekaClientAutoConfiguration.class)
@CommonsLog
public class DiscoveryClientConfigServiceBootstrapConfiguration implements
ApplicationListener<ContextRefreshedEvent> {
SmartApplicationListener {

private HeartbeatMonitor monitor = new HeartbeatMonitor();

@Autowired
private DiscoveryClient client;
Expand All @@ -57,14 +60,36 @@ public class DiscoveryClientConfigServiceBootstrapConfiguration implements
private ConfigClientProperties config;

@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
public void onApplicationEvent(ApplicationEvent event) {
if (event instanceof ContextRefreshedEvent) {
refresh();
}
else if (event instanceof HeartbeatEvent) {
if (this.monitor.update(((HeartbeatEvent) event).getValue())) {
refresh();
}
}
}

@Override
public int getOrder() {
return 0;
}

@Override
public boolean supportsEventType(Class<? extends ApplicationEvent> eventType) {
return ContextRefreshedEvent.class.isAssignableFrom(eventType)
|| HeartbeatEvent.class.isAssignableFrom(eventType);
}

@Override
public boolean supportsSourceType(Class<?> sourceType) {
return true;
}

private void refresh() {
try {
log.info("Locating configserver via discovery");
Environment environment = event.getApplicationContext().getEnvironment();
if (!(environment instanceof ConfigurableEnvironment)) {
log.info("Environment is not ConfigurableEnvironment so cannot look up configserver");
return;
}
InstanceInfo server = this.client.getNextServerFromEureka(this.config
.getDiscovery().getServiceId(), false);
String url = server.getHomePageUrl();
Expand Down
Expand Up @@ -24,7 +24,17 @@

import com.netflix.client.config.DefaultClientConfigImpl;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.*;
import com.netflix.loadbalancer.ConfigurationBasedServerList;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.IPing;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.LoadBalancerBuilder;
import com.netflix.loadbalancer.NoOpPing;
import com.netflix.loadbalancer.Server;
import com.netflix.loadbalancer.ServerList;
import com.netflix.loadbalancer.ServerListFilter;
import com.netflix.loadbalancer.ZoneAvoidanceRule;
import com.netflix.loadbalancer.ZoneAwareLoadBalancer;
import com.netflix.niws.client.http.RestClient;
import com.netflix.servo.monitor.Monitors;

Expand Down Expand Up @@ -85,15 +95,11 @@ public RestClient ribbonRestClient(IClientConfig config, ILoadBalancer loadBalan
@Bean
@ConditionalOnMissingBean
public ILoadBalancer ribbonLoadBalancer(IClientConfig config,
ServerList<Server> serverList,
ServerListFilter<Server> serverListFilter,
ServerList<Server> serverList, ServerListFilter<Server> serverListFilter,
IRule rule, IPing ping) {
ZoneAwareLoadBalancer<Server> balancer = LoadBalancerBuilder.newBuilder()
.withClientConfig(config)
.withRule(rule)
.withPing(ping)
.withServerListFilter(serverListFilter)
.withDynamicServerList(serverList)
.withClientConfig(config).withRule(rule).withPing(ping)
.withServerListFilter(serverListFilter).withDynamicServerList(serverList)
.buildDynamicServerListLoadBalancer();
return balancer;
}
Expand Down
Expand Up @@ -16,15 +16,14 @@

package org.springframework.cloud.netflix.zuul;

import java.util.concurrent.atomic.AtomicReference;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.endpoint.Endpoint;
import org.springframework.boot.actuate.trace.TraceRepository;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.discovery.event.HeartbeatEvent;
import org.springframework.cloud.client.discovery.event.HeartbeatMonitor;
import org.springframework.cloud.client.discovery.event.InstanceRegisteredEvent;
import org.springframework.cloud.client.discovery.event.ParentHeartbeatEvent;
import org.springframework.cloud.context.scope.refresh.RefreshScopeRefreshedEvent;
Expand Down Expand Up @@ -121,7 +120,7 @@ public RoutesEndpoint zuulEndpoint() {
private static class ZuulRefreshListener implements
ApplicationListener<ApplicationEvent> {

private AtomicReference<Object> latestHeartbeat = new AtomicReference<>();
private HeartbeatMonitor monitor = new HeartbeatMonitor();

@Autowired
private ProxyRouteLocator routeLocator;
Expand All @@ -148,9 +147,7 @@ else if (event instanceof HeartbeatEvent) {
}

private void resetIfNeeded(Object value) {
if (this.latestHeartbeat.get() == null
|| !this.latestHeartbeat.get().equals(value)) {
this.latestHeartbeat.set(value);
if (this.monitor.update(value)) {
reset();
}
}
Expand Down

0 comments on commit 0b8f855

Please sign in to comment.