0

I want to implement circuit breaker using vert.x for rabbit mq. if rabbit mq is down then circuit is open based on the configuration.

I did separate POC for vert.x circuit breaker and also able to connect with Rabbit MQ client . using vert.x .

Now, I want to build circuit breaker if circuit is open then client will not to push messages in queue , and keep in data base, once circuit is closed then it will start pushing db messages in mq. Please help.

I've use below links for create working poc.

Snippet Used for Circuit Breaker

     CircuitBreakerOptions options = new CircuitBreakerOptions()
        .setMaxFailures(0)
        .setTimeout(5000)
        .setMaxRetries(3)
        .setFallbackOnFailure(true);

    CircuitBreaker breaker =
        CircuitBreaker.create("my-circuit-breaker", vertx, options)
        .openHandler(v -> {
          System.out.println("Circuit opened");
        }).closeHandler(v -> {
          System.out.println("Circuit closed");
        }).retryPolicy(retryCount -> retryCount * 100L);

    breaker.executeWithFallback(promise -> {
      vertx.createHttpClient().getNow(8080, "localhost", "/", response -> {
        if (response.statusCode() != 200) {
          promise.fail("HTTP error");
        } else {
          response.exceptionHandler(promise::fail).bodyHandler(buffer -> {
            promise.complete(buffer.toString());
          });
        }
      });
    }, v -> {
      // Executed when the circuit is opened
      return "Hello (fallback)";
    }, ar -> {
      // Do something with the result
      System.out.println("Result: " + ar.result());
    });
  }

Snippet Used for RAbbit MQ Client

public static void main(String[] args) {
    Vertx vertx = Vertx.vertx();
    RabbitMQOptions config = new RabbitMQOptions();
    // Each parameter is optional
    // The default parameter with be used if the parameter is not set
    config.setUser("guest");
    config.setPassword("guest");
    config.setHost("localhost");
    config.setPort(5672);
    // config.setVirtualHost("vhost1");
    // config.setConnectionTimeout(6000); // in milliseconds
    config.setRequestedHeartbeat(60); // in seconds
    // config.setHandshakeTimeout(6000); // in milliseconds
    // config.setRequestedChannelMax(5);
    // config.setNetworkRecoveryInterval(500); // in milliseconds
    // config.setAutomaticRecoveryEnabled(true);
    // vertx.

    RabbitMQClient client = RabbitMQClient.create(vertx, config);
    CircuitBreakerOptions options = new CircuitBreakerOptions().setMaxFailures(0).setTimeout(5000).setMaxRetries(0)
            .setFallbackOnFailure(true);

    CircuitBreaker breaker = CircuitBreaker.create("my-circuit-breaker", vertx, options).openHandler(v -> {
        System.out.println("Circuit opened");
    }).closeHandler(v -> {
        System.out.println("Circuit closed");
    }).retryPolicy(retryCount -> retryCount * 100L);

    
    breaker.executeWithFallback(promise -> {
          vertx.createHttpClient().getNow(8080, "localhost", "/", response -> {
            if (response.statusCode() != 200) {
              promise.fail("HTTP error");
            } else {
              response.exceptionHandler(promise::fail).bodyHandler(buffer -> {
                promise.complete(buffer.toString());
              });
            }
          });
        }, v -> {
          // Executed when the circuit is opened
          return "Hello (fallback)";
        }, ar -> {
          // Do something with the result
          System.out.println("Result: " + ar.result());
        });
    
    client.start(rh -> {

        if (rh.failed()) {
            System.out.println("failed");
        } else {
            for (int i = 0; i > 5; i++) {
                System.out.println(rh.succeeded());
                System.out.println("client : " + client.isConnected());
                breaker.executeWithFallback(promise -> {
                    if(!client.isConnected()) {
                        promise.fail("MQ client is not connected");
                    }
                },v -> {
                      // Executed when the circuit is opened
                      return "Hello (fallback)";
                    }, ar -> {
                      // Do something with the result
                      System.out.println("Result: " + ar.result());
                    });
                /* RabbitMQClient client2 = RabbitMQClient.create(vertx); */
                JsonObject message = new JsonObject().put("body", "Hello RabbitMQ, from Vert.x !");
                client.basicPublish("eventExchange", "order.created", message, pubResult -> {
                    if (pubResult.succeeded()) {
                        System.out.println("Message published !");
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    } else {
                        pubResult.cause().printStackTrace();
                    }
                });
            }
        }
    });

}

Although its working but, circuit open in case rabbit mq down . But its not looks a standard way of ding it with vert.x .

CAn you please suggest of give input how i can implement it.

Nilay Tiwari
  • 492
  • 5
  • 16

0 Answers0