Skip to content

Commit

Permalink
Remove health check from API Gateway component
Browse files Browse the repository at this point in the history
The health check mechanism should be implemented by the service discovery infrastructure rather than API Gateway.

Signed-off-by: sczyh30 <sczyh16@gmail.com>
  • Loading branch information
sczyh30 committed Apr 15, 2017
1 parent 2eb6727 commit 1d288a9
Show file tree
Hide file tree
Showing 5 changed files with 0 additions and 81 deletions.
Expand Up @@ -3,7 +3,6 @@
import io.vertx.blueprint.microservice.account.Account;
import io.vertx.blueprint.microservice.account.AccountService;
import io.vertx.blueprint.microservice.common.RestAPIVerticle;
import io.vertx.blueprint.microservice.common.functional.Functional;
import io.vertx.core.Future;
import io.vertx.core.http.HttpClient;
import io.vertx.core.http.HttpClientRequest;
Expand All @@ -29,7 +28,6 @@

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
* A verticle for global API gateway.
Expand All @@ -40,7 +38,6 @@
*/
public class APIGatewayVerticle extends RestAPIVerticle {

private static final int DEFAULT_CHECK_PERIOD = 60000;
private static final int DEFAULT_PORT = 8787;

private static final Logger logger = LoggerFactory.getLogger(APIGatewayVerticle.class);
Expand Down Expand Up @@ -82,9 +79,6 @@ public void start(Future<Void> future) throws Exception {
// api dispatcher
router.route("/api/*").handler(this::dispatchRequests);

// init heart beat check
initHealthCheck();

// static content
router.route("/*").handler(StaticHandler.create());

Expand Down Expand Up @@ -209,72 +203,6 @@ private Future<List<Record>> getAllEndpoints() {
return future;
}

// heart beat check (very simple)

private void initHealthCheck() {
if (config().getBoolean("heartbeat.enable", true)) { // by default enabled
int period = config().getInteger("heartbeat.period", DEFAULT_CHECK_PERIOD);
vertx.setPeriodic(period, t -> {
circuitBreaker.execute(future -> { // behind the circuit breaker
sendHeartBeatRequest().setHandler(future.completer());
});
});
}
}

/**
* Send heart-beat check request to every REST node in every interval and await response.
*
* @return async result. If all nodes are active, the result will be assigned `true`, else the result will fail
*/
private Future<Object> sendHeartBeatRequest() {
final String HEARTBEAT_PATH = config().getString("heartbeat.path", "/health");
return getAllEndpoints()
.compose(records -> {
List<Future<JsonObject>> statusFutureList = records.stream()
.filter(record -> record.getMetadata().getString("api.name") != null)
.map(record -> { // for each client, send heart beat request
String apiName = record.getMetadata().getString("api.name");
HttpClient client = discovery.getReference(record).get();

Future<JsonObject> future = Future.future();
client.get(HEARTBEAT_PATH, response -> {
future.complete(new JsonObject()
.put("name", apiName)
.put("status", healthStatus(response.statusCode()))
);
})
.exceptionHandler(future::fail)
.end();
return future;
})
.collect(Collectors.toList());
return Functional.sequenceFuture(statusFutureList); // get all responses
})
.compose(statusList -> {
boolean notHealthy = statusList.stream().anyMatch(status -> !status.getBoolean("status"));

if (notHealthy) {
String issues = statusList.stream().filter(status -> !status.getBoolean("status"))
.map(status -> status.getString("name"))
.collect(Collectors.joining(", "));

String err = String.format("Heart beat check fail: %s", issues);
// publish log
publishGatewayLog(err);
return Future.failedFuture(new IllegalStateException(err));
} else {
// publish log
publishGatewayLog("api_gateway_heartbeat_check_success");
return Future.succeededFuture("OK");
}
});
}

private boolean healthStatus(int code) {
return code == 200;
}

// log methods

private void publishGatewayLog(String info) {
Expand Down
Expand Up @@ -50,9 +50,6 @@ public void start(Future<Void> future) throws Exception {
router.put(API_INCREASE).handler(this::apiIncrease);
router.put(API_DECREASE).handler(this::apiDecrease);

// enable heart beat check
enableHeartbeatCheck(router, config());

// get HTTP host and port from configuration, or use default value
String host = config().getString("inventory.http.address", "0.0.0.0");
int port = config().getInteger("inventory.http.port", 8086);
Expand Down
Expand Up @@ -52,8 +52,6 @@ public void start(Future<Void> future) throws Exception {
router.delete(API_DELETE).handler(this::apiDelete);
router.delete(API_DELETE_ALL).handler(context -> requireLogin(context, this::apiDeleteAll));

enableHeartbeatCheck(router, config());

// get HTTP host and port from configuration, or use default value
String host = config().getString("product.http.address", "0.0.0.0");
int port = config().getInteger("product.http.port", 8082);
Expand Down
Expand Up @@ -46,8 +46,6 @@ public void start(Future<Void> future) throws Exception {

enableLocalSession(router);

enableHeartbeatCheck(router, config());

// get HTTP host and port from configuration, or use default value
String host = config().getString("shopping.cart.http.address", "0.0.0.0");
int port = config().getInteger("shopping.cart.http.port", 8084);
Expand Down
Expand Up @@ -38,8 +38,6 @@ public void start(Future<Void> future) throws Exception {
router.get(API_RETRIEVE).handler(this::apiRetrieve);
router.delete(API_CLOSE).handler(this::apiClose);

enableHeartbeatCheck(router, config());

// get HTTP host and port from configuration, or use default value
String host = config().getString("store.http.address", "0.0.0.0");
int port = config().getInteger("store.http.port", 8085);
Expand Down

0 comments on commit 1d288a9

Please sign in to comment.