cleanup: use more appropriately ConfigurationProperties making a DTO for TTL heartbeating

This commit is contained in:
nicu marasoiu
2015-03-13 16:12:09 +02:00
parent 893a6b0fd2
commit 12d3695d7a
4 changed files with 82 additions and 68 deletions

View File

@@ -18,6 +18,11 @@ public class ConsulDiscoveryClientConfiguration {
return new TtlScheduler();
}
@Bean
public TtlHeartbeatConfiguration ttlHeartbeatConfiguration() {
return new TtlHeartbeatConfiguration();
}
/*@Bean
public ConsulLoadBalancerClient consulLoadBalancerClient() {
return new ConsulLoadBalancerClient();

View File

@@ -22,6 +22,9 @@ public class ConsulLifecycle extends AbstractDiscoveryLifecycle {
@Autowired
private TtlScheduler ttlScheduler;
@Autowired
private TtlHeartbeatConfiguration ttlConfig;
@Override
protected void register() {
NewService service = new NewService();
@@ -34,7 +37,7 @@ public class ConsulLifecycle extends AbstractDiscoveryLifecycle {
service.setPort(port);
service.setTags(consulProperties.getTags());
NewService.Check check = new NewService.Check();
check.setTtl(ttlScheduler.getTTL() + "s");
check.setTtl(ttlConfig.getTtlAsString());
service.setCheck(check);
register(service);
}

View File

@@ -0,0 +1,37 @@
package org.springframework.cloud.consul.discovery;
import lombok.Data;
import org.joda.time.Period;
import org.springframework.boot.context.properties.ConfigurationProperties;
import javax.annotation.PostConstruct;
import javax.validation.constraints.DecimalMax;
import javax.validation.constraints.DecimalMin;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
@ConfigurationProperties(prefix = "consul.heartbeat")
@Data
public class TtlHeartbeatConfiguration {
@Min(1)
@Max(10)
private volatile int ttl = 3;
@DecimalMin("0.1")
@DecimalMax("0.9")
private volatile double intervalRatio = 2.0 / 3.0;
private volatile Period heartbeatInterval;
@PostConstruct
public void computeHeartbeatInterval() {
// heartbeat rate at ratio * ttl, but no later than ttl -1s and, (under lesser
// priority), no sooner than 1s from now
heartbeatInterval = new Period(Math.round(1000 * Math.max(ttl - 1,
Math.min(ttl * intervalRatio, 1))));
}
public String getTtlAsString() {
return ttl + "s";
}
}

View File

@@ -1,85 +1,54 @@
package org.springframework.cloud.consul.discovery;
import com.ecwid.consul.v1.ConsulClient;
import com.ecwid.consul.v1.agent.model.NewService;
import lombok.extern.slf4j.Slf4j;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.annotation.PostConstruct;
import javax.validation.constraints.DecimalMax;
import javax.validation.constraints.DecimalMin;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import lombok.extern.slf4j.Slf4j;
import org.joda.time.DateTime;
import org.joda.time.Period;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.scheduling.annotation.Scheduled;
import com.ecwid.consul.v1.ConsulClient;
import com.ecwid.consul.v1.agent.model.NewService;
/**
* Created by nicu on 11.03.2015.
*/
@Slf4j
@ConfigurationProperties(prefix = "consul.heartbeat")
public class TtlScheduler {
public static final DateTime EXPIRED_DATE = new DateTime(0);
private final Map<String, DateTime> serviceHeartbeats = new ConcurrentHashMap<>();
private final AtomicBoolean heartbeatingNow = new AtomicBoolean();
public static final DateTime EXPIRED_DATE = new DateTime(0);
private final Map<String, DateTime> serviceHeartbeats = new ConcurrentHashMap<>();
private final AtomicBoolean heartbeatingNow = new AtomicBoolean();
@Min(1)
@Max(10)
private volatile int ttl = 3;
@Autowired
private TtlHeartbeatConfiguration configuration;
@DecimalMin("0.1")
@DecimalMax("0.9")
private volatile double intervalRatio = 2.0/3.0;
@Autowired
private ConsulClient client;
private volatile Period heartbeatInterval;
/**
* Add a service to the checks loop.
*/
public void add(final NewService service) {
serviceHeartbeats.put(service.getId(), EXPIRED_DATE);
}
@Autowired
private ConsulClient client;
public void remove(String serviceId) {
serviceHeartbeats.remove(serviceId);
}
@PostConstruct
public void computeHeartbeatInterval() {
// heartbeat rate at ratio * ttl, but no later than ttl -1s and, (under lesser
// priority), no sooner than 1s from now
heartbeatInterval = new Period(Math.round(1000 * Math.max(ttl - 1,
Math.min(ttl * intervalRatio, 1))));
}
/**
* Add a service to the checks loop.
*/
public void add(final NewService service) {
serviceHeartbeats.put(service.getId(), EXPIRED_DATE);
}
public void remove(String serviceId) {
serviceHeartbeats.remove(serviceId);
}
public int getTTL() {
return ttl;
}
@Scheduled(initialDelay = 0, fixedRateString = "${consul.heartbeat.fixedRate:201000}")
private void heartbeatServices() {
if (heartbeatingNow.compareAndSet(false, true)) {
for (String serviceId : serviceHeartbeats.keySet()) {
DateTime latestHeartbeatDoneForService = serviceHeartbeats.get(serviceId);
if (latestHeartbeatDoneForService.plus(heartbeatInterval).isBefore(
new DateTime())) {
client.agentCheckPass(serviceId);
serviceHeartbeats.put(serviceId, new DateTime());
}
}
}
}
@Scheduled(initialDelay = 0, fixedRateString = "${consul.heartbeat.fixedRate:201000}")
private void heartbeatServices() {
if (heartbeatingNow.compareAndSet(false, true)) {
for (String serviceId : serviceHeartbeats.keySet()) {
DateTime latestHeartbeatDoneForService = serviceHeartbeats.get(serviceId);
if (latestHeartbeatDoneForService.plus(configuration.getHeartbeatInterval())
.isBefore(DateTime.now())) {
client.agentCheckPass(serviceId);
serviceHeartbeats.put(serviceId, DateTime.now());
}
}
}
}
}